Florian G. Pflug schrieb:
> Hi

Moin!

> I'm trying to add a method that receives a block as an argument via
> define_method - but none of the following versions work.

You can try something like this:

obj = Object.new

sklass = class << obj
   def meth1(*args, &block)
     _meth1(args, block)
   end

   self
end

some_variable = "bar"

sklass.send(:define_method, :_meth1) do |args, block|
   block.call(some_variable, *args)
end

obj.meth1("foo") { |var, str| p [str, var] } # outputs ["foo", "bar"]

As you see this way you still get the closure behavior of define_method. 
(You can access variables from the scope where you defined the method 
from within the method.)

It's all a bit complex, but this is the only way to do this right now.

Maybe it would be better to define a convenience method for this:

class Class
   def define_block_method(name, &block)
     internal_name = :"_#{name}"

     module_eval %{
       def #{name}(*args, &block)
         #{internal_name}(args, block)
       end
     }

     define_method(internal_name, &block)
     return block
   end
end

It's used like this:

Fixnum.define_block_method(:new_times) do |args, block|
   (1 .. self).each { |i| block.call(i) }
   self
end

5.new_times { puts "foo" } # outputs 3 "foo"s

> greetings, Florian Pflug

Regards,
Florian Gross