How can I create instantiable objects (not classes)?

J

Julien

Hi,

I have a situation where I would like to "instantiate" an object. Note
that I really mean object (which is an instance of its class), not
class. Hence, a child object inherits not only its parent object's
attributes (and the attribute values of the parent, which will be
common to all child instances), but also gains additional attributes
whose values may be different on a per-object-instance basis. So we
have per-instance data vs. object data, a bit analoguous to having
per-object attributes versus class data (which is common to all objects
of the class).

To do this, I've created a parent class called "Instantiable", which
provides a constructor method "new_instance()". When new_instance() is
called on an Instantiable object, it creates a new object of the class
"Instance". This new Instance object has a reference to it's parent
object (a weak reference, so that destruction of the parent does not
depend on destruction its children). The Instance class uses an
AUTOMETHOD (like AUTOLOAD, see Class::Std) such that if an unknown
method is called on an Instance, this is translated into a call using
the parent object's reference on a method of the same name and
arguments, but with an extra argument inserted to identify which object
instance was initially called. Finally, any sub-class of Instantiable
is expected to provide an "instance_init" method, which is called by
new_instance() when appropriate. The instance_init method can be
CUMULATIVE, so that you can instantiate a hierarchy of Instantiable
objects with one call. When implementing methods, there are now 3
types of method calls i) a class method, ii) an object (class-instance)
method and newly iii) an object-instance method.

The application is in a situation where you have a set of identical
objects (e.g. they are all of class Dog), but need to maintain separate
state information for each (e.g. sleeping, barking...), even though
they also common attributes (e.g. hair colour). Another example are
logic gates or flip-flops where you might have 1000s of identical
gates, but they are in a different state. My particular application
has to do with biochemical states of molecules.

If anyone is interested, I can post my code (it's not quite ready yet,
in a few days...). I would welcome comments and tips, I would like to
know if something equivalent or better already exists. I am not sure
if I am using the correct or best vocabulary for "object-instance". I
am not sure which is the best place to keep the instance data, though
currently I keep in the sub-class of Instantiable and that seems to
work. Finally, I would like to use attributes to designate certain
class attributes as being instance attributes instead of object
attributes (similar to ATTR designation in Class::Std). Also, it might
be reasonable to split instance_init into START_INSTANCE and
BUILD_INSTANCE to follow the standard set build Class::Std.

I've already searched CPAN for something similar but nothing jumps out
at me.

A quick and dirty synopsys:

# class InstantiableObject is a sub-class of Instantiable
$object = InstantiableObject->new();
# instance name is I0, InstantiableObject::instance_init(@args) is
called by new_instance
$object_instance = $object->new_instance("I0", @args);

$object->foo(); # call an object (class instance)
method
$object_instance->bar() # call an object-instance method (translated
to $object->bar("I0") )

##############
package InstantiableObject; {
use base qw(Instantiable);
use Class::Std;

# class methods
sub fee {
my $class = shift;
....
}

# instance methods
sub foo {
my $self = shift;
....
}

# object-instance method
sub bar {
my $self = shift;
my $instance = shift; #
.....
}
}
 
M

Mumia W. (reading news)

Hi,

I have a situation where I would like to "instantiate" an object. Note
that I really mean object (which is an instance of its class), not
class. Hence, a child object inherits not only its parent object's
attributes (and the attribute values of the parent, which will be
common to all child instances), but also gains additional attributes
whose values may be different on a per-object-instance basis. So we
have per-instance data vs. object data, a bit analoguous to having
per-object attributes versus class data (which is common to all objects
of the class).

To do this, I've created a parent class called "Instantiable", which
provides a constructor method "new_instance()". When new_instance() is
called on an Instantiable object, it creates a new object of the class
"Instance". This new Instance object has a reference to it's parent
object (a weak reference, so that destruction of the parent does not
depend on destruction its children). The Instance class uses an
AUTOMETHOD (like AUTOLOAD, see Class::Std) such that if an unknown
method is called on an Instance, this is translated into a call using
the parent object's reference on a method of the same name and
arguments, but with an extra argument inserted to identify which object
instance was initially called. Finally, any sub-class of Instantiable
is expected to provide an "instance_init" method, which is called by
new_instance() when appropriate. The instance_init method can be
CUMULATIVE, so that you can instantiate a hierarchy of Instantiable
objects with one call. When implementing methods, there are now 3
types of method calls i) a class method, ii) an object (class-instance)
method and newly iii) an object-instance method.

The application is in a situation where you have a set of identical
objects (e.g. they are all of class Dog), but need to maintain separate
state information for each (e.g. sleeping, barking...), even though
they also common attributes (e.g. hair colour). Another example are
logic gates or flip-flops where you might have 1000s of identical
gates, but they are in a different state. My particular application
has to do with biochemical states of molecules.

