Kernel's module methods?

According to pickaxe2, p516:

Module Kernel

···

------------
The Kernel module is included by class Object, so its [instance] methods
are available in every Ruby object. The Kernel instance methods are
documented in class Object beginning on page 567. This section
documents the module methods. These methods are called without a
receiver and thus can be called in functional form.
------------

I tried to model that state of affairs with this code:

module K
  def K.test1
    puts "test1"
  end

  def test2
    puts "test2"
  end
end

class O
  include K

  K.test1

  test1
end

--output:--
test1
r2test.rb:16: undefined local variable or method `test1' for O:Class
(NameError)

How come you can call Kernel methods without a receiver?
--
Posted via http://www.ruby-forum.com/.

7stud -- wrote:

How come you can call Kernel methods without a receiver?

If I understand it rightly: because self is the top level object 'main',
and main is an *instance* of Object.

self

=> main

self.class

=> Object

module K
def test2
puts "test2"
end
end

=> nil

class Object; include K; end

=> Object

test2

test2
=> nil

···

--
Posted via http://www.ruby-forum.com/\.

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`. 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.

Another way you could do this is by having all objects inherit from Kernel's
eigenclass, but that's also not allowed in user code so again this points at
special treatment of Kernel code in the Ruby VM.

···

2009/8/6 Brian Candler <b.candler@pobox.com>

7stud -- wrote:
> How come you can call Kernel methods without a receiver?

If I understand it rightly: because self is the top level object 'main',
and main is an *instance* of Object.

--
James Coglan
http://jcoglan.com

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?

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?

···

--
Posted via http://www.ruby-forum.com/\.

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

They are "module functions" actually, implemented with this:

------------------------------------------------- Module#module_function
      module_function(symbol, ...) => self

···

On Aug 6, 2009, at 7:32 AM, Brian Candler wrote:

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?

------------------------------------------------------------------------
      Creates module functions for the named methods. These functions
      may be called with the module as a receiver, and also become
      available as instance methods to classes that mix in the module.
      Module functions are copies of the original, and so may be changed
      independently. The instance-method versions are made private. If
      used with no arguments, subsequently defined methods become module
      functions.

         module Mod
           def one
             "This is one"
           end
           module_function :one
         end
         class Cls
           include Mod
           def callOne
             one
           end
         end
         Mod.one #=> "This is one"
         c = Cls.new
         c.callOne #=> "This is one"
         module Mod
           def one
             "This is the new one"
           end
         end
         Mod.one #=> "This is one"
         c.callOne #=> "This is the new one"

James Edward Gray II

Thanks for pointing that out, I wasn't aware of it. Reminds me of a neat
trick for adding a module's instance methods to the same module as singleton
methods:

module MyMod
  extend self
end

Any instance methods from MyMod (and modules it includes) will appear as
singleton methods on the MyMod object. It differs from #module_function in
that the methods are not copied, so if you change MyMod#foo, MyMod.foo will
be updated to reflect the new method.

···

2009/8/6 James Gray <james@grayproductions.net>

On Aug 6, 2009, at 7:32 AM, Brian Candler wrote:

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?

They are "module functions" actually, implemented with this:

------------------------------------------------- Module#module_function
    module_function(symbol, ...) => self
------------------------------------------------------------------------
    Creates module functions for the named methods. These functions
    may be called with the module as a receiver, and also become
    available as instance methods to classes that mix in the module.
    Module functions are copies of the original, and so may be changed
    independently. The instance-method versions are made private. If
    used with no arguments, subsequently defined methods become module
    functions.

--
James Coglan
http://jcoglan.com

James Coglan wrote:

In fact, `puts` does not even appear as an instance method on Object:

Object.instance_methods.grep /puts/
=>

but:

irb(main):001:0> Object.private_instance_methods.grep(/puts/)
=> ["puts"]

···

--
Posted via http://www.ruby-forum.com/\.

Yes, and I generally prefer extend(self) to module_function after much time trying it both ways. Unfortunately, I always seem to eventually run into issues after using module_function, say with constant resolution or included modules (like you mentioned).

James Edward Gray II

···

On Aug 6, 2009, at 8:12 AM, James Coglan wrote:

2009/8/6 James Gray <james@grayproductions.net>

On Aug 6, 2009, at 7:32 AM, Brian Candler wrote:

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?

They are "module functions" actually, implemented with this:

------------------------------------------------- Module#module_function
   module_function(symbol, ...) => self
------------------------------------------------------------------------
   Creates module functions for the named methods. These functions
   may be called with the module as a receiver, and also become
   available as instance methods to classes that mix in the module.
   Module functions are copies of the original, and so may be changed
   independently. The instance-method versions are made private. If
   used with no arguments, subsequently defined methods become module
   functions.

Thanks for pointing that out, I wasn't aware of it. Reminds me of a neat
trick for adding a module's instance methods to the same module as singleton
methods:

module MyMod
extend self
end

Any instance methods from MyMod (and modules it includes) will appear as
singleton methods on the MyMod object. It differs from #module_function in
that the methods are not copied, so if you change MyMod#foo, MyMod.foo will
be updated to reflect the new method.

James Gray wrote:

Yes, and I generally prefer extend(self) to module_function after much time trying it both ways. Unfortunately, I always seem to eventually run into issues after using module_function, say with constant resolution or included modules (like you mentioned).

Can you post an example of the constant resolution problem next time you come across it? I'm curious because I'm in the habit of using module_function rather than extend(self), not for any good reason except that it is perhaps more self documenting.

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Here's an example I remember from just the other day (though it probably falls more under the included module problem). Consider this simple module:

module MoreMath
   extend Math # needed for self::sqrt
   include Math # needed for self#sqrt and PI

   module_function

   def circ(r)
     2 * PI * r
   end

   def dist(x1, y1, x2, y2)
     sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
   end
end

p MoreMath.circ(12)
p MoreMath.dist(0, 0, 3, 4)

Note that I need both an extend and include to get just that much to work. Or, I can just do:

module MoreMath
   include Math
   extend self

   def circ(r)
     2 * PI * r
   end

   def dist(x1, y1, x2, y2)
     sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
   end
end

p MoreMath.circ(12)
p MoreMath.dist(0, 0, 3, 4)

Anyway, I too like module_function() and have used it a lot. I like how it makes the instance methods private so they don't add to an object's public interface when mixed in.

It just seems like I have more control with extend(self) so I tend to reach for that now.

James Edward Gray II

···

On Aug 6, 2009, at 11:32 AM, Joel VanderWerf wrote:

James Gray wrote:

Yes, and I generally prefer extend(self) to module_function after much time trying it both ways. Unfortunately, I always seem to eventually run into issues after using module_function, say with constant resolution or included modules (like you mentioned).

Can you post an example of the constant resolution problem next time you come across it? I'm curious because I'm in the habit of using module_function rather than extend(self), not for any good reason except that it is perhaps more self documenting.