0

I have an array of integers

a = [3, 4, 5, 6]

and I need to POW this numbers, so they can be like this

a 
# => [9, 16, 25, 36]

I'm trying to do this with this piece of code:

a.map!(&:**2)

but Isn't working :(

Can anyone help me?

vhbsouza
  • 407
  • 2
  • 5
  • 15
  • possible duplicate of [Can you supply arguments to the map(&:method) syntax in Ruby?](http://stackoverflow.com/questions/23695653/can-you-supply-arguments-to-the-mapmethod-syntax-in-ruby) – Uri Agassi May 18 '14 at 04:37

4 Answers4

3

You can use a lambda with & if you so desire:

square = lambda { |x| x**2 }
a.map!(&square)

This sort of thing is pointless busywork with a block so simple but it can be nice if you have a chain of such things and the blocks are more complicated:

ary.select(&some_complicated_criteria)
   .map(&some_mangling_that_takes_more_than_one_line)
   ...

Collecting bits of logic in lambdas so that you can name the steps has its uses.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
2

You should do this

a.map! { |i| i**2 }

Read the docs.

hjing
  • 4,922
  • 1
  • 26
  • 29
1

As a matter of rule, you cannot add parameters to methods using the &:sym syntax.

However, if you follow my suggestion here you could do the following:

class Symbol
  def with(*args, &block)
    ->(caller, *rest) { caller.send(self, *rest, *args, &block) }
  end
end

a.map!(&:**.with(2))
# => [9, 16, 25, 36] 
Community
  • 1
  • 1
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • I think this is smart approach but shouldn't we be wary of modifying Symbol object for our use. – amitamb May 18 '14 at 05:20
  • @amitamb we should if it changes in any way an _existing_ behavior (which might cause breakage in other parts of the code) - but adding a new method which keeps the object in question un-mutated is safe enough - it is actually quite ubiquitous - how do you think Rails got `1.day.ago`? – Uri Agassi May 18 '14 at 06:09
  • I know Rails add so many such features and agree that it is useful. But I have found that adding such support through initializers in Rails can make code bit unreadable. Or using this in a gem means we have to be sure gem user doesn't re-implement it in some way. – amitamb May 18 '14 at 10:03
0

You can only use the &: shortcut syntax if you are calling a method on the object with no arguments. In this case, you need to pass 2 as an argument to the ** method.

Instead, expand the block to the full syntax

a.map! { |n| n**2 }
andars
  • 1,384
  • 7
  • 12
  • Can I do something like this? --> a.map(&2.method(:**)) – vhbsouza May 18 '14 at 02:47
  • AFAIK, you can't. `&` calls `to_proc` on the symbol (`:**`) given, and you can't express arguments in the symbol representing the method. – andars May 18 '14 at 02:55
  • vhbsouze, see Arup's answer [here](http://stackoverflow.com/questions/23695653/can-you-supply-arguments-to-the-mapmethod-syntax-in-ruby/23696043#23696043). – Cary Swoveland May 18 '14 at 02:58
  • Alright, I'm learning now too, so this is for my benefit. Doesn't that answer rely on the commutativity of addition? I don't know if it will work here. – andars May 18 '14 at 03:06
  • 1
    It won't work - but if you follow this http://stackoverflow.com/a/23711606/1120015 - you could do `a.map!(&:**.with(2))` – Uri Agassi May 18 '14 at 04:44