Ruby-Array Method Confusion

we can call the Array method at a higher level like this

Array(something) 

what makes sense to me is a method call without an explicit receiver, and itself, which is the main one in this case, is inserted at the beginning of the method call. But isn't that equivalent:

 Kernel.Array(something) 

it doesn't make sense to me. Since in the first case, the main object of the object has the Object class into which the kernel module has been added, that is, the Array method. But in the second case, we call the Array method on the kernel module object itself, and not on the main object, aren't they the same?

Sorry for my bad english.

+7
ruby language-design
source share
4 answers

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

A module function is a method that is both a class method in a module and a private instance method. When you call Array () at the top level, you call it as a private instance method of the main object. When you call it through Kernel.Array (), you call it as a class method on the kernel. This is the same method.

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

+4
source share

What confuses you is the difference between class and instance methods.

Class methods do not have an explicit receiver, and thus do not have self to access other fields. They just ... are.

Typically, instance methods are used to query or manipulate attributes of a given object, while class methods are helper or factory methods that provide some functions related to or especially useful for a particular class, but it does not depend on real live instances (objects ) of this class.

Not sure about Ruby, but Java has (for example) an entire Math class that only contains instances that look like sin() , max() , exp() , etc.: "Math" does not exist, object, this just methods that embody mathematical algorithms. Not a good example, because in Ruby, these methods are probably embedded directly in number classes as instance methods.

The case you mentioned is a bit confusing because the Array () and Kernel Array() methods are actually different methods that do similar things. Both are class methods.

Array() takes a list of arguments and creates and returns an array containing them.

Kernel.Array() takes a single argument of type "array-able", such as a sequence, and takes the values ​​returned by this argument and builds an array from them.


UPDATE

The shift was perhaps justified; I apologize for the fact that you are engaged in a subject outside my competence. I think I will delete this answer soon.

@ Chuck: I sincerely hope that the official documentation in the language / library will offer some meaningful clues as to how this works. This is what I consulted when answering this question.

rdoc for Kernel.Array() :

Returns arg as an array. It tries to call arg.to_ary first, then arg.to_a. If both fail, creates one array of elements containing arg (if arg is not equal to zero).

for Array.() :

Returns a new array filled with these objects.

I don’t know about you, but I think that if the documents change so much, either they speak of separate methods, or the documentation is a train wreck.

@ freeknight:

But everything in the ruby ​​is an object of some kind, even classes and modules. And Kernel.Array is actually a method call for a specific object - a kernel object.

Yes, under the covers it looks like Java too. But the Array() method does nothing with Kernel, no more than Array() does anything with an object of the Array class, so this is really just a semantic pun. This is an instance method because you could disconnect it from the IPSocket class if you were crazy enough and it would work the same anyway.

0
source share

Class The object of the mixed module The kernel, but the kernel is an instance of the object. Thus, kernel module methods are instance methods.

0
source share

This is the same:

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

Maybe there is an alias?

-2
source share

All Articles