| Contract |
a_thing.<cache_instance
add_vector_key=false if_exists="set"
/> |
| See also | docs |
cache_instance is a method typically used in an init method of a defclass.
It stores an instance in the "of" field of the class.
First cache_instance looks up the 'primary_key' of the parent of the
_subject to cache_instance. The primary_key of 'thing' is "id" so
that is used if there is no other primary_key found.
Then the _subject is examined for a field with the key of the primary_key,
i.e. "id". If the _subject as no primary key in it (no lookup is performed here),
then no further action is taken and the _subject will not be cached.
Otherwise, if there is no "of" field in the parent of subject then
it is created using <thing/> as its value (making an object with parent 'thing').
Then the name of the _subject is retrieved by getting the value of the field
within subject whose key is the value of 'primary_key'.
Then the field of the primary key name is set within the value of "of"
to the _subject.
Here is how it works;
Example:
<defclass boat>
<defmethod init> _new_object.<cache_instance/> </defmethod>
</defclass>
<boat id="bluebelle"/>
The above call returns our new instance since the init method is called
and its last expression is a call to cache_instance which returns
its subject, in this case the '_new_object' which is our new instance
of boat named "bluebelle".
But the important thing is the side-effect. Now
boat.of.bluebelle returns our new object.
Note that since there was no primary_key in boat, the primary_key
defaulted to 'id'. Since our new instance has an id of "bluebelle",
the instance was cached.
We can create an instance WITHOUT caching it if we like by not giving it
an id such as <boat/> or <boat weight=123/>. We might do this if we were
creating a temporary boat.
Caching an instance makes it convenient to reference the object via
a path of its class name, followed by "of" followed by the name of the
instance.
Should we want our "name" field to be called something other than 'id':
Example:
<defclass boat primary_key="licence_plate">
<defmethod init> _new_object.<cache_instance/> </defmethod>
</defclass>
<boat licence_plate="bluebelle"/>
boat.of.bluebelle.licence_plate
result=
"bluebelle"
cache_instance takes one argument, add_vector_key (default false).
If this argument is true, an additional key is added to the "of" object which
is the next highest integer key available in the "of" object.
This makes it easy to count the number of instances, maintain the
order they were created in and reference them by an integer like so:
Example:
<defclass boat>
<defmethod init> _new_object.<cache_instance true/> </defmethod>
</defclass>
<boat id="bluebelle"/>
<boat id="old paint"/>
Example:
boat.of.<length/>
result=2
Example:
boat.of.0.id
result="bluebelle"
boat.of.1.id result="old paint"
The formatting method to_h2o has special support for cached instances.
Example:
boat.<to_h2o only_print_instances=true/>
turns off the printing of the
call to defclass and the printing of all its attributes.
It does however leave on the printing of the "of" field and all the "of" fields
of all the subclasses of the class you are printing.
Use only_print_instances=true when you want to save the instances of a
class in a file but not the classes that they came from since you probably
load them as part of the loading of your application.