Using yield inside define_method in Ruby

metaprogramming, ruby

Solution

I think this is what you're looking for:

class Test
  define_method :test do |&b|
    b.call
  end
end

Test.new.test {
  puts "Hi!"
}

More at http://coderrr.wordpress.com/2008/10/29/using-define_method-with-blocks-in-ruby-18/

Problem

Is it possible to make yield keyword work inside a block given to define_method? Simple example: ``` class Test define_method :test do |&b| puts b # => #<Proc:...> yield end end Test.new.test { puts "Hi!" } ``` This code produces following error in both Ruby 1.8.7 and 1.9.0: test.rb:4:in `test': no block given (LocalJumpError) from test.rb:8 The strange thing is the b block variable `!= nil` but `block_given?` returns false. Is it intentional Ruby behaviour not to recognize blocks by Proc objects? Edit: Regards to Beerlington's answer: `b.call()` is is not what I am looking for. Block variable was used only to indicate that block is actually given, and is not detected inside define_method. Reason why I need use `yield` instead of `block.call` I am willing to write some extension to the way how new classes are defined in Ruby, thus any code You can write in pure Ruby should be accepted when I use my extension. So similar semantics cannot be taken into consideration, because this forces users of my library to use only one proper way to pass a block. This breaks the TIMTOWTDI rule, and does not make my library transparent. Real life example Code below can be simplified to code above since `my_def` uses `define_method`: ``` require 'my_library' class Test # client can write 'my_def' instead of 'def' since # my_library extends Class class my_def :test, "some parameter" do yield # oh no, error :( end end Test.new.test { puts "Hi!" } ```

Original source