Ruby - метод массива путаницы - PullRequest
7 голосов
/ 06 декабря 2009

мы можем вызвать метод Array на верхнем уровне, как это

Array(something)

это имеет смысл для меня, это вызов метода без явного получателя, и self, которое в этом случае является основным, вставляется в начало вызова метода. Но разве это не эквивалентно:

Kernel.Array(something)

это не имеет смысла для меня. Так как в первом случае объект main принадлежит классу Object, в который встроен модуль Kernel, то есть имеет метод Array. Но во втором случае мы вызываем метод Array на самом объекте модуля Kernel, а не на главном объекте, разве это НЕ одно и то же?

извините за мой плохой английский.

Ответы [ 4 ]

4 голосов
/ 06 декабря 2009

Kernel.Array - это то, что называется функцией модуля. Другие примеры функций модуля включают Math.sin, Math.hypot и т. Д.

Функция модуля - это метод, который является одновременно методом класса в модуле, а также методом частного экземпляра. Когда вы вызываете Array () на верхнем уровне, вы вызываете его как частный метод экземпляра основного объекта. Когда вы вызываете его через Kernel.Array (), вы вызываете его как метод класса в Kernel. Это один и тот же метод.

Чтобы узнать больше, прочтите метод module_function в rubydocs: http://www.ruby -doc.org / core / classes / Module.html # M001642

0 голосов
/ 06 декабря 2009

Это одно и то же:

a = Kernel.Array ('aa')
=> ["аа"]
a.class
=> Массив
a = Array ('aaa')
=> ["ааа"]
класс
=> Массив

Может быть, есть псевдоним?

0 голосов
/ 06 декабря 2009

класс Объектный смешанный модуль Ядро, но Ядро является экземпляром Объекта. Итак, методы "модуля" ядра - это методы экземпляра.

0 голосов
/ 06 декабря 2009

Что вас смущает, так это разница между методами класса и экземпляра.

Методы класса не имеют явного получателя, поэтому self не имеет доступа к другим полям с помощью. Они просто ... есть.

Обычно методы экземпляра используются для запроса или манипулирования атрибутами данного объекта, тогда как методы класса являются «вспомогательными» или «фабричными» методами, которые предоставляют некоторую функциональность, связанную или особенно полезную для определенного типа класса, но не зависит от реальных живых экземпляров (объектов) этого класса.

Не уверен насчет Ruby, но в Java есть (например) целый класс, Math, который не содержит ничего, кроме методов экземпляра, таких как sin(), max(), exp() и т. Д. Нет "Math" объект, это просто методы, которые воплощают математические алгоритмы. Не лучший пример, потому что в Ruby эти методы, вероятно, встроены прямо в числовые классы как методы экземпляра.

Случай, который вы упоминаете, немного сбивает с толку, потому что метод Array () и метод Kernel Array() на самом деле являются разными методами, которые делают подобные вещи. Оба являются методами класса.

Array() принимает список аргументов, создает и возвращает массив, содержащий их.

Kernel.Array() принимает один аргумент типа "массива", такого как последовательность, и принимает значения, возвращаемые этим аргументом, и строит массив из них.


UPDATE

Возможно, голосование было оправданным; Я прошу прощения за то, что взял предмет за пределами моей области знаний. Я думаю, что скоро буду удалять этот ответ.

@ Чак: Я искренне надеюсь, что официальная документация языка / библиотеки предложит несколько значимых подсказок о том, как это работает. Это то, с чем я советовался, отвечая на этот вопрос.

RDOC для Kernel.Array():

Возвращает arg как массив. Сначала пытается вызвать arg.to_ary, затем arg.to_a. Если оба не удаются, создается один массив элементов, содержащий arg (если arg не равен nil).

для Array.():

Возвращает новый массив, заполненный данными объектами.

Я не знаю о вас, но я думаю, что если документы сильно отличаются, то либо они говорят об отдельных методах, либо документация - крушение поезда.

@ freeknight:

Но все в ruby ​​- это какой-то объект, даже классы и модули. А Kernel.Array на самом деле является вызовом метода для конкретного объекта - объекта Kernel.

Да, под обложками это похоже на Java. Но метод Array() ничего не делает с ядром, более чем Array() ничего не делает с объектом класса Array, так что на самом деле это всего лишь семантический спор. Это метод экземпляра, потому что вы можете повесить его на класс IPSocket, если вы достаточно сумасшедший, и он все равно будет работать так же.

...