James Coglan wrote:
> I think the point being raised is that when you mix a module into a
> class,
> the class gains the module's instance methods, but not its
> module/singleton
> methods. So it seems that the only way you'd be able to call Kernel's
> module
> methods without a receiver would be if `self` were equal to `Kernel`.
Yes, but are you sure they are module methods, not just instance
methods?
Yes, for example `puts` is a singleton method on Kernel:
module Kernel
def metaclass
class << self; self; end
end
end
Kernel.metaclass.instance_methods(false).grep /puts/
=> ["puts"]
Kernel.instance_methods(false).grep /puts/
=>
In fact, `puts` does not even appear as an instance method on Object:
Object.instance_methods.grep /puts/
=>
But
> seeing as how you can call these methods sans receiver anywhere in your
> program, I assume the Kernel methods are given special treatment and
> don't
> follow the usual scoping rules for method calls.
Everywhere in your program, you are inside some instance of Object (or a
subclass of Object). And therefore self is that object, and that object
inherits Kernel's instance methods. e.g.
class Foo
def bar
puts "hello"
end
end
foo = Foo.new
foo.bar
The 'puts' inside method :bar is calling foo.puts. Since you haven't
defined your own instance method 'puts' in the Foo class, then it
follows the class hierarchy back up to Kernel. No special casing
involved.
That is: AFAICS, this would make sense as long as foo were an instance
method of module Kernel, not a module/singleton method.
Also note:
foo.puts #=> private method `puts' called for #<Foo:0x82d875c>
So it seems 'puts' is an instance method of our class, albeit a private
one.
Or have I got this completely wrong?
It seems privacy might explain it, since that would stop it showing up in my
above example.
class Foo
def p
method :puts
end
end
Foo.new.p
=> #<Method: Foo(Kernel)#puts>
So that `puts` method is coming from Kernel, even though it doesn't appear
in Kernel.instance_methods. This would suggest that all the Kernel module
methods are in fact private instance methods of `Kernel` (making them
callable from any object), but the Kernel module exposes public singleton
versions of all of them. If this is true the Pickaxe explanation is a little
back-to-front.
···
2009/8/6 Brian Candler <b.candler@pobox.com>
--
James Coglan
http://jcoglan.com