This is probably best posted to ruby-talk, not ruby-core, folks would
=> nil
irb(main):004:0> “bye”.this(" that")
bye that
=> nil
Cheers,
Sam
That is good news to me. But now I wonder, if and how I can ask e.g.
String#this(opt) in which module it is defined.
First note, that a method can be defined in a module or a class, and
that a class is a kind of module.
I haven’t tested this extensively but I think it works. It searches
for a method name in a class the same way that methods are found at
runtime, at each level of the class hierarchy, the class is searched,
then any modules that class includes in the reverse order they were
included. This code depends on Module#included_modules giving it’s
result in the right order, which a few quick tests seems to indicate:
module A
end
module B
end
module C
include B
include A
end
C.included_modules => [A, B]
module D
include A
include B
end
D.included_modules => [B, A]
Okay so here’s my code:
class Module
def module_defining(method_name)
method_name = method_name.to_s
return self if
instance_methods(false).include?(method_name)
included_modules.each do |mixin|
answer = mixin.module_defining(method_name)
return answer if answer
end
nil
end
end
class Class
def module_defining(method_name)
answer = super
return answer if answer
return superclass.module_defining(method_name) if
superclass
end
end
IMO something like this would make a nice addition to the core library.
Jumping through hoops for introspection is no fun. (At least this one
doesn’t involve any string parsing.)
Note that the Method#inspect method gives you this same information in
string form:
Less or more reliable to use this with string parsing? Perhaps slightly
more, if only to be sure that the method resolution order is properly
followed.
=> #<UnboundMethod: String#==>
more, if only to be sure that the method resolution order is properly
followed.
Well although the ri documentation for Module#included_modules doesn’t
say wo in so many words, it does in fact produce the list in the right
order.
The way an included module is implemented is that a ‘hidden’ proxy
class is inserted between the class which includes the module, and
it’s superclass. It’s hidden because it’s marked as being a T_ICLASS.
The included_modules C code just walks the chain from the super class
and the superclass of the class, listing any T_ICLASSes that it finds.
Since this is the way that method lookup works, it’s exactly the right
order.