Ruby method with parameters in double parenthesis

  • A+
Category:Languages

I have come across the following code in erb library. Note the double (( )):

class MyTest   def location=((filename, lineno))     @filename = filename     @lineno = lineno if lineno   end end 

The following locatia= method is another version without the (( )) for testing:

class MyTest       def locatia=(filename, lineno)     @filename = filename     @lineno = lineno if lineno   end end 

I got this result:

a = MyTest.new a.location = "foo", 34 a # => #<MyTest:0x2a2e428 @filename="foo", @lineno=34>  b = MyTest.new b.location = "foo" b # => #<MyTest:0x2a2e338 @filename="foo">  c = MyTest.new c.locatia = "foo", 34 c # >> `locatia=': wrong number of arguments (given 1, expected 2) (ArgumentError) 

The version with double parenthesis works fine. The one with single fails. It must be specified on some level of the source code. Any clues?

 


Destructuring.

location= accepts one parameter. This parameter is assumed to be an array, and is destructured so that the first element of array goes into filename, and the second into lineno. The outer parentheses are the normal (usually optional) parentheses of a method definition; the inner parentheses indicate the structure of the first (and only) parameter.

Here's another example of destructuring at work:

{ foo: 17, bar: 34 }.each.with_index { |(key, value), index|   p [key, value, index] } # => [:foo, 17, 0] #    [:bar, 34, 1] 

Hash#each generates pairs [key, value]; Enumerator#with_index generates pairs of [value, index]. Apply them both, and you get [[key, value], index] passed to the block. We could just do this:

{ foo: 17, bar: 34 }.each.with_index { |pair, index|   key = pair[0]   value = pair[1]   p [key, value, index] } 

but it is so much simpler with destructuring. We could even write (key, value) = pair (or key, value = pair, as single-rvalue arrays are automatically destructured in multi-lvalue assignment) as another example of destructuring.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: