$ ruby -e ‘module Kernel;define_method(foo) { yield 1 };end;foo {|x| p x}’
-e:1:in <module:Kernel>': undefined local variable or method foo’
you meant :foo
Yes, of course. Thanks for catching that. Then we get
$ ruby -e ‘module Kernel;define_method(:foo) { yield 1 };end;foo {|x| p
x}’
-e:1:in block in <module:Kernel>': no block given (yield) (LocalJumpError) from -e:1:in ’
$ ruby -e ‘module Kernel;define_method(foo) { yield 1 };end;foo {|x| p x}’
-e:1:in <module:Kernel>': undefined local variable or method foo’
you meant :foo
Yes, of course. Thanks for catching that. Then we get
$ ruby -e ‘module Kernel;define_method(:foo) { yield 1 };end;foo {|x| p
x}’
-e:1:in block in <module:Kernel>': no block given (yield) (LocalJumpError) from -e:1:in ’
I looked at all the posts again, and realized that both, you li, and
Robert, have already presented the proper solution to your original
post. In fact you yourself, li, offered the solution at the end of your
first post above. Namely, contrary to the quote in ‘The Ruby P.ming
Language’ book, the following code with ‘define_method’ works just fine:
Kernel.send :define_method, :each_event do |events, &block|
events.each_pair do |message, condition|
block.call message, condition
end
end
events = { one: 1, two: 2, three: 3 }
each_event(events) { |m, c| puts “message:#{m}, condition:#{c}” }
I want to define a method in kernel using Flattern Scope.
Kernel.send :define_method, :each_event do
events.each_pair do |message, condition|
yield message, condition
end
end
. . .
However, if I use send define_method method to define each_event, I
would met a exception:
in `each_event’: no block given (LocalJumpError)
I do not know why? if I do not use “send”, the “yield” work well. Also,
I can define method as follows according to “meta programming ruby”
says:
Kernel.send :define_method, :each_event do |&block|
events.each_pair do |message, condition|
block.call message, condition
end
end
The problem is not the ‘send’, but rather the ‘define_method’. Namely,
‘define_method’ does not allow you to specify a method body that expects
a blok. If you need to dynamically create a method that accepts a block,
you need to use the ‘def method_name; …; end’ and the ‘class_eval’
(see: D. Flanagan’s & Y. Matsumoto’s book ‘The Ruby P.ming
Language’ page:275).
So, your example should look something like the following:
Kernel.class_eval do
def each_event(events)
events.each_pair do |message, condition|
yield message, condition
end
end
end
events = { one: 1, two: 2, three: 3 }
each_event(events) { |x, y| puts “#{x}, #{y}” }
Regards, igor
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.