Doubt in Pharo

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Doubt in Pharo

harshit
Hello,

I am creating an Object Relational Mapper in pharo using sqlite.

While creating database I am using a dictionary for columns of Database. This gives me Keys as column name and values as Data type of those.

So suppose Employee is the the table name, with ID->Integer, Name->Text, Salary->Float.

emp:= Employee new.
Now emp is a row of table, so for each row user has to create instance of Employee and then feed values to it. Later on he can pass message insert query to emp.

So I was creating this dictionary for column at the instance side initialization of Employee.

My instructor suggested to do that in class side initialization,

My Doubts are:

1. Why should we do class side initialization instead of instance side initialization.

2. Could you please refer me to the link which explains how to do class side initialization. Because when I do Employee new, I see only instance side initialization is being called.

Thanks,
Harshit


Reply | Threaded
Open this post in threaded view
|

Re: Doubt in Pharo

Peter Uhnak
Hi,

I'm sure someone can give a much better and more in-depth explanation but here goes:

1. Class side initialization is generally used to create fully functional objects. If you use just instance-side you might forget to set some important value (let's say ID) which would leave the object in invalid state. Another reason would be that it shows what does one really need to create a valid instance. If you have Empoyee class>>id: anId name: aName you will now know that salary is actually not needed and the object is able to cope with that. (And you can set it later). Yet another reason would be setting some additional/default values (however this can be done also internally on the instance-side).

2. Some elementary examples might be Rectangle or Point in Kernel > BasicObjects package. Generally you wouldn't send Employee message new directly, because that is class-side's job now, but rather you send the actual values: Employee id: 123 name: 'John Doe'. "answers with an Employee instance"

Peter


On Wed, Jul 23, 2014 at 8:33 AM, Dokania, Harshit <[hidden email]> wrote:
Hello,

I am creating an Object Relational Mapper in pharo using sqlite.

While creating database I am using a dictionary for columns of Database. This gives me Keys as column name and values as Data type of those.

So suppose Employee is the the table name, with ID->Integer, Name->Text, Salary->Float.

emp:= Employee new.
Now emp is a row of table, so for each row user has to create instance of Employee and then feed values to it. Later on he can pass message insert query to emp.

So I was creating this dictionary for column at the instance side initialization of Employee.

My instructor suggested to do that in class side initialization,

My Doubts are:

1. Why should we do class side initialization instead of instance side initialization.

2. Could you please refer me to the link which explains how to do class side initialization. Because when I do Employee new, I see only instance side initialization is being called.

Thanks,
Harshit



Reply | Threaded
Open this post in threaded view
|

Re: Doubt in Pharo

stepharo
In reply to this post by harshit
Hi Dokania

I hope that you do not doubt that Pharo is a cool system :)

> Hello,
>
> I am creating an Object Relational Mapper in pharo using sqlite.
>
> While creating database I am using a dictionary for columns of Database. This gives me Keys as column name and values as Data type of those.
>
> So suppose Employee is the the table name, with ID->Integer, Name->Text, Salary->Float.
>
> emp:= Employee new.
> Now emp is a row of table, so for each row user has to create instance of Employee and then feed values to it. Later on he can pass message insert query to emp.
>
> So I was creating this dictionary for column at the instance side initialization of Employee.
>
> My instructor suggested to do that in class side initialization,
>
> My Doubts are:
>
> 1. Why should we do class side initialization instead of instance side initialization.

Because class side initialization is executing once when the class is
loaded in memory.
And I imagine that you do not want to change and execute the mapping
declaration for every single
instance you will create. isn't?

So

Object subclass: #Employee
     instanceVariableNames: ''
     classVariableNames: 'Mappings'
     category: 'Foo-Model'


Employee class>>initialize

     Mappings := { #ID->Integer . #Name->Text. #Salary->Float }
asDictionary

makes a lot of sense.

or

Object subclass: #Employee
     instanceVariableNames: ''
     classVariableNames: ''
     category: 'Foo-Model'

Employee class
     instanceVariableNames: 'mappings'

Employee class>>initialize

     mappings := { #ID->Integer . #Name->Text. #Salary->Float }
asDictionary

Read pharo by example to understand the difference between class
variable (Shared Variable) and class instance variables
>
> 2. Could you please refer me to the link which explains how to do class side initialization. Because when I do Employee new, I see only instance side initialization is being called.

Employee initialize

you send a message to the CLASS itself to get **ITS** initialize method
execute. Normally when you load the class its initialize method is
automatically executed.

When you do Employee new
     => Employee basicNew initialize
     => anEmployee initialize
     => anInitializedEmployee


>
> Thanks,
> Harshit
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Doubt in Pharo

Richard Sargent
Administrator
In reply to this post by harshit
harshit wrote
So I was creating this dictionary for column at the instance side initialization of Employee.

My instructor suggested to do that in class side initialization,

My Doubts are:

1. Why should we do class side initialization instead of instance side initialization.

2. Could you please refer me to the link which explains how to do class side initialization. Because when I do Employee new, I see only instance side initialization is being called.
This comes down to the distinction between class and instance. As you know, instance-side functionality relates to how individual instances behave while class-side functionality related to how all instances behave. In this case, the relational mapping rules are not going to differ from one instance to another. That is why your instructor advised you to set that up using class-side behaviour.

If you aren't that familiar with Smalltalk - compared to C-derived languages like Java - it may be hard to get really and truly adapted to the meaning of "everything is an object". In this case, you have a number of classes which represent objects mapped to a relational database, so it makes sense that each such class is responsible for defining what that mapping is. (Although, one could argue that proper decoupling of layers moves the responsibility of knowing how to map the data from the individual classes to some other objects.)


As far as doing class-side initialization, it is simply a matter of sending the right messages to the classes at the right time. For example, you might have a Employee class>>#setUpRelationalMappingRules method defined. Before you can replicate the data between Smalltalk and SQL, you need to execute that method.

You have choices in terms of when you actually do it.
- There is "lazy initialization" in which the initialization is done at the last possible instant. But this incurs an overhead in that every mapping occurrence requires the check.
- There is "application start up initialization" in which the initialization is done early, as part of starting the application. For example, when you connect to the database, you can initialize the mapping rules.
- There is "class loading initialization" in which the initialization is done when you actually load the code into the image. This is typically controlled by a class-side method called #initialize. The code loading frameworks may execute the method automatically for you. I find too many "corner cases" with this technique and I prefer explicit behaviours rather than implicit ones.

The "application start up initialization" is my preferred approach. If you imaging the UML of an application, you would have a package for your model code, another for your persistence mechanism, and a third for your "application". This is grossly simplified, of course. The application package has dependencies on the other two packages, but they have no dependencies on any of the others. In this sense, you are using the application to tie together the model and the persistence mechanism of your choice. At start up, you "configure" the persistence mechanism by explicitly invoking the appropriate methods to set up the server connection, the mapping rules, and anything else your choice of persistence requires.