tags:

views:

144

answers:

4

we can call the Array method in the top level like this

Array(something)

that makes sense to me, it's a method call without explicit receiver, and self, which is main in this case, is inserted at the front of the method call. But isn't it that this is equivalent to :

Kernel.Array(something)

this doesn't make sense to me. Since in the first case, the object main is of class Object, which got Kernel module mixed in, thus have the Array method. But in the second case, we are calling the Array method on the Kernel module object itself, rather than main object, didn't they are NOT the same thing?

sorry for my bad english.

A: 
Carl Smotricz
The receiver of class methods is the Class singleton that represents the class.
Martinho Fernandes
In general, class method is indeed some kind of "factory" or "helper" and that's especially true in Java. But everything in ruby is an object of some kind, even classes and modules. And Kernel.Array is actually a method call on an specific object - the Kernel object.
freenight
anyway, thanks.
freenight
In other words, there is a self within class methods. Also, I see no evidence that the two `Array()`s are different methods, and neither appears to be a class method.
Chuck
Chuck, Array is a module_function (as stated in my answer) and so is a class method on Kernel as well as a private instance method on Kernel. (for proof check out the definition of rb_define_global_function in class.c)
banister
@Martinho, that's incorrect. The receiver of a class method is the CLASS. However the class method must be defined on the Class's singleton.
banister
Some more clarification in my answer. The discussion in the comments is getting so interesting it might be a shame to delete answer; any (non-obscene) suggestions regarding what I should do?
Carl Smotricz
A: 

They are the same thing:

a = Kernel.Array('aa')
=> ["aa"]
a.class
=> Array
a = Array('aaa')
=> ["aaa"]
a.class
=> Array

Maybe there is an alias?

VP
A: 

class Object mixed-in module Kernel, but Kernel is an instance of Object. So Kernel "module" methods - is it's instance methods.

aaz
this cannot be right because the Array method is a private instance method and so would not be accessible directly on Kernel. Try it on any other object => Object.new.Array #=> private method error
banister
yes, you are right - in Object its private instance method (but in Kernel its public).I don't see any variant exceptclass << Kernel public :Arrayend
aaz
to your post "When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. They are the same method."In documentation method Array is a Public Instance method of Kernel, and problem is how it becomes Kernel public class method...
aaz
+4  A: 

Kernel.Array is what is known as a module function. Other examples of module functions include Math.sin, and Math.hypot and so on.

A module function is a method that is both a class method on the module and also a private instance method. When you invoke Array() at the top-level you are invoking it as a private instance method of the main object. When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. They are the same method.

To learn more, read up on the module_function method in rubydocs: http://www.ruby-doc.org/core/classes/Module.html#M001642

banister
+1 for what looks to be a very helpful explanation. Can you please address/explain the difference in documentation mentioned in my answer?
Carl Smotricz
@Carl, what documentation are you reading? but it's true that many ruby docs leave a lot to be desired
banister
<http://ruby-doc.org/core/classes/Array.html> and <http://ruby-doc.org/core/classes/Kernel.html>. Horse's mouth, as it were. I think rdoc could use some mechanism for automating these intentional identical duplicates.
Carl Smotricz