Define_method and blocks

Hi

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

Version1: (gives a syntax error - &block doesn’t seem to be allowed in block arguments)
define_method(:meth1) do |*args, &block|
block.call
end

Version2: (gives "No block given, altough I called methd2 with a block)
define_method(:meth2) do |*args|
Proc::new.call
end

Version3: (“No block given” - the same as before)
define_method(:meth3) do |*args|
yield
end

Is it possible to define methods that accept blocks as parameters using
define_method()?

greetings, Florian Pflug

Hi

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

[snip]

Is it possible to define methods that accept blocks as parameters using
define_method()?

I believe that both procs and blocks use the block from the scope in
which they are defined, making it impossible using define_method.

···

Florian G. Pflug (fgp@phlo.org) wrote:


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

I thought Matz was contemplating &block parameters for blocks for the future,
but I can’t find the post by searching ruby-talk.

Currently what you want is not possible, but it may be in the future.

  • Dan

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

As it seems you can’t do it with define_methods, you could try using
eval. It is slower, but it should work. Try something like this :
eval %{
class MyClass
def meth1(*args, &block)
block.call
end
end
}

eval is the most powerful statement in the script languages…

PS : I have not tested it, because I have no ruby interpreter to test
this on. But the idea should work :o)

Vincent Isambart

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

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/90671

···

On Tue, Apr 06, 2004 at 12:23:40PM +0900, Dan Doel wrote:

I thought Matz was contemplating &block parameters for blocks for the future,
but I can’t find the post by searching ruby-talk.


Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Sex, Drugs & Linux Rules
– MaDsen Wikholm, mwikholm@at8.abo.fi