I'm having trouble initializing class variables in Pharo. I started by creating a class with a single class variable:
Object subclass: #ClassVariableTestBehavior
instanceVariableNames: ''
classVariableNames: 'test'
package: 'DummyPackage'
And then on the class side I created an initialize message and set the variable to nil.
ClassVariableTestBehavior class >>> initialize
test := nil
I saved and then created an instance method:
ClassVariableTestBehavior >>> test
^ test
and went back again and changed the class method to be:
ClassVariableTestBehavior class >>> initialize
test := 34
In the playground I then printed the result of the following:
ClassVariableTestBehavior new test.
Which was nil. Why hasn't the value of the class variable updated to be 34?
The class>>initialize method is used only once, when the code is initially loaded from an external file. It does not get run every time the method is edited. (If you modified a comment would you want the data to get wiped out!?) In fact, the nil value didn't come from your method but was just the initial default value.
A common convention is to add a comment to the initialize method with a line of code that could be executed.
"
ClassVariableTestBehavior initialize.
"
I think you are confused about initialize. Based on your comment you want to create a constant value shared among the instances.
The initialize is usually a method for defining values for instance of an object you are creating. The issue with Smalltalk is that not every Smalltalk implementation runs initialize when creating an instance; so watch out for this one.
If you want to share value among instances you can create a class method like this:
ClassVariableTestBehavior class >> #test
Where:
test
"Class method returning always the same value"
^ 34
When you want to access the value you simply do:
ClassVariableTestBehavior test.
If you want to access it when you have your own instance create it you can do it like this:
| instance |
instance := ClassVariableTestBehavior new.
instance class test. "This accesses the class variable"
Edit - due to excellent comment by Leandro, which I forgot to mention.
You should use capital letter for the class variable! (credit to Leandro)
If you would like to have a value stored in a class variable instead of just constant value in a method as I have shown above. You can do it using class variable.
If you define class variable as Test, then you need to have a getter and setter for it.
You would have:
ClassVariableTestBehavior class >> #test
test
"returns value of class variable"
^ Test
ClassVariableTestBehavior class >> #test:
test: aNumber
"sets the value of class variable"
Test := aNumber
You would access the value the same way as above (just before the edit).
Related
I was looking through this example:
class SQLObject
def self.columns
return #columns if #columns
columns = DBConnection.execute2(<<-SQL).first
SELECT
"#{table_name}".*
FROM
"#{table_name}"
LIMIT
0
SQL
columns.map!(&:to_sym)
#columns = columns
end
def self.table_name
#table_name ||= self.name.underscore.pluralize
end
def insert
column_symbols = self.class.columns.drop(1)
column_names = column_symbols.map(&:to_s).join(", ")
question_marks = (['?'] * column_symbols.count).join(", ")
DBConnection.execute(<<-SQL, *attribute_values)
INSERT INTO
#{self.class.table_name} (#{column_names})
VALUES
(#{question_marks})
SQL
self.id = DBConnection.last_insert_row_id
end
end
And I was confused as to why it's ok to call the table_name method in the "self.columns" method as if it were an instance method. Isn't the "table_name" method a class method? Hence, shouldn't it be called as "self.class.table_name" in the "self.columns" method as well?
When inside an abstract class, the self refers to the proper class, not the object. That's why you can access the method without explicitly telling self
Short answer: self is the implicit receiver in Ruby. If you leave it out, the message will be sent to self. In other words, it is never necessary to say self.foo in a message send, because foo is always implicitly the same as self.foo.
Long answer: there is no such thing as a "class method" in Ruby. What you call a "class method" is actually nothing but a singleton method defined on an object which just happens to be an instance of the class Class.
Actually, there are no singleton methods in Ruby, either. A singleton method is really nothing but a regular old instance method which is defined on the singleton class of an object.
[Note: This is not to say that you should not use those terms. Saying "class method" is clearly simpler and communicates intent better than "instance method of the singleton class of an object of class Class". Also, note that there are methods such as Object#singleton_methods. Those terms clearly exist in the Ruby Community, but it is important to understand that these concepts do not exist in the Ruby Language. They are a tool for communication, not an actual Ruby concept.]
The singleton class is a class that is associated with an individual object. Each object has exactly one singleton class and that object is the only instance (the "singleton instance", hence the name) of its singleton class.
In fact, the inheritance hierarchy of an object always starts with its singleton class, i.e. the class pointer of an object always points to its singleton class, and the singleton class's superclass pointer then points to the class that created this object. You just don't see the singleton class in the inheritance chain, because methods like Object#class "skip over" the singleton class when calculating the inheritance chain. It is, however, always used during method lookup.
In fact, method lookup is actually very simple (the only exception is Module#prepend, which I am going to ignore for this explanation):
Dereference the receiver's class pointer.
If that class's method table has a method by the name of the message, invoke it. STOP.
If not, dereference the class's superclass pointer.
GOTO #2.
If you reach a class that doesn't have a superclass, restart the algorithm with the message method_missing(original_message_name, ...), unless the message name is already method_missing, in which case raise a NoMethodError.
So, it all comes down to two questions:
When defining a method, which class (or module) are you defining it in?
When sending a message, which object are you sending the message to?
When you define a method using def foo.bar, Ruby will first evaluate the expression foo and then define a method bar on the resulting object's singleton class (the definee). If you don't provide foo, i.e. you just say def bar, then bar is defined on the default definee, which is a little bit of a tricky concept. Normally, it is the closest lexically enclosing module definition. If there is no enclosing module definition, i.e. you are at the top-level, the default definee is Object and the method visibility is private.
When you send a message using foo.bar, Ruby will first evaluate the expression foo and then send the message bar to the resulting object (the receiver). If you don't provide foo, i.e. if you just say bar, then the default receiver is self.
Which brings us to the next question:
What is self?
Within a method definition body, self is the receiver of the message send that led to the invocation of this method. So, if you send the message foo.bar, then any reference to self in the definition of the method bar will, during this one execution of the method, evaluate to foo.
Within a module or class definition body, self is the class or method itself. (That is why defining a singleton method instance method of the singleton class using def self.bar works in a module or class definition body.)
Within a block or lambda literal, self is lexically captured, i.e. it is whatever self is at the point where the block or lambda literal is written. However, there are a couple of methods which change how self is evaluated, most notably the BasicObject#instance_eval, BasicObject#instance_exec, Module#module_eval, Module#module_exec, Module#class_eval, Module#class_exec, … family of methods.
If you are always aware of the answers to those three questions (where am I defining a method, what is the receiver of a method call, what is self) at any point in your code, then you have basically understood the most important parts of Ruby.
So, to put it all together:
At the point where you are defining the method using def self.columns, we are in a class definition body, so self refers to the class object itself (SQLObject).
The syntax def foo.bar defines a method bar on the singleton class of foo. In this case, you define the method columns on the singleton class of SQLObject. This means that the object SQLObject is the only object in the universe that will respond to the message columns.
Both of these also apply to the definition of self.table_name.
Inside of the method body of self.columns, self will dynamically refer to whatever the receiver is.
When you send the message columns to SQLObject, i.e. you write SQLObject.columns, then inside the body of the SQLObject::columns method, the receiver (i.e. self) will be set to SQLObject. (In this case, the receiver will always be SQLObject, since this is a method of a singleton class.)
So, inside the method body of self.columns, when you write the message send table_name, this is a message send with an implicit receiver. Since the implicit receiver is self, this is equivalent to self.table_name. self at this point is bound to SQLObject, so this is equivalent to SQLObject.table_name. In other words, the message is sent to SQLObject.
Now, per the algorithm I outlined above, the method lookup first retrieves the class pointer from SQLObject. As mentioned, the class pointer always points to the singleton class. So, we look inside the singleton class of SQLObject to see if we find a method named table_name, and we do!
Method lookup is finished, everything works.
I try to implement a specific Dictionary class in Smalltalk which needs to override the #at:put: method in Pharo and Squeak. But when I create a class having #at:put: as an instance method and I send that methode, I get the error:
Error: Instances of '#SortedDictionary' class are not indexable
The class definition is as follows:
Dictionary subclass: #SortedDictionary
instanceVariableNames: 'index'
classVariableNames: ''
category: 'MyApplication'
An instance is created by overriding new:
!SortedDictionary class methodsFor: 'creation' stamp: 'nanitous 9/28/2015 19:17'!
new
super new.
^self initialize! !
An instance is initialized with:
initialize
index := Heap new.
^self
And the instance method is defined as:
at: anIndex put: aValue
index add: anIndex.
^self at: anIndex put: aValue! !
And I test with the script in a workspace:
| d |
d := SortedDictionary new.
d at: 1 put: 3.
I tried to make a class not derived from #Dictionary but from #Object and used an instance variable dict containing an instance of #Dictionary, but with the same result.
Why can't I override #at:put: and and how can I override this method?
EDIT
Thanks to #lurker and #aka.nice I should have done the following:
!SortedDictionary class methodsFor: 'creation' stamp: 'nanitous 9/28/2015 19:17'!
new
^super new initialize! !
Doing this wrong was outright silly! In the original and wrong code I was trying to index a nil object.
And:
!SortedDictionary instance methodsFor: 'accessing' stamp: 'nanitous 9/28/2015 19:17'!
at: anIndex put: aValue
index add: anIndex.
^super at: anIndex put: aValue! !
Well, I never came to solve this one before solving the #new issue.
Thanks again to everyone taking the trouble to help out here!
Generally, an instance of collection (more precisely a subclass of Collection) is created with #new:, not #new.
The parameter passed to new: is a size, either the size for a fixed size collection (like Array new: 3), or some pre-allocated size for variable size collection (like OrderedCollection, Set, Dictionary, ...).
From the stamp, I guess you are on a Squeak or Pharo flavour, so I will continue explanation with these dialects, it may slightly vary for other flavours.
In Squeak/Pharo, see the definition of HashedCollection class>>new:
new: nElements
"Create a Set large enough to hold nElements without growing"
^ self basicNew initialize: (self sizeFor: nElements)
It sends initialize: not initialize.
So the first thing you have to do is to define initialize: at instance side of your class, and the second thing is to remove definition of new/new: overriding these is rarely ever needed in Squeak/Pharo.
Currently you have a problem in your #new definition, when you tell self initialize what is self exactly? it is the class SortedDictionary, so you initialize the class, not the instance! And you answer the class, not the newly created instance, so you later send at:put: to the class...
It should have been something like newInstance := super new. ^newInstance initialize.
Last, your at:put: definition will loop forever, it should invoke super at: ... put: ...
A couple of nits to pick.
When you write Smalltalk code as text, such as we're doing here,
you can use the format
{classname|blank} {class|blank} >> methodHead
where the first field names the class, the second field tells whether it is class side or instance side, and the '>>' indicates start of source code.
If you don't name the class, we assume the same class as the last one named.
If you don't say it is class side, we assume it is instance side.
So your methods would be written as
SortedDictionary class>>new
^super new
initialize
>>initialize
index := Heap new
>>at: anIndex put: aValue
index add: anIndex.
^super at: anIndex put: aValue
Second, since you're defining a subclass, you only need to define
your own #new (and/or #new:) method if you must override the one that is otherwise inherited from the superclasses. (But you knew that).
Third, whenever you write an #initialize method, you want to get in the habit of writing 'super initialize.' as the first line thereof.
And once you get into said habit, you'll want to get out of the habit of writing your #new methods starting with '^super new initialize', and get into the habit of starting them with 'self basicNew initialize' instead.
I know, everyone learns to do it that other way. (Sigh.)
But that is soooooo wrong.
Extra points if you can figure out why this is so. ;-)
I know that for an instance variable all I have to do is put it inside the initialise method in the instance side and assign it a default value. But how I do this for class variable ? I tried to create an initialise method at class side but it did not give my variable a default value so I had to do this in one of my methods
pythonString ifNil:[pythonString := '']
But I don't like this approach.
I also found this for squeak , http://forum.world.st/Howto-initialize-class-variables-td1667813.html again I don't like this approach either. Is there a proper way of doing this. In Python it was fairly simple case of assignment why is it so cryptic for Pharo ?
First of all I hope that you are talking about instance variable of a class object (not a thing that you define on instance side as "class variable").
initialize is working, but it's being run upon instance creation. And instance (a class object) exists already when you define initialize method.
So when you define your class for the first time, you should run it by yourself e.g. YourClass initialize, bun later each time you load your class into system it should be initialised.
How can we initialize a class variable in Visualworks Smalltalk and destroy it after its use?
I want to know about ClassVariables. NOT ClassInstanceVariables.
I am implementing Singleton pattern and here is my code
MyClass class>> aClasMethod
aClassVariable isNil ifTrue:[
aClassVariable := 'I am a variable'.
]
^aClassVariable.
Once the variable is created, I am not able to destroy it.
i.e Next time I run my code, I see that the class variable is retaining its previous value.
How can I avoid this?
I tried this:
MyClass allInstances do: [:inst |
inst become: nil
].
But of no use.
The best way is simply to add a class method to set the class variable to nil and then call it whenever it's an appropriate time to clear it. I do this all the time with the Singleton pattern.
i think we usually use singleton pattern so that we only have one object. I don't know why do you want to store a string value in the class variable. Try to store a object so you will have only one copy of that specific object and store values in the instance variables. so that specific object has only some specific values. Then in future if u need to update the values stored in instance variable then make one more method updateValues and do everything in that.
I've been hearing these two words used in Microsoft tutorials for VB.NET. What is the difference between these two words when used in reference to variables?
Value vis-a-vis Reference Types
Variables in C# are in 1 of 2 groups. Value types or Reference types. Types like int and DateTime are value types. In contrast, any class you create is a reference type. C# strings are also a reference type. Most things in the .NET framework are reference types.
Parts of a Variable
There is the variable name and its value. Two parts.
The variable's name is what you declare it to be. The value is what you assign to it.
Variables are Initialized
All variables are always given an initial value at the point the variable is declared. Thus all variables are initialized.
For value types, like int the compiler will give them a valid value if you do not do so explicitly. int's initialize to zero by default, DateTime's initialize to DateTime.MinValue by default.
Reference type variables initialize to the object you give it. The compiler will not assign an object (i.e. a valid value) if you don't. In this case the value is null - nothing. So we say that the reference is initialized to null.
Objects are Instantiated
Humans are born. Objects are instantiated. A baby is an instance of a Human, an object is an instance of some Class.
The act of creating an instance of a Class is called instantiation (Ta-Da!)
So declare, initialize, and instantiate come together like this
MyClass myClassyReference = new MyClass();
In the above, it is wrong to say "... creating an instance of an object..."
edit - inspired by comments discussion
Three distinct things are going on (above) using distinct terminology and that terminology is not interchangeable :
A reference variable is declared - MyClass myClassyReference
An object is instantiated (...from/of a given class, implied) - new MyClass()
The object is assigned to the variable. =.
Restating the facts:
A reference-type variable is also called simply "a reference". A "value-type variable" is not a reference.
This: "objectA is an instance of an object" is profoundly wrong. If objectA was "an instance of objectB" then it must be that objectA begins life with objectB's type - whatever that is - and current state - whatever that is. What about creating objects D, E, and F as objectB changes? Nay, nay! It is the conceptual and technical case the "objectA is an instance of a Class". "Instantiation" and "instance of" have precise meaning - an object gets its type, definitions, and values from a Class.
MyClass myClassyReference = null Generally we don't say "the variable is assigned to null" and we never say "the variable is referencing null", No. instead we say "the variable is null"; or "the variable is not referencing anything", or "the reference is null"
Practical Application:
I jab my finger at your code and say "this instance has an invalid property. Maybe that's why the loop fails. You gotta validate parameters during instantiation." (i.e. constructor arguments).
I see this in your code ,
MyClass myClassyReference;
myClassyReference.DoSomething();
"You declared the variable but never assigned it. it's null so it's not referencing anything. That's why the method call throws an exception."
end edit
The Unbearable Lightness of Being
A reference type variable's name and value exists independently. And I do mean independent.
An instantiated object may or may not have a reference to it.
An instantiated object may have many references to it.
A declared reference may or may not be pointing to an object.
A variable is initialized with a value. An object is instantiated when memory is allocated for it and it's constructor has been run.
For instance here is a variable:
Dim obj as Object
This variable has not been initialized. Once I assign a value to the obj variable, the variable will be initialized. Here are examples of initialization:
obj = 1
obj = "foo"
Instantiation is a very different thing but is related since instantiation is usually followed by initialization:
Dim obj As New Object()
In the preceding line of code, the obj variable is initialized with the reference to the new Object that was instantiated. We say that the new Object was instantiated because we have created a new instance of it.
Now I believe that VB.NET makes this a lot more confusing than C# because it is not clear that an assignment is taking place in the code above. In C# it is much clearer that there is both an instantiation of an instance and an initialization of a variable:
Object obj = new Object();
To initialize something is to set it to its initial value. To instantiate something is to create an instance of it.
Often this is the more or less same thing. This:
SqlConnection conn = new SqlConnection();
instantiates a SqlConnection object, and initializes the conn variable by setting it to the that instance.
Since an object's constructor also sets the object's properties to their default values, it's often correct to say that instantiating an object initializes it. (Misleading, if the object exposes a method that you have to explictly call to initialize it after it's instantiated, as is sometimes the case.)
*Instantiation means to create an instance for a class or object.Initialization means to *initiate the same object or class for any purpose.**
Instantiated means that an instance of the object has been created. Initiated means that that same object has done some initialization.
When you instantiate a class or object, you're creating a new instance of it, or allocating memory to "hold" one. Initializing that object would be the instructions that are performed during instantiation.
Instantiation is when you create an instance of a class. That instance is then an object, and you can set its properties, or call methods on it (tell it to do things).
Initiation is when you set up a set of initial conditions for something. That something might be an object, where you tell it to initiate itself, or just a variable to which you assign a value.
An object might initialise some other things, or even instantiate other objects as part of its initiation.
The difference is that instantiation is creation of a thing that can do stuff; initiation is stuff that gets done.
See the Java docs:
https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
"Point originOne = new Point(23, 94);
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object."
We can see it this way. For a line of code below:
var p = new Person();
The above line can be read as following two ways:
The variable p has been initialized as a person class
Person class has been instantiated in variable p
The subject of reference or context matters. When talking in terms of variable, we use the word initialize. When talking in terms of class/type, we use the word instantiate.
Instantiation refers to the allocation of memory to create an instance of a class whereas initialization refers to naming that instance by assigning the variable name to that instance.
Eg: SqlConnection conn = new SqlConnection();
Here new is a keyword which allocates memory for an instance and conn is a variable name assigned for that instance.
Others have explained the difference, so I wont go into detail. But there are cases where instantiation does not properly initialize an object. When you instantiate an object you also initialize it with some data. The class/type will have the initialization logic, whereas the instantiation logic is typically carried out by thenew keyword (basically memory allocation, reference copying etc). But instantiation need not necessarily result in a valid state for objects which is when we can say the object is uninitialzed. Here's a practical example where an object can be instantiated but not initialized (sorry e.g. in C#).
class P { string name = "Ralf"; }
WriteLine(new P().name); // "Ralf";
WriteLine((FormatterServices.GetUninitializedObject(typeof(P)) as P).name); // null
GetUninitializedObject doesn't call the constructor to instantiate object there (but some internal magic).
One could also argue value types are not instantiated but only initialized as it doesn't need new allocation when you do new.. but that's up to one's definition of instantiation.
In object-oriented parlance:
To instantiate means creating an object of some class, which initial state may be undefined.
The class is a blueprint which is used by the program to create objects. Objects created are compliant with the blueprint and can be manipulated by the program. E.g. variables current_client and previous_client can be assigned objects of class Customer. An instance of class X is an object instantiated from class X.
In the code the class is a permanent static description of what an object can do, but the objects themselves are temporary and dynamic. They have an individual state which can be changed (e.g. the Customer name, the associated orders). Instantiation can be done like this:
dim current_client as new Customer (VB)
Customer* current_client = new Customer() (C++)
current_client = Customer() (Python)
new Customer, new Customer() and Customer() are equivalent forms in different languages to trigger the instantiation.
In the end objects are destructed to release memory and other resources required for their existence and working.
To initialize means assigning an initial state to the object before it is used.
This initialization can be part of the instantiation process, in that case values are explicitly assigned to object attributes in the constructor of the object. Alternatively it can be left to the user who can decide whether it is required or not. The latter method allows faster instantiation, but requires the user's code to not read the value of any attribute before this code has explicitly assigned a value to this attribute. E.g. this code:
current_client.count = current_client.count + 1
is not allowed before the attribute count has been set by the user, since it can contain any initial value, including an invalid value which would trigger an execution error.