问题
I am trying to use gnu-smalltalk. In following code of a simple class with a variable, I find it is not getting initialized to the given value:
Object subclass: Myclass[
|mainval|
mainval := 555.
getmainval [^mainval]
]
gc := Myclass new.
gc getmainval printNl.
The object gets created without any error. But, the output is:
nil
while I had expected it to be 555.
If I add a method to assign a value to it and call it after creating an instance of the class, it works.
Where is the problem and how can it be corrected? Thanks.
回答1:
I think you were close but you tried a shortcut which does not work due to the fact that you are expecting that setting value to an instance variable within class definition (outside a method and local validity) will return value. In reality you want to use an instance variable within a method e.g. init
to express the inner state of an object.
As I have noted in some previous answers, I'm not a GNU Smalltalk expert. I'm using Smalltalk/X-jv branch for programming.
I have taken the liberty to rewrite your code to more GNU Smalltalk like code:
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
]
]
The explanation:
I'm defining the mainVal
instance variable. Then I'm redefining a class method new
which is not needed but for illustration purposes I'm doing so. (The new
message is inherited from Object
class)
What I'm doing in the class method new
. I'm sending the new
message to the superclass
which creates instance of anObject
, then initializing the myClass
with init
and then returing it.
Afterwards you can see the init
class which initialize your instance variable to your wished value of 555
.
Then you have a getter (in Smalltalk it is usual to have it without the get prefix, but that is "only" matter of style) the mainVal
.
Then your code to call the object and get value.
gc := MyClass new.
gc mainVal
The minimal example without the new
message redefinition:
Object subclass: MyClass [
| mainVal |
<comment:
'testing main value'>
init [
<category: 'initialization'>
mainVal := 555.
]
mainVal [
^ mainVal
]
]
What you must not forget that in Smalltalk there is usually no default calling of a constructor so you have to send the init
message manually (the other option is to redefine new
message like I did above).
Then using it would look like this:
gc := MyClass new.
a MyClass
st> gc init
a MyClass
st> gc mainVal
555
来源:https://stackoverflow.com/questions/55931862/why-this-class-instance-variable-is-not-being-intialized