-1

I'm reviewing someone's ruby code and in it they've written something similar to:

class Example
  attr_reader :val
  def initialize(val)
    @val = val
  end
end

def trigger
  puts self.val
end

anArray = [Example.new(10), Example.new(21)]
anArray.each(&:trigger)

The :trigger means the symbol is taken and the & transforms it into a proc?

If that's correct, is there any way of passing variables into trigger apart from using self.?

This is related but never answered: http://www.ruby-forum.com/topic/198284#863450

AJP
  • 26,547
  • 23
  • 88
  • 127

3 Answers3

2

Symbol#to_proc is a shortcut for calling methods without parameters. If you need to pass parameters, use full form.

[100, 200, 300].map(&:to_s) # => ["100", "200", "300"]
[100, 200, 300].map {|i| i.to_s(16) } # => ["64", "c8", "12c"]
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
2

is there any way of passing variables into trigger

No.

You're invoking Symbol#to_proc which does not allow you to specify any arguments. This is a convenient bit of sugar Ruby provides specifically for invoking a method with no arguments.

If you want arguments, you'll have to use the full block syntax:

anArray.each do |i|
  i.trigger(arguments...)
end
user229044
  • 232,980
  • 40
  • 330
  • 338
  • I couldn't find this in the docs, how did you learn this / could I have learnt this by myself? Thanks. – AJP Aug 07 '12 at 23:21
  • Google "symbol to_proc". The second link is to [the documentation](http://www.ruby-doc.org/core-1.9.3/Symbol.html#method-i-to_proc). – user229044 Aug 07 '12 at 23:51
  • Nice, I was only trying `&:` and thus not finding anything, including the `(&:to_s)` in that documentation. – AJP Aug 08 '12 at 13:54
0

This will do exactly what you need:

def trigger(ex)
  puts ex.val
end

anArray = [Example.new(10), Example.new(21)]
anArray.each(&method(:trigger))
# 10
# 21
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93