Почему методы возвращают "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 по умолчанию по нескольким причинам.

  1. Smalltalk методы должны возвращать что-то
  2. self-самый простой объект для возврата
  3. self-самый быстрый объект для возврата
  4. Возвращающ собственную личность позволяет нескольким картин дизайна работать естественно

позвольте мне объяснить #4 немного больше. Один общий шаблон для инициализации объекта-определить новая метод для класса, который выглядит как это:

new
   ^super new initialize

этот шаблон зависит от инициализации возвращающегося self. Это не нормально, однако, чтобы добавить ^self в конце инициализации метод. Это не нужно, потому что метод все равно вернет себя.

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


исходя из Java, вы знаете о NullPointExceptions при работе с неопределенными возвращаемыми значениями. Кроме того, ваш код должен выполнять условную проверку null здесь и там.

Я был рад найти возвращаемое значение для каждого вызова метода или отправки сообщения в Smalltalk. Если вы решите, чтобы каждый метод возвращал какое-то значение, вы спросите, каким может быть значение по умолчанию. Сам объект (self) является очень естественным способом использования в качестве значения по умолчанию. Или спросить другой способ: что может быть лучшим возвращаемым значением?