Что действительно блокируется в среднем Ruby? Это выглядит похожим с Smalltalk, но Вы не можете отправить сообщения в него.
Например, в smalltalk:
[:x | x + 3] value: 3
возвраты 6. Но в рубине:
{|x| x + 3}.call 3
вызовет SyntaxError.
Ну, можно передать сообщения лямбде в рубине, хотя:
irb(main):025:0> ->(x){x+3}.call 3
=> 6
Таким образом в Ruby, блок не является блоком, но лямбда является блоком? Действительно ли это верно? Я имею в виду, там какие-либо различия между рубиновой лямбдой и smalltalk блоком? Если это верно, то, что такое рубиновый блок?
Обновление:
Из комментария и ответа ниже, вместе с некоторым поиском с помощью Google, я предполагаю, что у меня есть больше понимания блока Ruby. В Ruby обычно часть кода оценивает значение, и каждое значение является объектом. Но, блок не оценивает значение. Таким образом, это не объект. Вместо этого это может действовать как часть объекта. Например, в {|x | x + 3} может действовать как часть объекта proc {|x | x + 3}.
Но это действительно смущало меня. В smalltalk почти каждое выражение может быть разделено на объекты (связывающий с переменными, исключения). Это кажется в Ruby, существует больше исключений.
Первое и самое важное, чем блок Ruby не является: объект. Это синтаксическая конструкция, которая также, очевидно, имеет эквивалентную реализацию, но не является объектом и, следовательно, не может получать сообщения. Что делает ваш пример
{|x| x + 3}.call 3
неграмотным. Лямбды, процедуры - это объекты, которые заключают блок и имеют метод call
, который выполняет блок.
Таким образом, блок - это просто кусок кода, который может быть передан методу вне списка аргументов - ни больше, ни меньше. Если вы передадите его конструктору Proc.new, например, он обернет его и предоставит вам объект, который вы можете обработать:
Proc.new {|x| x + 3}.call 3
Точность:
Я бы даже сказал, что в smalltalk даже привязка создается с помощью объекта. Подумайте о MethodContext. На самом деле вы сохраняете объект в MethodContext. Итак,
a := Object new
Можно переписать в:
thisContext at: 1 put: Object new.
Но, очевидно, вы не будете писать так, потому что вам нужно знать, что это переменная temps.