Подтвердить что ты не робот

Метод Ruby, Proc и путаница блоков

У меня есть пара вопросов о методах, процедурах и блоках 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.

4b9b3361

Ответ 1

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

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

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

Ответ 2

В некоторой степени, по крайней мере, методы - это объекты:

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

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

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

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

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

Ответ 3

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

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

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