Почему эта переменная класса / экземпляра не инициализируется? - PullRequest
2 голосов
/ 01 мая 2019

Я пытаюсь использовать gnu-smalltalk.В следующем коде простого класса с переменной я обнаружил, что он не инициализируется с указанным значением:

Object subclass: Myclass[
    |mainval|
    mainval := 555.
    getmainval [^mainval]
]

gc := Myclass new.
gc getmainval printNl.

Объект создается без каких-либо ошибок.Но вывод:

nil

, хотя я ожидал, что он будет 555.

Если я добавлю метод, чтобы присвоить ему значение и вызвать его после создания экземпляракласс, все работает.

Где проблема и как ее можно исправить?Спасибо.

1 Ответ

3 голосов
/ 01 мая 2019

Я думаю, что вы были близки, но вы пробовали ярлык, который не работает из-за того, что вы ожидаете, что значение переменной переменной экземпляра в определении класса (вне метода и локальной валидности) вернет значение.В действительности вы хотите использовать переменную экземпляра в методе, например, init для выражения внутреннего состояния объекта.

Как я уже отмечал в некоторых предыдущих ответах, я не эксперт GNU Smalltalk.Я использую для программирования ветку Smalltalk / X-jv.

Я позволил себе переписать ваш код в более GNU Smalltalk-подобный код:

Object subclass: MyClass [
    | mainVal |
    <comment:
        'testing main value'>
    MyClass class >> new [
        <category: 'instance creation'>
        | myClass |
        myClass := super new.
        myClass init.
        ^ myClass
    ]
    init [
        <category: 'initialization'>
        mainVal := 555.
    ]
    mainVal [
        ^ mainVal
    ]
]

Объяснение:

Я определяю mainVal переменную экземпляра.Затем я переопределяю метод класса new, который не необходим, но для иллюстрации я делаю это.(Сообщение new унаследовано от Object класса)

Что я делаю в методе класса new.Я отправляю сообщение new на superclass, которое создает экземпляр anObject, затем инициализирует myClass с помощью init и затем повторяет его.

После этого вы можете увидеть init класс, который инициализирует переменную вашего экземпляра с вашим желаемым значением 555.

Затем у вас есть геттер (в Smalltalk обычно он есть без префикса get , но это«только» вопрос стиля) mainVal.

Затем ваш код для вызова объекта и получения значения.

gc := MyClass new.
gc mainVal

Минимальный пример без new переопределение сообщения:

Object subclass: MyClass [
    | mainVal |
    <comment:
        'testing main value'>
    init [
        <category: 'initialization'>
        mainVal := 555.
    ]
    mainVal [
        ^ mainVal
    ]
]

То, что вы не должны забывать, что в Smalltalk обычно нет вызова по умолчанию конструктора, поэтому вы должны отправить сообщение init вручную (другой вариант - переопределить new сообщение, как я делал выше).

Тогда его использование будет выглядеть так:

gc := MyClass new.
a MyClass
st> gc init
a MyClass
st> gc mainVal
555
...