benjohn
3/25/2006 10:34:00 AM
On 25 Mar 2006, at 02:09, dblack@wobblini.net wrote:
> Hi --
>
> On Sat, 25 Mar 2006, Axel Schlueter wrote:
>
>> Hi,
>>
>> When reading somes ruby source I saw the
>> *array_name notation, an asterisk in front
>> of an array variables. I was unable to look
>> up its meaning in the pickaxe. What exactly
>> does the asterisk do to the array ? Any hints
>> on where I can find a description in the
>> pickaxe ?
There's something about it near the beginning, in the section about
passing arguments to functions. In fact, until the post below, I had
no idea it could be used more generally!
> The * is a "unary unarray" operator. It "un-arrays" the array into a
> list of separate values.
>
> Thus, for example:
>
> a = [4,5,6]
> [1,2,3,*a] => [1,2,3,4,5,6]
>
> There are rules about where and when and how it can be used, but
> that's basically what's happening when you see that.
That makes a lot of sense, thank you! Usually this will be used to
allow a function to take additional arguments:
def a_function( required_argument, also_required,
*any_optional_arguments )
puts required_argument
puts also_required
puts any_optional_arguments.join(',')
end
Calling:
> irb(main):006:0> a_function(1,2,3,4,5)
> 1
> 2
> 3,4,5
You can also use it to split out an array in to seperate parameters
(so kind of the opposite of the above). Again, this is often used
when calling a method:
> irb(main):007:0> a=[1,2,3,4,5]
> => [1, 2, 3, 4, 5]
> irb(main):008:0> a_function(*a)
> 1
> 2
> 3,4,5
> => nil
> irb(main):009:0> a_function(a)
> ArgumentError: wrong number of arguments (1 for 2)
> from (irb):9:in `f'
> from (irb):9
As an example of both of these uses; I'd like to have an object
delegate any method calls that it can't handle to some other object.
I could write it like this:
class DelgatingClass
attr_accessor :my_delegatee
...
# Pick method calls I can't handle, and pass them on to the delegatee.
def method_missing( method_name, *all_the_parameters )
@my_delegatee.send( method_name, *all_the_parameters )
end
...
end
:) However, the above doesn't pick up any optional block that's
passed to the method. To rectify that, you would probably write the
method above like this:
def method_missing( method_name, *all_the_parameters, &optional_block )
@my_delegatee.send( method_name, *all_the_parameters, &optional_block )
end
I think this is also discussed in the same section of the pickaxe.