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/.
|
|
0
|
|
|
|
Reply
|
bbxx789_05ss (1895)
|
8/6/2009 11:02:06 AM |
|
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/.
|
|
0
|
|
|
|
Reply
|
b.candler (2627)
|
8/6/2009 11:58:44 AM
|
|
[Note: parts of this message were removed to make it a legal post.]
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.
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.
--
James Coglan
http://jcoglan.com
|
|
0
|
|
|
|
Reply
|
jcoglan (199)
|
8/6/2009 12:16:36 PM
|
|
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/.
|
|
0
|
|
|
|
Reply
|
b.candler (2627)
|
8/6/2009 12:32:10 PM
|
|
[Note: parts of this message were removed to make it a legal post.]
2009/8/6 Brian Candler <b.candler@pobox.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.
--
James Coglan
http://jcoglan.com
|
|
0
|
|
|
|
Reply
|
jcoglan (199)
|
8/6/2009 12:43:08 PM
|
|
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.
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
|
|
0
|
|
|
|
Reply
|
james8284 (4404)
|
8/6/2009 12:46:38 PM
|
|
[Note: parts of this message were removed to make it a legal post.]
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 Coglan
http://jcoglan.com
|
|
0
|
|
|
|
Reply
|
jcoglan (199)
|
8/6/2009 1:12:50 PM
|
|
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.
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
|
|
0
|
|
|
|
Reply
|
james8284 (4404)
|
8/6/2009 1:16:08 PM
|
|
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/.
|
|
0
|
|
|
|
Reply
|
b.candler (2627)
|
8/6/2009 1:49:14 PM
|
|
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
|
|
0
|
|
|
|
Reply
|
vjoel (2600)
|
8/6/2009 4:32:12 PM
|
|
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.
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
|
|
0
|
|
|
|
Reply
|
james8284 (4404)
|
8/6/2009 6:53:22 PM
|
|
|
10 Replies
39 Views
(page loaded in 0.146 seconds)
Similiar Articles: KERNEL - Thermal, fan, processor and other modules built-in - comp ...Welcome to the bootstrapping problems of booting operating systems ... kernel fails to find ext4 module on boot - openSUSE Forums... Smeegol on it, which is built on 11 ... Finding High kernel CPU usage reason - comp.unix.solaris ...... thing on the other direction (retrieve the stats from a specific module). ... depending on the workload. eg, NFS before Solaris 9 runs in the kernel SYS class and systems ... Annoying kernel memory leak in U6? - comp.unix.solaris... 0 0 0 module_data ... Phone: +46 13 28 2786 Computer Systems ... of memory taken by the kernel, but it's not necessarily a memory leak. Kernel ... DPT RAID controller - how to detect a disk failure from a cron job ...We have a machine with a RAID controller that uses the following solaris 8 kernel module ... / The Institute of Biotechnology at Systems Analyst, Techno-Amish & / the ... mount xfs with 64kb blocksize - comp.os.linux.miscDo you have the necessary kernel support for XFS file systems, either built in, or as a loadable module? Have you installed the necessary user level software ... What is the minimum hardware requirement for installing and ...... be dropping off support of sun4m and Ultra 1 and the very earliest Ultra 2 systems. ... host" OS; this would require to port the Linux or the FreeBSD VMware kernel module to ... Adding a second CPU to a DS20E - comp.os.vmsHowever I have added cpu's to AlphaServer 1200 systems and all there is ... -- VAXman- A Bored Certified VMS Kernel Mode Hacker ... precisely, the box currently has a 667MHz module ... Booting x86 Solaris to 32 bits? - comp.unix.solarisDisplayed during the Grub boot: kernel /platform/i86pc/multiboot module ... Booting Solaris Systems to Either the 64-Bit Kernel or the 32-Bit ... This ... What went wrong with the leap second - comp.protocols.time.ntp ...... sput ntpd[1387]: time reset -0.244206 s Jan 1 01:42:33 sput ntpd[1387]: kernel ... DCF77 or GPS receiver, how the driver module ... back during the leap second as some systems ... insufficient physical memory while oracle installation - comp.unix ...... Checking kernel parameters Checking for BIT_SIZE=32 ... The systems I've installed Oracle on had a good deal ... comp.unix ... how to check installed RAM module and free ... Module: Kernel (Ruby 1.9.3)Registers filename to be loaded (using Kernel::require) the first time that module (which may be a String ... The standard shell means always "/bin/sh" on Unix-like systems, ENV ... Class: Module (Ruby 1.9.3)Conversely, module methods may be called without creating an ... Registers filename to be loaded (using Kernel::require) the first time that module (which may be a ... 7/23/2012 1:27:34 PM
|