views:

1228

answers:

2

I would like to pass an argument(s) to a method being defined using define_method, how would I do that?

+12  A: 

The block that you pass to define_method can include some parameters. That's how your defined method accepts arguments. When you define a method you're really just nicknaming the block and keeping a reference to it in the class. The parameters come with the block. So:

define_method(:say_hi) { |other| puts "Hi, " + other }
Kevin Conner
+11  A: 

In addition to Kevin Conner's answer: block arguments do not support the same semantics as method arguments. You cannot define default arguments or block arguments.

This is only fixed in Ruby 1.9 with the new alternative "stabby lambda" syntax which supports full method argument semantics.

Example:

# Works
def meth(default = :foo, *splat, &block) puts 'Bar'; end

# Doesn't work
define_method :meth { |default = :foo, *splat, &block| puts 'Bar' }

# This works in Ruby 1.9 (modulo typos, I don't actually have it installed)
define_method :meth, ->(default = :foo, *splat, &block) { puts 'Bar' }
Jörg W Mittag
Actually, I believe block arguments on define_method do support splat, which can provides a round-a-bout way to define default arguments too.
Chinasaur
Chinasaur is correct about block arguments allowing splats. I've confirmed this in both Ruby 1.8.7 and 1.9.1.
Peter Wagenet
Thanks, I forgot about this. Fixed now.
Jörg W Mittag