Syntax for class and instance variables and methods in Pharo 4.0
Asked Answered
M

2

5

I am learning Pharo online and am not sure if I got the syntax correct for creating class and instance variables. Please correct me if I am wrong :-

Class (Static) method created on class side of Pharo, where name, email, phone are instance variables of class CreateUser:

createNewUser:Arguments name:userName email:userEmail phone:userPhone

To call this static method of class CreateUser, I will do the following :-

CreateUser 
     name:userName
     email:userEmail
     phone:userPhone

If I want to create an instance variable by this name, the method declaration will be exactly the same as above, but it will be on the instance side of the class. However, when I call the method, I will call it using the keyword "new" to create a new instance as under:

CreateUser new
     name:userName
     email:userEmail
     phone:userPhone

When I run the above code and call this method statically, I get an error message as:-

MessageNotUnderstood: CreateUser class >>name:email:phone:

However, when I go to the CreateUser class to recheck, I see the above method create on the class side as :

CreateUser:name:email:phone:

My queries are as below: 1. What am I doing wrong above? How can I fix the above error? 2. The concept behind using static variables/methods vs class variables/methods is the same as Java? 3. If I wish to access the above instance variables, I can add accessor methods for class/instance and then call them with the class instance/class object instance. Is that correct?

Any help you can give will be greatly appreciated! Thanks very much in advance.

Mannequin answered 14/6, 2015 at 6:52 Comment(0)
K
10

I guess you misunderstand the method syntax a bit, because createNewUser:Arguments part makes no sense. What you should have is a method on the class side like this:

name: userName email: userEmail phone: userPhone
   "and here you probably have something like:"
   name := userName.
   email := userEmail.
   "and so on"

In my example name:email:phone: is the method's selector and userName, userEmail and userPhone are parameters. You can call this method as in your example. name and email are either class side on instance side variables depending on where the method is defined.

Also you shouldn't name a class CreateUser. Think about this, what will be the instances called? "createUsers"? Usually you name a class User, then you can think about instances as "users", and then the responsibility of the class object is "to create users (its instances)".

Please note, that it's weird to have a method like this on the class side. What you usually do is to create an instance method:

initializeName: userName email: userEmail phone: userPhone
   name := userName.
   email := userEmail.
   phone := userPhone

and a class side method:

newName: userName email: userEmail phone: userPhone
   | instance |
   instance := self new.
   instance initializeName: userName email: userEmail phone: userPhone.
   ^ instance

or a shorter version using cascaded messages:

newName: userName email: userEmail phone: userPhone
   ^ self new
      initializeName: userName email: userEmail phone: userPhone;
      yourself

2) In Pharo (and Smalltalk) the concept is a bit simpler. As everything is an object, Class is an object also, so class side variables and methods are instance variables and methods of a class which is an instance of the "class class". Next picture may help you to understand the associations between objects in Pharo:

enter image description here

This may be a bit confusing at the beginning, but in the end, you don't have and static/nonstatic methods/variables, you just have objects, instantiation and inheritance.

So what you should think about is what are you going to ask the objects about. Probably you should ask User about it's email or mobile number, but you will ask User class to create a user or find a user, or suggest a default t-shirt size for a user.

3) Yes, you should make an accessor. Moreover, if you select a class in system browser and press Cmd+H+A (or Ctrl, or Alt) depending on your OS, you will get a dialog for automatic accessor creation

Karp answered 14/6, 2015 at 9:26 Comment(4)
Thats very very clear now. Thank you very much. And my code works now, I also modified the class name as you suggested. However, the discussion about objects got me thinking.. If every thing is an object, class side methods and variables are also treated as objects of "class class", then can we implement polymorphism and inheritance using smalltalk? I mean I know that there is also no way to define a datatype for variables/arguments/return values. If that is the case, does compile time polymorphism exist? And inheritance is single or multiple? Finally, what is double dispatch?Mannequin
@Mannequin Pharo is completely object oriented language with single inheritance and traits. "Everything is an object" concept allows you to have the same "interface" when you need to work with something. For example if you execute Object methodNamed: #printOn: you will gat an instance of CompiledMethod class which is your class. And to work with it you don't need some special tools, but as it is an object, you can sent it a message. (Object methodNamed: #printOn:) argumentNames will return all the argument names. Also you can evaluate that method, ask fro it's AST and so on.Karp
I see. So abstract classes/interface refer to the same thing? I know you can define abstract classes with methods that say "subclass responsibility" to create their own implementation forcefully. Is this the only way abstract classes/interface/inheritance is implemented?Mannequin
@Rekha, you see, Pharo does not force you to do all the complicated type things (which is nice). Now to achieve polymorphism you don't need to subclass the same thing. So for example both Streams and Transcripts implement #nextPutAll: method which makes them polymorphic: you can substitute a transcript with a stream and your logging will not break. Now to help communicating intensions we have methods like #subclassResponsibility and to avoid code duplication you can definitely use inheritance or traits which are "pluggable sets of behavior` i.e. they contain only methods and no dataKarp
I
1

@Rekha - In case you find this useful in your learning, take a look at the Updated Pharo By Example book. (Specifically, the 'Pharo Object Model' chapter, which is exactly about the topic of this question -- instance creation, class variables, inheritance, etc). The book is a work in progress (we're updating the old 'Pharo by Example' book to refer to the new version of Pharo), but should still prove useful.

Inexhaustible answered 15/6, 2015 at 14:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.