Using yield inside define_method in Ruby

Viewed 6603

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!"
}
2 Answers
Related