ruby-changes:26771
From: drbrain <ko1@a...>
Date: Tue, 15 Jan 2013 11:49:01 +0900 (JST)
Subject: [ruby-changes:26771] drbrain:r38823 (trunk): * doc/syntax/calling_methods.rdoc (Arguments): Added improved
drbrain 2013-01-15 11:48:49 +0900 (Tue, 15 Jan 2013) New Revision: 38823 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38823 Log: * doc/syntax/calling_methods.rdoc (Arguments): Added improved introduction to arguments including passing style and lazy evaluation. Thanks to Matt Aimonetti. * doc/syntax/calling_methods.rdoc (Positional Arguments): Added description for sending a message to a method with *arguments * doc/syntax/calling_methods.rdoc (Default Positional Arguments): Added description. Thanks to Andy Lindeman. * doc/syntax/calling_methods.rdoc (Block Local Arguments): Added description of block locals. Thanks to Justin Collins. * doc/syntax/calling_methods.rdoc (Hash to Keyword Arguments): Added section describing ** operator. Thanks to Justin Collins. Modified files: trunk/ChangeLog trunk/doc/syntax/calling_methods.rdoc Index: doc/syntax/calling_methods.rdoc =================================================================== --- doc/syntax/calling_methods.rdoc (revision 38822) +++ doc/syntax/calling_methods.rdoc (revision 38823) @@ -27,13 +27,35 @@ NoMethodError. https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L27 You may also use <code>::</code> to designate a receiver, but this is rarely used due to the potential for confusion with <code>::</code> for namespaces. -== Positional Arguments +== Arguments -The positional arguments for the message follow the method name: +There are three types of arguments when sending a message, the positional +arguments, keyword (or named) arguments and the block argument. Each message +sent may use one, two or all types of arguments, but the arguments must be +supplied in this order. + +All arguments in ruby are passed by reference and are not lazily evaluated. + +Each argument is separated by a <code>,</code>: + + my_method(1, '2', :three) + +Arguments may be an expression, a hash argument: + + 'key' => value + +or a keyword argument: + + key: value + +Hash and keyword arguments must be contiguous and must appear after all +positional arguments, but may be mixed: + + my_method('a' => 1, b: 2, 'c' => 3) - my_method(argument1) +=== Positional Arguments -Multiple arguments are separated by a <code>,</code>: +The positional arguments for the message follow the method name: my_method(argument1, argument2) @@ -47,7 +69,76 @@ to: https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L69 method_one argument1, method_two argument2, argument3 -== Keyword Arguments +If the method definition has a <code>*argument</code> extra positional +arguments will be assigned to +argument+ in the method as an Array. + +If the method definition doesn't include keyword arguments the keyword or +hash-type arguments are assigned as a single hash to the last argument: + + def my_method(options) + p options + end + + my_method('a' => 1, b: 2) # prints: {'a'=>1, :b=>2} + +If too many positional arguments are given an ArgumentError is raised. + +=== Default Positional Arguments + +When the method defines default arguments you do not need to supply all the +arguments to the method. Ruby will fill in the missing arguments in-order. + +First we'll cover the simple case where the default arguments appear on the +right. Consider this method: + + def my_method(a, b, c = 3, d = 4) + p [a, b, c, d] + end + +Here +c+ and +d+ have default values which ruby will apply for you. If you +send only two arguments to this method: + + my_method(1, 2) + +You will see ruby print <code>[1, 2, 3, 4]</code>. + +If you send three arguments: + + my_method(1, 2, 5) + +You will see ruby print <code>[1, 2, 5, 4]</code> + +Ruby fills in the missing arguments from left to right. + +Ruby allows default values to appear in the middle of positional arguments. +Consider this more complicated method: + + def my_method(a, b = 2, c = 3, d) + p [a, b, c, d] + end + +Here +b+ and +c+ have default values. If you send only two arguments to this +method: + + my_method(1, 4) + +You will see ruby print <code>[1, 2, 3, 4]</code>. + +If you send three arguments: + + my_method(1, 5, 6) + +You will see ruby print <code>[1, 5, 3, 6]</code>. + +Describing this in words gets complicated and confusing. I'll describe it +in variables and values instead. + +First <code>1</code> is assigned to +a+, then <code>6</code> is assigned to ++d+. This leaves only the arguments with default values. Since +<code>5</code> has not been assigned to a value yet, it is given to +b+ and ++c+ uses its default value of <code>3</code>. + +=== Keyword Arguments Keyword arguments follow any positional arguments and are separated by commas like positional arguments: @@ -58,7 +149,9 @@ Any keyword arguments not given will use https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L149 definition. If a keyword argument is given that the method did not list an ArgumentError will be raised. -== Block Argument +=== Block Argument + +The block argument sends a closure from the calling scope to the method. The block argument is always last when sending a message to a method. A block is sent to a method using <code>do ... end</code> or <code>{ ... }</code>: @@ -97,14 +190,45 @@ go in <code>| ... |</code> following the https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L190 # ... end -== Array to Arguments Conversion +==== Block Local Arguments + +You may also declare block-local arguments to a block using <code>;</code> in +the block arguments list. Assigning to a block-local argument will not +override local arguments outside the block in the caller's scope: + + def my_method + yield self + end + + place = "world" + + my_method do |obj; place| + place = "block" + puts "hello #{obj} this is #{place}" + end + + puts "place is: #{place}" + +This prints: + + hello main this is block + place is world + +So the +place+ variable in the block is not the same +place+ variable as +outside the block. Removing <code>; place</code> from the block arguments +gives this result: + + hello main this is block + place is block + +=== Array to Arguments Conversion Given the following method: - def my_method(argument1, argument2) + def my_method(argument1, argument2, argument3) end -You can turn an Array into an Argument list with <code>*</code> (or splat) +You can turn an Array into an argument list with <code>*</code> (or splat) operator: arguments = [1, 2, 3] @@ -120,7 +244,16 @@ Both are equivalent to: https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L244 my_method(1, 2, 3) If the method accepts keyword arguments the splat operator will convert a hash -at the end of the array into keyword arguments. +at the end of the array into keyword arguments: + + def my_method(a, b, c: 3) + end + + arguments = [1, 2, { c: 4 }] + my_method(*arguments) + +You may also use the <code>**</code> (described next) to convert a Hash into +keyword arguments. If the number of objects in the Array do not match the number of arguments for the method an ArgumentError will be raised. @@ -128,7 +261,44 @@ the method an ArgumentError will be rais https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L261 If the splat operator comes first in the call, parentheses must be used to avoid a warning. -== Proc to Block Conversion +=== Hash to Keyword Arguments Conversion + +Given the following method: + + def my_method(first: 1, second: 2, third: 3) + end + +You can turn a Hash into keyword arguments with the <code>**</code> operator: + + arguments = { first: 3, second: 4, third: 5 } + my_method(**arguments) + +or: + + arguments = { first: 3, second: 4 } + my_method(third: 5, **arguments) + +Both are equivalent to: + + my_method(first: 3, second: 4, third: 5) + +If the method definition uses <code>**</code> to gather arbitrary keyword +arguments they will not be gathered by <code>*</code>: + + def my_method(*a, **kw) + p arguments: a, keywords: kw + end + + my_method(1, 2, '3' => 4, five: 6) + +Prints: + + {:arguments=>[1, 2], :keywords=>{"3"=>4, :five=>6}} + +Unlike the splat operator described above the <code>**</code> operator has no +commonly recognized name. + +=== Proc to Block Conversion Given a method that use a block: @@ -146,6 +316,6 @@ operator: https://github.com/ruby/ruby/blob/trunk/doc/syntax/calling_methods.rdoc#L316 If the splat operator comes first in the call, parenthesis must be used to avoid a warning. -Unlike the splat operator described above the <code>&</code> has no commonly -recognized name. +Unlike the splat operator described above the <code>&</code> operator has no +commonly recognized name. Index: ChangeLog =================================================================== --- ChangeLog (revision 38822) +++ ChangeLog (revision 38823) @@ -1,3 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Jan 15 10:54:59 2013 Eric Hodel <drbrain@s...> + + * doc/syntax/calling_methods.rdoc (Arguments): Added improved + introduction to arguments including passing style and lazy + evaluation. Thanks to Matt Aimonetti. + * doc/syntax/calling_methods.rdoc (Positional Arguments): Added + description for sending a message to a method with *arguments + * doc/syntax/calling_methods.rdoc (Default Positional Arguments): + Added description. Thanks to Andy Lindeman. + * doc/syntax/calling_methods.rdoc (Block Local Arguments): + Added description of block locals. Thanks to Justin Collins. + * doc/syntax/calling_methods.rdoc (Hash to Keyword Arguments): Added + section describing ** operator. Thanks to Justin Collins. + Tue Jan 15 10:40:18 2013 Marc-Andre Lafortune <ruby-core@m...> * test_lazy_enumerator: Test that map & flat_map also require a block -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/