If anyone is interested, I can post my code (it's not quite ready yet,
in a few days...). I would welcome comments and tips, I would like to
know if something equivalent or better already exists. I am not sure
if I am using the correct or best vocabulary for "object-instance". I
am not sure which is the best place to keep the instance data, though
currently I keep in the sub-class of Instantiable and that seems to
work. Finally, I would like to use attributes to designate certain
class attributes as being instance attributes instead of object
attributes (similar to ATTR designation in Class::Std). Also, it might
be reasonable to split instance_init into START_INSTANCE and
BUILD_INSTANCE to follow the standard set build Class::Std.

I've already searched CPAN for something similar but nothing jumps out
at me.

A quick and dirty synopsys:

# class InstantiableObject is a sub-class of Instantiable
$object = InstantiableObject->new();
# instance name is I0, InstantiableObject::instance_init(@args) is
called by new_instance
$object_instance = $object->new_instance("I0", @args);

$object->foo(); # call an object (class instance)
method
$object_instance->bar() # call an object-instance method (translated
to $object->bar("I0") )

##############
package InstantiableObject; {
use base qw(Instantiable);
use Class::Std;

# class methods
sub fee {
my $class = shift;
....
}

# instance methods
sub foo {
my $self = shift;
....
}

# object-instance method
sub bar {
my $self = shift;
my $instance = shift; #
.....
}
}

It sounds like what you're trying to do is "delegation." Delegation
occurs when the programmer decides to let one object send those messages
that it can't understand to another object. For example, an object of
type Car might receive a message named "ticket," and since a car does
not know what to do with a ticket, it would pass that message
(unmodified) to an object of type Driver.

(The meter-maid placed the ticket onto the car while the driver was away.)

Read up on delegation in object-oriented programming. FYI they do
delegation in Smalltalk often.

This is an example of delegation:

#!/usr/bin/perl

use strict;
use warnings;
use Class::Struct;

struct Driver => [ Name => '$' ];
struct Car => [ PlateNo => '$', Driver => '$' ];

my @drivers = map Driver->new (Name => $_), qw(Mark Julie James);
my @cars;

push @cars, Car->init(PlateNo => 'TN11', Driver => $drivers[0]);
push @cars, Car->init(PlateNo => 'NQ79B', Driver => $drivers[1]);
push @cars, Car->init(PlateNo => 'R8XE', Driver => $drivers[2]);
push @cars, Car->init(PlateNo => 'ST43', Driver => $drivers[2]);

# Give each car a ticket and see where the messages end up.
$_->ticket() for (@cars);

exit;

####################### packages ####

package Car;
use Scalar::Util qw(weaken);
our $AUTOLOAD;

sub init {
my $self = new(@_);
weaken $self->[1];
$self;
}

sub delegate {
my $self = shift;
my $method = undef;
$method = $1 if (shift() =~ /(\w+)$/);

die "No method" unless $method;
return if 'DESTROY' eq $method;

if ($self->Driver->can($method)) {
$self->Driver->$method($self, @_);
} else {
die ("$self: Object does not understand $method.\n");
}
}

sub AUTOLOAD {
my $self = shift;
$self->delegate($AUTOLOAD, @_);
}

package Driver;

sub ticket {
my $self = shift;
my $car = shift;
print $self->Name, " is handling the ticket for ",
$car->PlateNo, ".\n";
}

# This program is under the GPL (General Public License).
 
J

Julien

Mumia said:
It sounds like what you're trying to do is "delegation." Delegation
occurs when the programmer decides to let one object send those messages
that it can't understand to another object. For example, an object of
type Car might receive a message named "ticket," and since a car does

Hi Mumian,

Thanks a lot for replying :)

I think maybe I didn't make myself clear enough, but anyway I am not
sure that delegation as you are describing is what I am trying to do.
To follow your car example, I am trying to instantiate 100 identical
(say red, with AC, auto windows or whatever) Toyota Corollas, but in a
simulation, each instance of the corolla may have a different speed,
driver, location, etc. So my object defines what the Corolla looks
like off of the assembly line, but an object-instance has additional
attributes with state information. I could just add a "speed"
attribute to the Corolla object and instantiate it 100x, but it seems
to me a waste of memory because a subset of the Corolla attributes are
shared and indentical across all the instances of the Corolla class.

Another way to put my question is, how to share the values of a subset
of attributes of a given class across all instances of that class?

Julien
 
M

Mumia W. (reading news)

Hi Mumian,

Thanks a lot for replying :)

I think maybe I didn't make myself clear enough, but anyway I am not
sure that delegation as you are describing is what I am trying to do.
To follow your car example, I am trying to instantiate 100 identical
(say red, with AC, auto windows or whatever) Toyota Corollas, but in a
simulation, each instance of the corolla may have a different speed,
driver, location, etc. So my object defines what the Corolla looks
like off of the assembly line,

No, a class will define what a Corolla looks like off of the assembly
line, and each "instance" of a Corolla is an "object."
but an object-instance has additional
attributes with state information. I could just add a "speed"
attribute to the Corolla object and instantiate it 100x, but it seems
to me a waste of memory because a subset of the Corolla attributes are
shared and indentical across all the instances of the Corolla class.

This would be class data.
Another way to put my question is, how to share the values of a subset
of attributes of a given class across all instances of that class?

Julien


perldoc perltooc
perldoc perltoot
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top