Метод Ruby, Proc и блок путаницы - PullRequest
21 голосов
/ 07 августа 2009

У меня есть пара вопросов о методах, процедурах и блоках Ruby, которые кажутся мне довольно странными. Они не столько о синтаксисе или функции, сколько о логике принятых решений.

Вопрос 1:

Почему блоки могут быть переданы в методы (например, каждый), но они не могут быть присвоены переменной?

Я знаю, что вы можете передавать их в процедурах, т. Е. p = Proc.new {...} (доступ с помощью &p), но нет смысла заставлять программиста проходить через эти средства.

Вопрос 2:

Почему существует различие между методами и процедурами?

Например, я могу выполнить задачу определения функции и вызова этой функции следующими двумя способами:

def square(x)
    x**2
end

square(3)
=> 9

или

square = lambda {|x| x**2}
square.call(3)
=> 9

Почему дифференциация? Например, в Python как определение функции стандартным способом, так и square = lambda x: x**2 выполняют ту же задачу создания функции и присваивания ей square.

Ответы [ 3 ]

21 голосов
/ 07 августа 2009

Вопрос 1: блоки не являются объектами, они являются синтаксическими структурами; Вот почему они не могут быть присвоены переменной. Это привилегия, зарезервированная для объектов.

Вопрос 2: Методы не являются объектами, поэтому они не могут получать сообщения. И наоборот, procs и lambdas являются объектами, поэтому они не могут быть вызваны как методы, но должны получить сообщение, в котором говорится, что они должны возвращать значение на основе параметров, переданных с сообщением.

Procs и Lambdas являются объектами, поэтому они могут получать сообщение call и назначаться именам. Подводя итог, можно сказать, что это объект, который заставляет проки и лямбды вести себя странным образом. Методы и блоки не являются объектами и не имеют такого поведения.

5 голосов
/ 07 августа 2009

В некоторой степени, по крайней мере, методы являются объектами:

class ABC
  def some_method
  end
end
ABC.instance_method(:some_method) #=> #<UnboundMethod: ABC#some_method>

Кроме того, есть встроенный класс: метод, как описано здесь .

См. Также это: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

Обезьяны <bseg>, скорее всего, это подтверждает все, что является объектом. В данном конкретном случае, кажется, что нужно еще немного покопаться, чтобы увидеть.

(Я действительно должен приложить усилия, чтобы лучше понять это: я начинаю думать, что это фундаментально для более глубокого понимания.)

4 голосов
/ 07 августа 2009

Методы - это методы, то есть действия, которые объект может выполнять в ответ на сообщения. Они не являются функциями.

Блоки - это замыкания - это функции, которые закрываются во всей области видимости. Концептуально они не «принадлежат» данному объекту.

В некоторых языках методы - это просто функции, которые являются членами объекта, но Ruby не рассматривает их таким образом. Отделение метода от объекта-владельца больше похоже на хирургическое вмешательство, чем простое назначение. Ruby берет свою объектно-ориентированную модель от Smalltalk , дедушки современного ОО.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...