In this video, we'll explain a point rarely covered in Pharo courses.
How to define variable size objects.
You'll notice that we already use objects of different sizes.
Here I'll create an array using this expression.
It contains ten elements, all set at nil.
Using the same expression, I now create an array
that contains five elements.
We see that the Array class creates instances of variable sizes.
But until now, we haven't explained how you can do this.
So,
here we'll show you how to define classes with variable size instances,
how to instantiate these objects,
and how to access these variable sizes.
Now for the first point.
It's very simple.
The definition uses the message variableSubclass: instead of subclass:.
We copy the Array class definition.
Note that we use variableSubclass, instanceVariableNames,
and so on, to create the class.
Whereas usually, when we define the Pointer class,
Counter class, or Dice class,
we would only use Subclass.
Using this definition, the instances we create have variable sizes.
Using this example, if we want to make a "strange" point,
using two instance variables, x and y,
as a point and a variable zone, we use this definition.
This creates objects that look like this, with a value for x,
a value for y, and one variable zone per instance.
We could also have another instance,
which also has x and y, with 10 here and 20 here,
and, for example, 100 here and 200 here,
with a variable zone that can contain different objects.
So, the instances of a class that can have variable size instances
have an indexed zone that is added after named variables, like x and y.
It's implicit and there's only one per class,
to avoid implementation problems when expanding it.
Now we've seen how to create classes
that have different sized instances.
Now we'll go back to how we can instantiate them
and how to access this variable size.
The way we instantiate them
is to use the message "new:" noting the use of the colon.
We discussed this in the course on collections.
Here we want to create a variable size object.
The variable size of the object is specified by its "max" value.
So, we create an object, an array with four elements.
This shows the four elements.
How do we access this variable size?
We use the messages at: and at:put:, which you saw in the arrays.
This works for all objects with a variable size.
So, if we write at: 2 here, we add 'lulu'.
Then if we access value 1, it will logically return nil.
And if we look at value 2, it will give us 'lulu.'
In fact, a mapping is applied here
between arrays and variable size objects using at:put: and 'lulu.'
This API protocol functions for arrays
and for all objects we want to have a variable size.
I haven't explained a great deal here,
only how to define Array class and extend it to other objects,
since you know the protocol.
So, in Pharo there are objects, or classes,
that take different forms.
There are classes that only have named instance variables,
like Counter class with count or Dice class with the number of sides.
Then we have classes that only have
a variable or indexed zone, like Array class.
Then we have other classes that are a mix of both.
However, there are some constraints, it's more subtle than it seems.
We can now decide on the type of class variable.
I'll just show you the intention.
This variable aspect we're talking about
can simply be object pointers, or perhaps Byte or Word variables.
It's used to interface with the outside world
when we need to specify a size,
and within it we put pointers to objects with a specific form.
This is an advanced feature, but I wanted to show it to you.
You'll usually only need to use "Subclass."
Sometimes you'll use "variableSubclass"
and "Bitmap," which represents the screen.
Bitmap is an object
that has a variable zone, named Words.
Just so you know it exists.
Since Pharo is a reflective system,
we can ask it questions.
So, using these methods, we can make queries.
Such as whether the class size is fixed or variable.
Or whether it stores pointers or bytes, for example.
We have the entire API to enquire about the type of class.
This list was created by making queries to the system.
A constraint applies.
Classes that are defined using subclass
can have any type of subclass.
If we have points using x and y,
we'll be able to add a subclass named z
or a subclass named xy, plus a variable zone.
But if you want to create a subclass of a class that already has a variable,
you can only use variables from classes that are variable.
Otherwise, the system that constructs classes says it's incompatible.
It needs to know that there is one zone to handle the constraints.
In any case, the system will inform you if it's impossible.
So, what do you need to know?
You should now know how to define classes
that have instances of variable sizes
and how to instantiate them using "new:"
and how to access them using the protocol seen in the arrays.