Calling a method by a name you don't know yet

Free preview 3 min to read

The problem ordinary method calls can't solve

Every method call so far in this series has looked like object.method_name, with method_name typed into the source code and fixed when the file was written. That covers almost everything, until the method to call is itself data that isn't known until the program runs.

action = fetch_user_choice  # returns "walk", "run", or "jump" -- decided at runtime

Calling robot.action here is wrong: Ruby would look for a method named action instead of reading the string in the variable. The usual fallback is a dispatch table:

case action
when "walk" then robot.walk
when "run" then robot.run
when "jump" then robot.jump
end

This works but doesn't scale. Every new action means editing this case statement too, a second place that has to stay in sync with the methods robot has.

Meta: code that works on code

This course and the next one, which closes this series, are usually filed under "metaprogramming". The name sounds bigger than the idea. It means writing code whose subject is other code: methods, classes and calls treated as data to inspect and change, instead of fixed text someone types out each time. .send and define_method are two of Ruby's most direct tools for this. The same family of techniques lets attr_accessor and Rails' delegate generate methods that nobody wrote out one by one, and later lessons check that against Rails' installed source.

What this course covers

  • .send(:method_name, *args), calling any method by a name computed at runtime, with one important and surprising exception to what "any method" means, covered in lesson 3.
  • define_method, generating methods when a class is defined, from a symbol or string plus a block, instead of writing a separate def for each.
  • How this connects to real Rails source: what attr_accessor and delegate do to generate the methods they promise.

Key takeaways

  • An ordinary object.method_name call needs the method's name as fixed text in the source code, known when the file was written.
  • When the method to call is only known as data at runtime, such as a string or symbol in a variable, you need another mechanism: the subject of this course.
  • Metaprogramming means writing code that treats methods and classes as data, inspecting or generating them, instead of typing every call and definition by hand.
  • .send and define_method are two of Ruby's core metaprogramming tools, and this course checks that Rails' own generators use this family of techniques.
Lesson 1 of 7 · free

Keep going with lesson 2

.send: calling methods by a dynamic name

The .send method calls a method by a symbol or string name, passing arguments and blocks through.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...