harp:~ > cat a.rb
class Object
def defines method
singleton_class = class << self; self; end
([singleton_class] + self.class.ancestors).reverse.each do |a|
return a if a.instance_methods.include? method
end
return nil
end
alias defines? defines
end
module M
def foobar; end
end
class C
def foo; end
end
class B < C
include M
def bar; end
end
1. a method created with Classname.method( 'method_name' )
knows the class it's defined for, as inspect shows.
Object.methods returns an Array of Strings only.
ObjectSpace.each_object( Method ) delivers methods created
as in 1. only
Does Reflection provides a way to find out ?
Like Ara said, it doesn't seem to be provided
So, another (crude) hack ...
···
#---------------------------------
class Method
def definer_class
inspect =~ /:\s(\w+)/
Object.const_get($1)
end
end #---------------------------------
tm = Time.method(:now)
p tm #-> #<Method: Time.now>
p tm.definer_class #-> Time #---------------------------------
<aside:>
Internally the information we want is stored in an
instance_variable called @__attached__ but it's not
accessible from a script. (??)
p tm.instance_variable_get(:@__attached__)
p tm.class.instance_variable_get(:@__attached__)
p (class << tm; self; end).instance_variable_get(:@__attached__)
#-> nil # (all)
</aside:>
harp:~ > cat a.rb
class Object
def defines method
singleton_class = class << self; self; end
([singleton_class] + self.class.ancestors).reverse.each do |a|
return a if a.instance_methods.include? method
end
return nil
end
alias defines? defines
end
If you want to get at the class reported by Method#inspect, you shouldn't
reverse the ancestors list. As a consequence, you have to treat singleton
methods special. If you also want to support private singleton methods, it gets
really nasty. If someone needs this (support for private singleton methods), I
can show you the code.