Search code examples
rubyruby-1.9enumerable

What does the multiplication symbol :* do?


In particular, using inject, the following scripts,

  • puts (1..5).inject {|x, y| x * y} and
  • puts (1..5).inject(:*),

both have output 120 as I expected.

However, the script

print [[1,2], [3,4], [5,6]].map {|x, y| x * y}

has output

[2, 12, 30]

as expected but the script

print [[1,2], [3,4], [5,6]].map(:*)

raises an ArgumentError:

confused_ruby_map_inject.rb:1:in `map': wrong number of arguments(1 for 0) (ArgumentError)
    from confused_ruby_map_inject.rb:1:in `<main>'

Why is this happening, what does :* do, and what's the most concise way to achieve the result I'm looking for with the second set of scripts?


Solution

  • inject() can take a block or a symbol, but map() always takes a block. I think your working map() is concise enough.

    :* is the symbol name for the multiplication method.

    Update: I think your working map() is fine, but it seems like what you might be looking for is the classic map/reduce, even though it's actually longer:

    [[1,2], [3,4], [5,6]].map{|a| a.reduce(:*)}