Metaprogramming in Ruby

Open Classes

In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.

Monkey See, Monkey Patch

In Ruby, the term monkey patch means any dynamic modification to a class.

Monkey patching is a practice which involves substituting the pillars of an house: if you're not very careful in what you substitute, the whole building will collapse over your remains. Moreover, you may take down some underground stations full of people as well as a side-effect.

Classes

Classes themselves are nothing but objects.

Calling methods dynamically

The most common way for dynamic method calling is to send a message to object.

A Method object represents a chunk of code and a context in which it executes. Once we have our Method object, we can execute it sometime later by sending it the message call.

Or just eval

Instantiating a method object is the fastest dynamic way in calling a method, eval is the slowest one. Also when sending a message to an object, or when instantiating a method object, you can call private methods of that object.

Defining methods dynamically

You can define a method on the spot with define_method(). You just need to provide a method name and a block, which becomes the method body.

Undefining methods

A method can be undefined any time, as well as defined.


Defining classes dynamically

Undefining class

As a class is just an object in the memory, which is identified by the constant, destroying a constant will cause a class itself to be removed by GC

Method missing

When you send a message to an object, the object executes the first method it finds on its method lookup path with the same name as the message. If it fails to find any such method, it end up with method_missing method, where a NoMethodError exception is raised unless you have provided other behavior for it. The method_missing method is passed the symbol of the non-existent method, an array of the arguments that were passed in the original call and any block passed to the original method.

Method aliases

What happens if you alias a method and then redefine it?

Instance variables
instance_variable_get(), instance_variable_set(), instance_variable_defined?()

Blocks and local variables

Methods with shared variable

Binding

In Ruby current binding can be captured, and any code can be evaluated in that captured scope, any time.

instance_eval and instance_exec

instance_eval method evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj).

Class eval

class_eval (also known by its alternate name, module_eval) evaluates a block in the context of an existing class.

Method Objects binding

Runtime introspection

Hook methods

Class plus instance methods

Struct

Follow by http://www.ruby-doc.org/core-2.0.0/Struct.html for more information.

Homework

Please implement your own class 'Factory' which will have the same behavior as 'Struct' class.

Hometask

metakoans.rb

/

#