tags:

views:

769

answers:

3

Given the Ruby code

line = "first_name=mickey;last_name=mouse;country=usa" 
record = Hash[*line.split(/=|;/)] 

I understand everything in the second line apart from the * operator - what is it doing and where is the documentation for this? (as you might guess, searching for this case is proving hard...)

+15  A: 

The * is the splat operator.

It expands an Array into a list of arguments, in this case a list of arguments to the Hash.[] method. (To be more precise, it expands any object that responds to to_ary/to_a, or to_splat in Ruby 1.9.)

To illustrate, the following two statements are equal:

method arg1, arg2, arg3
method *[arg1, arg2, arg3]

It can also be used in a different context, to catch all remaining method arguments in a method definition. In that case, it does not expand, but combine:

def method2(*args)  # args will hold Array of all arguments
end

Some more detailed information here.

molf
In general, when used as in LHS-like situation (any time you're invoking it on a value), splat splits an array up into separate values, and when used in a RHS-like situation (any time you're using it on some previously undefined variables), it groups separate values into an array. So `a,b,*c = d,e,f,*g` sets a=d, b=e, and c=[f,g0,g1,g2,...,gn], where g=[g0,g1,g2,...,gn]
rampion
great answer, clear and detailed, thanks
David Burrows
Just for completeness, the splat operator turns an array into a bare list according to the terminology used in 'The Well Grounded Rubyist' by David A. Black
David Burrows
@rampion: Wonderful comment, you just mixed LHS and RHS. It's the other way round.
ThomasH
+5  A: 

The star operator unpacks an array passed to a function so that each element is sent to the function as an individual parameter.

A simple example:

>> def func(a, b, c)
>>   puts a, b, c
>> end
=> nil

>> func(1, 2, 3)  #we can call func with three parameters
1
2
3
=> nil

>> list = [1, 2, 3]
=> [1, 2, 3]

>> func(list) #We CAN'T call func with an array, even though it has three objects
ArgumentError: wrong number of arguments (1 for 3)
    from (irb):12:in 'func'
    from (irb):12

>> func(*list) #But we CAN call func with an unpacked array.
1
2
3
=> nil

That's it!

BJ Homer
+1  A: 

As everyone mentions, it's a splat. Looking for Ruby syntax is impossible, and I've asked this in other questions. The answer to that part of the question is that you search on

asterisk in ruby syntax

in Google. Google is there for you, just put what you see into words.

Anyhoo, like a lot of Ruby code, that code is quite dense. The

line.split(/=|;/)

makes an array of SIX elements, first_name, mickey, last_name, mouse, country, usa. Then the splat is used to make that into a Hash. Now the Ruby people always send you to look at the Splat method, since everything is exposed in Ruby. I have no idea where it is, but once you have that, you'll see that it runs a for through the array and builds the hash.

You would look for the code here. If you cannot find it (I could not), you would try to write some lame code yourself like this (which works, but is NOT ruby-like code):

line = "first_name=mickey;last_name=mouse;country=usa"
presplat = line.split(/=|;/)
splat = Hash.new
for i in (0..presplat.length-1)
    splat[presplat[i]] = presplat[i+1] if i%2==0
end

puts splat["first_name"]

and then the Ruby gang will be able to tell you why your code is silly, bad, or just plain wrong.

Edit: If you've read this far, take a read through this, which doesn't explain splat but you do need to know it.

Yar