What the purpose of bind/unbind methods in Ruby?
It is indeed useful for metaprogramming. Suppose you want to know the location of the source code for SomeClass#method
. If you can generate an instance of SomeClass
, then you can create a (bound) method instance of it on that SomeClass
instance, on which you can call various methods to investigate some meta-data of the method. But what if you did not know the method signature of SomeClass#new
, or what if SomeClass
's constructor method was named other than SomeClass#new
? Just safely creating an instance of SomeClass
can be difficult. That is where unbound method comes in handy. Without bothering with a particular instance of the class, or with how to create an instance, you can simply do SomeClass.instance_method(:a_method)
(which is an unbound method), then call source_location
on it to investigate the location of the definition:
unbound = SomeClass.instance_method(:a_method)
puts unbound.source_location
And when would this kind of metaprogramming be necessary in the real world applications? One example is when you are creating an IDE with functions for method lookup.
how to check what object that a method bind to?
The receiver of the method is returned by the aptly named Method#receiver
method.
What mechanism is used to allow one to call methods defined in ruby root scope from that scope?
This is really special cased in Ruby. If you define methods in the global scope they get actually defined on Kernel
which is included in every object by default.
Kernel is also there when no other context is defined. Since Class inherits also from Kernel methods defined on it are also in scope in class scopes.
Using instance_exec and converting a method to a Proc
It seems that, in Ruby, methods defined using def some_method
are bound permanently to the class they're defined in.
So, when you call .to_proc
on them they keep the binding of their original implementation, and you cannot rebind them. Well, you can, but only to an object of the same type as the first one. It's possible I could do some fancyness with inheritance, but I don't think so.
The solution becomes instead of using methods, I just put actual Proc
s into variables and use them then, as they're not bound until execution time.
Singleton method error from bind when called with the same metaclass
This should work for you:
class Module
def add_logging(*method_names)
method_names.each do |method_name|
original_method = method(method_name).unbind
define_singleton_method(method_name) do |*args, &blk|
puts "#{self}.#{method_name} called"
original_method.bind(self).call(*args, &blk)
end
end
end
end
# class method example
module MyModule
def self.module_method1
puts "hello"
end
add_logging :module_method1
end
MyModule.module_method1
# output:
#
# MyModule.module_method1 called
# hello
Related Topics
How to Run Ruby in Haml in JavaScript Definition
Made a Mistake Installing Rvm with Sudo. How to Reverse
How to Implement Composite Primary Keys in Rails
How to Assert That No Route Matches in a Rails Integration Test
Change The Ruby Process Name in Top
"Ruby.Exe Is Not Recognized as an Internal or External Command" in Windows 7
Why Are My Thread Variables Intermittent in Rails
Rails Server Does Not Start -> Could Not Find a JavaScript Runtime
What's The Impact of Eager_Load=True
Getting Remove_Entry_Secure Error While Using Ruby Application
Download File from S3 to Rails 4 App
What Ide/Editor Do You Use for Ruby on Linux
How to Send Message to All Client Except Sender in Rails/Actioncable
How to Read from Redis Inside a Multi Block in Ruby