define_method(...) public

Defines an instance method in the receiver. The method parameter can be a Proc or Method object. If a block is specified, it is used as the method body. This block is evaluated using instance_eval, a point that is tricky to demonstrate because define_method is private. (This is why we resort to the send hack in this example.)

class A
  def fred
    puts "In Fred"
  def create_method(name, &block)
    self.class.send(:define_method, name, &block)
  define_method(:wilma) { puts "Charge it!" }
class B < A
  define_method(:barney, instance_method(:fred))
a = B.new
a.create_method(:betty) { p self }


In Fred
Charge it!
Show source
Register or log in to add new notes.
November 5, 2009
9 thanks

define_method with parameters

Just to be clear, you can do this:

define_method(:my_method) do |foo, bar| # or even |*args|
  # do something

This means same as:

def my_method(foo, bar)
  # do something

If you want to define method with parameters that have default values, you need to get a bit more creative and do something like this:

define_method(:my_method) do |foo, bar|
  bar ||= {}
  # do something
August 3, 2015
1 thank

define_method with default parameters

To define a method with a default parameter the usual notation can be used:

define_method("example") do |fixed, default = {}|
  # something
May 5, 2010
0 thanks

Avoiding the "multiple values for a block parameter" warning

As pointed out below, you can also have optional parameters. But you will get something like “warning: multiple values for a block parameter (0 for 1)” if you omit them.

You can avoid those warnings by passing *args and picking the parameters yourself:

define_method :that_method do |*args|

  foo = args[0] || 'my default'
  # ...

Now the warning will be gone. Just make sure you fetch your parameters from *args and assign a default value (unless you want them to default to nil).