How does following code works and, more importantly, why does it work that way?
class Example
def one
def one
@value = 99
end
puts "Expensive Call"
@value = 99 # assume its expensive call
end
end
ex = Example.new
puts ex.one # => "Expensive Call"; 99
puts ex.one # => 99
Here, on first call to method one
, Ruby executes the outer one
method, but on successive calls, it executes only the inner one
method, bypassing the outer one
method totally.
I want to know how does it happen and why does it happen so.
To define and execute a dynamic method Declare a delegate type to execute the method. Create an array that specifies the parameter types for the dynamic method. Create a DynamicMethod. Emit the method body. Create an instance of the delegate (declared in step 1) that represents the dynamic method by calling the CreateDelegate method.
The method is associated with the module that contains the Example class, which contains the example code. Any loaded module could be specified. The dynamic method acts like a module-level static method ( Shared in Visual Basic). Emit the method body. In this example, an ILGenerator object is used to emit the Microsoft intermediate language (MSIL).
However, the ' name appears in calls stacks and can be useful for ' debugging. ' ' In this example the return type of the dynamic method ' is Long. The method is associated with the module that ' contains the Example class. Any loaded module could be ' specified. The dynamic method is like a module-level ' Shared method.
The second dynamic method has two parameters, of type Example and type int ( Integer in Visual Basic). When the dynamic method has been created, it is bound to an instance of Example, using a generic delegate that has one argument of type int.
Ruby allows you to redefine classes at run-time, because class and def are actually executable code. In your example, the code does the following:
Basically, the last definition of a method replaces any earlier definitions in that namespace, but the methods are actually new objects. You can see this in action as follows:
def my_method
puts 'Old Method'
puts self.method(:my_method).object_id
def my_method
puts 'New Method'
puts self.method(:my_method).object_id
end
end
If you run this in an irb or pry session, you can see the method redefined at run-time:
> my_method; puts; my_method
Old Method
8998420
New Method
8998360
As you can see by the different object IDs, even though the methods have the same name and are attached to the same object (generally main at the console), they are actually different method objects. However, since the methods were defined with the same name, only the most recent definition is found when the instance does a method lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With