внутренние классы в Smalltalk - PullRequest
       4

внутренние классы в Smalltalk

1 голос
/ 20 сентября 2011

Интересно, почему smalltalk не использует внутренний класс в стиле java.Этот механизм позволяет эффективно определять новый экземпляр нового класса на лету там, где он вам нужен, когда вам это нужно.Это удобно, когда вам нужен объект, соответствующий какому-то конкретному протоколу, но вы не хотите создавать для него нормальный класс, поскольку его временный и локальный характер очень специфичен для реализации.Насколько я знаю, это можно сделать легко, поскольку синтаксис для создания подклассов является стандартной отправкой сообщений.И вы можете передать себя этому, чтобы оно имело понятие «внешнего» объекта.Единственная проблема - анонимность - класс не должен присутствовать в обозревателе объектов и должен собираться мусором, когда его экземпляры не закрываются.Вопрос: кто-нибудь думал об этом?

Ответы [ 6 ]

3 голосов
/ 21 сентября 2011

Создание анонимного класса (классов) в smalltalk - это очень просто.Более того, любой объект, для которого 3 переменные экземпляра имеют правильные значения: его суперкласс, словарь методов и формат экземпляра, может служить классом (иметь экземпляры).Итак, я не вижу, в чем здесь проблема.

Если вы говорите о поддержке инструментов (инструментов), таких как просмотр или навигация по коду, содержащемуся в таких классах, это другая история.Потому что по умолчанию все классы в системе являются общедоступными, а системный словарь является их плоским пространством имен (да, в некоторых реализациях есть пространства имен).Эта простая модель работает довольно хорошо в большинстве случаев.

3 голосов
/ 21 сентября 2011

Если вы думаете об использовании внутренних классов для тестов, то вы также можете взглянуть на класс ClassFactoryForTestCase

2 голосов
/ 23 сентября 2011

Здесь действительно два ответа:

1 - Да, нетрудно создать анонимные классы , которые автоматически собирают мусор.В Squeak их называют «одноклассниками», потому что типичный вариант использования - для добавления методов к одному объекту.Системы, которые используют это, например, Etoys и Tweak (хотя в Etoys классы фактически помещаются в SystemDict по историческим причинам).Вот некоторый Squeak-код, который я недавно использовал для него:

newClass := ClassBuilder new
    newSubclassOf: baseClass
    type: baseClass typeOfClass
    instanceVariables: instVars
    from: nil.
baseClass removeSubclass: newClass.
^newClass

Как правило, вы бы добавили для этого удобный метод.Затем вы можете добавить методы и создать экземпляр, и когда все экземпляры исчезнут, класс тоже будет gc'ed.

Обратите внимание, что в Java объект класса не gc'ed - внутреннийКласс компилируется точно так же, как обычный класс, он скрыт только компилятором.Напротив, в Smalltalk все это происходит во время выполнения, даже при компиляции новых методов для этого класса, что делает его сравнительно неэффективным.Существует гораздо лучший способ создания анонимного предварительно скомпилированного поведения, который заставляет нас ответить 2:

2 - Хотя это не сложно, его редко используют в Smalltalk. Причина этого заключается в том, чточто Smalltalk имеет гораздо более удобный механизм.Внутренние классы в Java чаще всего используются для создания метода на лету, реализующего определенный интерфейс.Внутреннее объявление класса необходимо только для того, чтобы компилятор был доволен безопасностью типов. В Smalltalk вы просто используете закрытие блоков. Это позволяет вам создавать поведение на лету, которое вы можете обойти.Системные библиотеки структурированы таким образом, чтобы использовать закрытие блоков.

Лично я никогда не чувствовал, что внутренние классы были чем-то необходимым для Smalltalk.

2 голосов
/ 20 сентября 2011

Я почти уверен, что это можно сделать, взломав протоколы Class и Metaclass. И вопрос довольно часто возникает от людей, которые имеют больше опыта в Java, и Smalltalk становится интересным для них. Поскольку внутренние классы не были реализованы, несмотря на это, я считаю это признаком того, что большинство пользователей Smalltalk не находят их пригодными для использования. Это может быть связано с тем, что в Smalltalk есть блоки, которые более простым способом решают многие, если не все проблемы, которые привели к введению внутренних классов в Java.

1 голос
/ 20 сентября 2011

(a) Вы можете отправлять сообщения для создания нового класса изнутри метода другого класса

(b) Я сомневаюсь, что есть какая-то польза от сокрытия полученного класса от системы самоанализа

(c) Причина, по которой вы используете внутренние классы в Java, заключается в том, что нет функций первого класса. Если вам нужно передать фрагмент кода в Smalltalk, вы просто передаете блок. Вам не нужно оборачивать его каким-либо другим типом объекта, чтобы сделать это.

0 голосов
/ 20 сентября 2011

Проблема (по крайней мере в Squeak) возникает из-за отсутствия четкого разделения проблем.Создать свой собственный подкласс и поместить его в приватный SystemDictionary:

myEnv := SystemDictionary new.
myClass := ClassBuilder new
    name: 'MyClass'
    inEnvironment: myEnv
    subclassOf: Object
    type: #normal
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'MyCategory'
    unsafe: false.  

тривиально. Но даже если вы поместите этот класс в свой собственный SystemDictionary, категория «Моя категория» добавлена ​​в системную навигацию.(проверяется открытием Browser) и, что еще хуже, организаторы классов не создаются, поэтому при переходе к MyClass вы получаете нулевой указатель.

Теоретически это, безусловно, не невозможно.Прямо сейчас инструмент ориентирован на единый пул глобально видимых определений классов.

...