🎓 A1Learner
🔍
0 of 28 lessons completed

Ruby Define Method at Depth

The intermediate course built methods with define_method from names in a loop. This lesson looks closer at symbol names and at the values the generated blocks capture.

Methods generated from a list of symbols

A list holds two symbols, and the loop builds one method for each symbol. Each generated method answers with its own symbol as a string.

class Parrot
  [:squawk, :chirp].each do |sound|
    define_method(sound) do
      sound.to_s
    end
  end
end
parrot = Parrot.new
puts parrot.squawk
puts parrot.chirp

A symbol name and an argument

The name here is written as the symbol :twice. The block parameter becomes the argument of the generated method.

class Doubler
  define_method(:twice) do |number|
    number * 2
  end
end
puts Doubler.new.twice 21

Each loop pass keeps its own value

The loop runs once for red and once for green. Each block captures the value from its own pass, so the two methods answer differently.

class Team
  [:red, :green].each do |color|
    define_method(color) do
      color.to_s
    end
  end
end
team = Team.new
puts team.red
puts team.green

A shared local answers its last value

This block captures a plain local instead of a loop value. The local is reassigned after the method is built, and the method reads the shared local when it is called.

class Team
  color = :red
  define_method(:shade) do
    color.to_s
  end
  color = :blue
end
puts Team.new.shade

Example

class Greeter
  [:hi, :hey].each do |word|
    define_method(word) do |name|
      "#{word} #{name}"
    end
  end
end
greeter = Greeter.new
puts greeter.hi "Ana"
puts greeter.hey "Ben"

Key points

  • define_method takes a symbol as the name of the new method.
  • The block parameter becomes an argument of the generated method.
  • Each pass of a loop gives its block a fresh captured value.
  • A generated method keeps the value its own block captured.
  • A plain local shared by a block keeps only its last value.

In this example, a loop builds the hi and hey methods on the Greeter class. Each block parameter becomes the name argument of its method. Each call prints its greeting word with the name passed in.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A class sets color = :red, builds a method answering color.to_s, then sets color = :blue. What does the method answer?