Рассмотрим метод
m
1 to: 10 do: [:i | self doSomethingWith: i]
Вот байтовые коды, которые генерирует Pharo
pushConstant: 1 ; i := 1
popIntoTemp: 0 ;
@2: pushTemp: 0 ; i <= 10 ?
pushConstant: 10 ;
send #'<=' ;
jumpFalse: @1 ; if false, go to end
self ; self doSomethingWith: i
pushTemp: 0 ;
send #doSomethingWith: ;
pop ;
pushTemp: 0 ; i := i + 1
pushConstant: 1 ;
send #'+' ;
popIntoTemp: 0 ;
jumpTo: @2 ; loop
@1: returnSelf
Как видите, сообщение #to:do
никогда не отправляется, тогда как #'<='
и #+
- (хотя их нет в исходном коде!). Зачем? Из-за того, что Берт сказал в своем ответе: эти сообщения оптимизированы компилятором Smalltalk. В случае Pharo оптимизация происходит в #to:do:
. На других диалектах #to:do:
реализован в терминах #whileTrue:
, который оптимизируется.
Как только вы поймете, как это работает под капотом , вернитесь к этому, как если бы #to:do:
было обычным сообщением с получателем 1
и аргументами 10
и блоком [:i | self doSomethingWith: i]
. Оптимизация не должна заслонять семантику, которой должен следовать ваш разум.