Блок в Ruby по сравнению с Smalltalk

Что действительно блокируется в среднем 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, существует больше исключений.

11
задан niton 21 April 2015 в 12:30
поделиться

2 ответа

Первое и самое важное, чем блок Ruby не является: объект. Это синтаксическая конструкция, которая также, очевидно, имеет эквивалентную реализацию, но не является объектом и, следовательно, не может получать сообщения. Что делает ваш пример

{|x| x + 3}.call 3

неграмотным. Лямбды, процедуры - это объекты, которые заключают блок и имеют метод call , который выполняет блок.

Таким образом, блок - это просто кусок кода, который может быть передан методу вне списка аргументов - ни больше, ни меньше. Если вы передадите его конструктору Proc.new, например, он обернет его и предоставит вам объект, который вы можете обработать:

Proc.new {|x| x + 3}.call 3
14
ответ дан 3 December 2019 в 07:36
поделиться

Точность:

Я бы даже сказал, что в smalltalk даже привязка создается с помощью объекта. Подумайте о MethodContext. На самом деле вы сохраняете объект в MethodContext. Итак,

a := Object new

Можно переписать в:

thisContext at: 1 put: Object new.

Но, очевидно, вы не будете писать так, потому что вам нужно знать, что это переменная temps.

1
ответ дан 3 December 2019 в 07:36
поделиться