B Seven
B Seven

Reputation: 45951

How to pass a variable to a Ruby proc that updates dynamically?

p = Proc.new{ |v| puts v }
p(5) #=> 5

This works fine, but what if I want to "bind" v so it updates dymanically. For example:

p = Proc.new{ ... puts v }
v = 5
p #=> 5
v = 7
p #=> 7

Upvotes: 1

Views: 1721

Answers (2)

Cluster
Cluster

Reputation: 5626

Declare the variable before the proc. When the proc is created it will take into account any local variables already declared.

This errors out because the variable was declared after the proc.

1.9.3p327 :001 > p = Proc.new { puts a }
 => #<Proc:0x9b91e4c@(irb):1> 
1.9.3p327 :002 > p.call()
NameError: undefined local variable or method `a' for main:Object
    from (irb):1:in `block in irb_binding'
    from (irb):2:in `call'
    from (irb):2
    from /home/chris/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in `<main>'
1.9.3p327 :003 > a = 1
 => 1 
1.9.3p327 :004 > p.call()
NameError: undefined local variable or method `a' for main:Object
    from (irb):1:in `block in irb_binding'
    from (irb):4:in `call'
    from (irb):4
    from /home/chris/.rvm/rubies/ruby-1.9.3-p327/bin/irb:16:in `<main>'

This works with the variable declared before the proc.

1.9.3p327 :001 > a = 1
 => 1 
1.9.3p327 :002 > p = Proc.new { puts a }
 => #<Proc:0x8cc2d44@(irb):2> 
1.9.3p327 :003 > p.call()
1
 => nil 
1.9.3p327 :004 > a = 2
 => 2 
1.9.3p327 :005 > p.call()
2
 => nil

Upvotes: 1

nurettin
nurettin

Reputation: 11756

You already did it right. Just use call to execute your proc:

irb(main):001:0> v= 42
=> 42
irb(main):002:0> p= Proc.new{ puts v }
=> #<Proc:0x422007a8@(irb):2>
irb(main):003:0> p.call
42
=> nil
irb(main):004:0> v= 43
=> 43
irb(main):005:0> p.call
43
=> nil
irb(main):006:0> 

Upvotes: 3

Related Questions