From: James Coglan Date: 2009-08-06T21:43:08+09:00 Subject: Re: Kernel's module methods? --001636c5a7e80933540470787641 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 2009/8/6 Brian Candler > 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 # > > 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 => # 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. -- James Coglan http://jcoglan.com --001636c5a7e80933540470787641--