B Seven
B Seven

Reputation: 45943

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: 5617

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: 11736

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