简体   繁体   English

Ruby - 数组方法混淆

[英]Ruby - Array method confusion

we can call the Array method in the top level like this 我们可以像这样在顶层调用Array方法

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. 这对我来说很有意义,它是一个没有显式接收器的方法调用,而self,在这种情况下是主要的,插入在方法调用的前面。 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. 由于在第一种情况下,对象main是Object类,它将Kernel模块混入,因此具有Array方法。 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? 但在第二种情况下,我们在内核模块对象本身上调用Array方法,而不是主对象,它们不是不一样吗?

sorry for my bad english. 对不起,我的英语不好。

Kernel.Array is what is known as a module function. Kernel.Array就是所谓的模块函数。 Other examples of module functions include Math.sin, and Math.hypot and so on. 模块函数的其他示例包括Math.sin和Math.hypot等。

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. 在顶层调用Array()时,您将其作为主对象的私有实例方法调用。 When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. 当您通过Kernel.Array()调用它时,您将其作为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 要了解更多信息,请阅读rubydocs中的module_function方法: http ://www.ruby-doc.org/core/classes/Module.html#M001642

What's confusing you is the difference between class and instance methods. 令你困惑的是类和实例方法之间的区别。

Class methods don't have an explicit receiver, and thus no self to access other fields with. 类方法没有明确的接收器,因此没有self访问其他字段。 They just... are. 他们只是......。

Generally instance methods are used to query or manipulate the attributes of a given object, whereas the class methods are "helper" or "factory" methods that provide some functionality associated with or especially useful for a certain kind of class, but not dependent on actual live instances (objects) of that class. 通常,实例方法用于查询或操纵给定对象的属性,而类方法是“帮助”或“工厂”方法,它们提供与某种类相关联或特别有用的某些功能,但不依赖于实际该类的实例(对象)。

Not sure about Ruby, but Java has (for example) a whole class, Math that contains nothing but instance methods like sin() , max() , exp() and so forth: There is no "Math" object, these are just methods that embody mathematical algorithms. 不确定Ruby,但Java有(例如)一个完整的类, Math只包含sin()max()exp()等实例方法:没有“Math”对象,这些只是体现数学算法的方法。 Not the best example, because in Ruby those methods are probably embedded right into the numeric classes as instance methods. 这不是最好的例子,因为在Ruby中,这些方法可能作为实例方法嵌入到数值类中。

The case you mention is a bit confusing because Array 's () method and Kernel 's Array() method are in fact different methods that do similar things. 你提到的情况有点令人困惑,因为Array()方法和KernelArray()方法实际上是做类似事情的不同方法。 Both are class methods. 两者都是类方法。

Array() takes a list of arguments and makes and returns an array containing them. Array()接受一个参数列表,并生成并返回一个包含它们的数组。

Kernel.Array() takes a single argument of an "array-able" type, such as a sequence, and takes the values returned by this argument and builds an array from those. Kernel.Array()接受一个“array-able”类型的单个参数,例如一个序列,并获取该参数返回的值并从中构建一个数组。


UPDATE UPDATE

The downvote was perhaps justified; downvote也许是合理的; I apologize for taking on a subject outside my area of expertise. 我为在我的专业领域之外接受一个主题而道歉。 I think I'll be deleting this answer soon. 我想我很快就会删除这个答案。

@ Chuck: I would sincerely hope that a language/library's official documentation would offer some meaningful clues as to how it works. @Chuck:我真诚地希望语言/图书馆的官方文档能够提供一些有用的线索。 This is what I consulted in answering this question. 这是我在回答这个问题时所咨询的。

The rdoc for Kernel.Array() : Kernel.Array()

Returns arg as an Array. 将arg作为数组返回。 First tries to call arg.to_ary, then arg.to_a. 首先尝试调用arg.to_ary,然后调用arg.to_a。 If both fail, creates a single element array containing arg (unless arg is nil). 如果两者都失败,则创建一个包含arg的单个元素数组(除非arg为nil)。

for Array.() : for Array.()

Returns a new array populated with the given objects. 返回使用给定对象填充的新数组。

I don't know about you, but I think if the docs vary that much then either they're talking about separate methods or the documentation is a train wreck. 我不了解你,但我认为如果文档变化那么多,那么他们要么谈论单独的方法,要么文档是火车​​残骸。

@ freeknight: @ freeknight:

But everything in ruby is an object of some kind, even classes and modules. 但是ruby中的所有东西都是某种对象,甚至是类和模块。 And Kernel.Array is actually a method call on an specific object - the Kernel object. 而Kernel.Array实际上是对特定对象(Kernel对象)的方法调用。

Yeah, under the covers it's similar in Java too. 是的,在Java下它也类似于Java。 But the Array() method isn't doing anything with Kernel, any more than Array() is doing anything with the Array class object, so this is really only a semantic quibble. 但是Array()方法没有对Kernel做任何事情,除了Array()正在使用Array类对象做任何事情,所以这实际上只是一个语义狡辩。 It's an instance method because you could hang it off class IPSocket if you were crazy enough, and it would still work the same way. 这是一个实例方法,因为如果你足够疯狂,你可以把它挂在类IPSocket ,它仍然会以同样的方式工作。

class Object mixed-in module Kernel, but Kernel is an instance of Object. class Object mixed-in module Kernel,但Kernel是Object的一个实例。 So Kernel "module" methods - is it's instance methods. 所以内核“模块”方法 - 是它的实例方法。

They are the same thing: 他们是一样的东西:

a = Kernel.Array('aa') a = Kernel.Array('aa')
=> ["aa"] => [“aa”]
a.class 一类
=> Array =>数组
a = Array('aaa') a =数组('aaa')
=> ["aaa"] => [“aaa”]
a.class 一类
=> Array =>数组

Maybe there is an alias? 也许有别名?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM