Ruby meta: send/define_method
This course covers two Ruby metaprogramming tools: .send and define_method. It starts with a dispatch problem, where the method to call is only known as data at runtime. The .send method calls any method by a name held in a symbol or string and forwards arguments and blocks. It also bypasses private, while public_send respects it. define_method builds real instance methods from a name and a block, often in a loop. The lessons reimplement attr_accessor with it and read how Rails' delegate generates methods with module_eval.
What you'll learn
- ✓Calling a method by a name computed at runtime with .send
- ✓Why .send bypasses private and when to use public_send
- ✓Generating instance methods with define_method, including in a loop
- ✓Reimplementing attr_accessor with instance_variable_get and instance_variable_set
- ✓How Rails' delegate generates methods with module_eval and a string of source
Calling a method by a name you don't know yet
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.
Read the full lesson free →Curriculum
7 lessonsCalling a method by a name you don't know yet
Why an ordinary call needs a fixed method name, and how metaprogramming treats methods as data.
.send: calling methods by a dynamic name
The .send method calls a method by a symbol or string name, passing arguments and blocks through.
The caveat: send bypasses private
The .send method ignores private access control, public_send respects it, and bypassing private in app code is a design smell.
define_method: generating methods from a block
define_method creates real instance methods from a name and a block, including several from a loop.
Reimplementing attr_accessor with define_method
Builds a pure-Ruby attr_accessor with define_method in a loop, since the real one is written in C.
How Rails' delegate generates methods
Reads activesupport's source to show delegate using module_eval with a string, and delegate_missing_to generating method_missing.
Putting it together
Combines define_method in a loop, a generated private method and .send reaching it in one example.