Почему методы возвращают "self" по умолчанию в Smalltalk?
фон
в Smalltalk, если вы не возвращаете ничего неявно, то передача сообщения оценивается получателю (или" себе " в контексте сообщения).
например, если этот метод:
MyClass >> myMethod
Transcript show: 'hello'; cr.
оценка (doint "print-it") это:
| myInstance |
myInstance := MyClass new.
myInstance myMethod.
если выполняется до последнего вызова, то результатом будет сам экземпляр.
вопросы
- почему это было разработано это способ?
- какая идея?
- какова была философская подоплека?
- каковы практические выгоды от этого? Это чтобы облегчить цепочку методов?
5 ответов
одна очень простая причина еще не была указана: в виртуальной машине возвращение self проще и эффективнее, чем возврат любого другого объекта.
байтовые коды Smalltalk реализуют машину стека. Это означает, что аргументы передаются, помещая их в стек, а не помещая их в регистры. В дополнение к аргументам, перечисленным в сигнатуре метода, всегда передается скрытый аргумент, который является получателем сообщения. Так что даже для унарных методов (те без аргументов) приемник помещается в стек, затем выполняется метод, а значение приемника в стеке-это то, как метод знает "себя". Возвращая "self", если явный оператор return не задан, VM может просто оставить" self " oop в стеке, что сохраняет по крайней мере одну операцию хранилища памяти. Поэтому с точки зрения эффективности и простоты возвращение "я" - это самая элегантная вещь.
Smalltalk-80-х Синяя книга (язык и его реализация) ничего не говорит о почему он возвращает receiver по умолчанию.
тем не менее, есть цитата на странице 27 (раздел "возврат значения") это может помочь вам:
" даже если никакая информация не должна быть передана обратно отправителю, получателю всегда возвращает значение для выражения сообщения. Возвращаемое значение указывает на ответ на сообщение завершен. (...)"
имейте в виду, что в Smalltalk методы активируются с помощью отправки сообщений, поэтому для сообщения существует полная поездка туда и обратно (которая может закончиться исключением MessageNotUnderstood). Концепция отправки сообщений имеет первостепенное значение.
есть некоторые образцы хорошей практики о том, что вернуть в зависимости от намерения сообщения, но это тема другой истории.
Я не создатель smalltalk, но, кажется, это лучшее, что можно сделать.
например, если вы выполните:
var := myInstance myMethod.
тогда возникает вопрос: Чего вы хотите var
стать? Одним из вариантов будет nil
. Но это немного запутанным, потому что вы работаете с определенными объектами и nil
на самом деле является неопределенным. Таким образом, вы можете относиться к нему, как вы назначаете myInstance
to var
и просто вызов myMethod по пути. Также это может быть возможно рассматривается как стенография для
var := myInstance myMethod; yourself.
если вы посмотрите изнутри, то из всех данных, доступных самому объекту, наиболее подходящая вещь, вероятно, также self
. Еще раз,nil
может быть возвращен, но я уже говорил свое мнение об этом раньше.
в Smalltalk нет такой вещи, как пустота метод, который ничего не возвращает, и нет проверял тип. Поэтому метод просто должен что-то вернуть. Это как объект говорит:
Я могу вернуть себя для любого вызова метода по умолчанию, потому что я всегда знайте о себе, и вы можете переопределить это поведение, если хотите мне нужно вернуть кое-что еще.
лично я думаю, что возвращение nil
может быть, тоже хорошо, и С приложения использовать nil
вещи очень часто, но Smalltalk сделан таким образом, и я думаю, что это довольно хорошее решение.
методы возвращают self по умолчанию по нескольким причинам.
- Smalltalk методы должны возвращать что-то
- self-самый простой объект для возврата
- self-самый быстрый объект для возврата
- Возвращающ собственную личность позволяет нескольким картин дизайна работать естественно
позвольте мне объяснить #4 немного больше. Один общий шаблон для инициализации объекта-определить новая метод для класса, который выглядит как это:
new
^super new initialize
этот шаблон зависит от инициализации возвращающегося self. Это не нормально, однако, чтобы добавить ^self в конце инициализации метод. Это не нужно, потому что метод все равно вернет себя.
в конце концов, возвращение self - это просто естественный выбор по умолчанию, учитывая, что вы должны вернуть что-то.
исходя из Java, вы знаете о NullPointExceptions при работе с неопределенными возвращаемыми значениями. Кроме того, ваш код должен выполнять условную проверку null здесь и там.
Я был рад найти возвращаемое значение для каждого вызова метода или отправки сообщения в Smalltalk. Если вы решите, чтобы каждый метод возвращал какое-то значение, вы спросите, каким может быть значение по умолчанию. Сам объект (self) является очень естественным способом использования в качестве значения по умолчанию. Или спросить другой способ: что может быть лучшим возвращаемым значением?