G
Gavin Sinclair
Hi,
Porting a program from 1.8 to 1.9, I hit a stumbling block in the use
of instance_eval.
The following code works in 1.8 but not 1.9. instance_eval in 1.9
does not allow you to use a lambda as a block. The solution is to use
a proc instead. I understand that lambdas are like methods and procs
are like blocks, but what gets me is the incredibly unhelpful error
message.
Anyway, the code (can also see it at http://gist.github.com/479572 )
class InstanceEval
def initialize(x)
@block = x
@context = Object.new
end
def run
code = @block
result = @object.instance_eval(&code)
"* run --> #{result.inspect}"
end
end
p = proc { }
l = lambda { :l } # (line 16 -- for the error message below)
puts InstanceEval.new(p).run
puts InstanceEval.new(l).run
The output in 1.8:
* run -->
* run --> :l
The output in 1.9:
* run -->
code.rb:16:in `block in <main>': wrong number of arguments (1 for 0)
(ArgumentError)
from code.rb:10:in `instance_eval'
from code.rb:10:in `run'
from code.rb:19:in `<main>'
To what method have I passed one argument where zero arguments were expected?
Is the average Ruby programmer supposed to know that instance_eval
can't take a lambda in Ruby 1.9? Perhaps it should say so in the
documentation. (http://bit.ly/96HBeb)
Is there a good reason ( instance_eval &lambda_object ) can't work?
Thanks for any light you can shed on it.
Gavin
Porting a program from 1.8 to 1.9, I hit a stumbling block in the use
of instance_eval.
The following code works in 1.8 but not 1.9. instance_eval in 1.9
does not allow you to use a lambda as a block. The solution is to use
a proc instead. I understand that lambdas are like methods and procs
are like blocks, but what gets me is the incredibly unhelpful error
message.
Anyway, the code (can also see it at http://gist.github.com/479572 )
class InstanceEval
def initialize(x)
@block = x
@context = Object.new
end
def run
code = @block
result = @object.instance_eval(&code)
"* run --> #{result.inspect}"
end
end
p = proc { }
l = lambda { :l } # (line 16 -- for the error message below)
puts InstanceEval.new(p).run
puts InstanceEval.new(l).run
The output in 1.8:
* run -->
* run --> :l
The output in 1.9:
* run -->
code.rb:16:in `block in <main>': wrong number of arguments (1 for 0)
(ArgumentError)
from code.rb:10:in `instance_eval'
from code.rb:10:in `run'
from code.rb:19:in `<main>'
To what method have I passed one argument where zero arguments were expected?
Is the average Ruby programmer supposed to know that instance_eval
can't take a lambda in Ruby 1.9? Perhaps it should say so in the
documentation. (http://bit.ly/96HBeb)
Is there a good reason ( instance_eval &lambda_object ) can't work?
Thanks for any light you can shed on it.
Gavin