Мне интересно, почему в GNU Smalltalk не работает следующее:
Object subclass: Foo [ ] new printNl
Я ожидал распечатку чего-то вроде "Foo", но вместо этого gst печатает "nil". Не кажется ли это немного странным?
Object subclass: Foo [] не является «обычным» синтаксисом Smalltalk, это недавнее дополнение, разработанное для практического кодирования в файлах. До этого не было специального синтаксиса для объявления класса, так как они были бы созданы командой в образе. Интерпретация этого кода, как вы ожидали, будет неправильной по нескольким причинам:
Object subclass: Foo []
Во-первых, если subclass: было реальным сообщением, отправленным Object, то Foo должно разрешить что-то, что невозможно, так как оно только что объявлено. Однако за кулисами компилятор делает нечто подобное Object subclass: #Foo, где #Foo является символом для имени нового класса, который будет создан. Можно было бы написать весь код подобным образом, за исключением того, что вы не могли бы использовать имена классов напрямую (так как они еще не существуют, когда код читается). Вы должны были бы сделать (Smalltalk at: #Foo) new printNl повсюду. Таким образом, вся форма Object subclass: Foo [ ] представляет собой чистый синтаксис, который просто объявляет, что этот класс должен быть создан, и не означает, что в этот момент сообщение должно быть отправлено на Object и т. Д.
subclass:
Object
Foo
Object subclass: #Foo
#Foo
(Smalltalk at: #Foo) new printNl
Object subclass: Foo [ ]
Во-вторых, вы не хотите создавать классы в середине алгоритма и немедленно отправлять им сообщения, что было бы довольно уродливо для практики разработки. Обратите внимание, что классы должны быть зарегистрированы в системе, чтобы браузер мог отображать их, чтобы компилятор мог автоматически перекомпилировать зависимости, чтобы контроль версий мог их записывать и т. Д. Кроме того, что, если ваш код случайно выполнит это дважды? Должны ли вы получить второй класс Foo и забыть о предыдущем? Поэтому, как правило, только компилятор, браузер и другие инструменты метапрограммирования создают новые классы и только по запросу программиста.
Это интерпретируется как два утверждения. Первый
Подкласс объекта: Foo []
а второй
новый принтNl
где новая переменная не определена, поэтому она равна nil.