- set
self
to the receiver for the duration of the block - set the current class to class/module which is the receiver
- can be called only on classes and modules
- => it's like re-opening the class/module
- => the scope of the block is that class
- => the methods defined in the block go directly in that class, so they become instance methods of that class (or module)
- set
self
to the receiver - set the current class to the singleton class of the receiver
- can be called on any object
- => the scope of the block is the instance itself
- => the methods defined in the block becomes singleton methods of the instance object (in case of classes, they become so-called "class-level methods")
- => DSLs in a block: execute a block in the context of an object
Passing a string to eval instead of a block can avoid the closure and the memory footprint of all the captured bindings
Modules in Ruby are just objects (instance of class "Module"): there's no surprise here, since everything in Ruby is an object. But modules differ from classes, in that a class (instance of class "Class") is a specialized version of a module (someone would say "a subtype") which can instantiate objects (through Class#new method
) and can have a parent superclass (Class#superclass
).
So if I'd like to add or modify methods on all modules, what I have to do is re-open the Module
class:
class Module
def included(mod)
puts "I'm re-writing a default implementation of Module#included hook method!"
end
end
But you know what? Module is a class too! Don't belive to me? Ask to Ruby:
Module.is_a? Class
# => true
Why that? Because Module is an object, so it has a class. And what is Module's class? The class Class
:
Module.class
# => Class
Ok, so Module
is an instance of class Class
, so it's lookup path will go "one to the right" in its class, Class
, than up through Module
, Object
and so on...
Here you have the lookup path (which includes also singleton classes, between squared brackets):
BasicObject
Kernel
Object
Module
Class
[BasicObject]
[Object]
[Module]
which means that while going up in the lookup chain, Module will pass through its instance methods! The same is true for Class, and this is simply because a Class is at the same time an object and a class.
Well, every module is an instance of Module
, created with the "module <module_name>" syntax or with Module.new
, while Module
is a class (actually the superclass of Class
).
1.9.3p385 :026 > Module.is_a? Class
=> true
1.9.3p385 :005 > Math.is_a? Class
=> false
By the way, this is the official definition of Module (http://www.ruby-doc.org/core-2.0/Module.html):
A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (See Module#module_function)