constructors vs. subclasses?

I

Ivan Shmakov

(ISTR that there was a discussion of this somewhere in the
Perl's documentation, but I cannot find it right now.)

So, I'm implementing a subclass SubClass to the class Class:

package SubClass;
use base 'Class';

Then, how do I write a suitable constructor for SubClass, given
that I need to associate some additional data with the object?

Indeed, I may know that the object is a reference to a hash, so:

sub new {
my ($class, $param_my, @param_super) = @_;
my $self
= Class::new ($class, @param_super)
or die ();
$self->{"SubClass::param_my"}
= $param_my;
## .
$self;
}

However, do I understand it correctly that once the Class'
author switches to, say, a reference to a list, I'm out of my
luck?

I wonder, will it help if the Class' author provided a way for
the subclasses to associate arbitrary data with the object?
Consider, e. g.:

package Class;

sub appdata {
my $self = shift;
return ($self->{"appdata"} = shift)
if (@_);
return ($self->{"appdata"});
}

package SubClass;

## a hack: replace appdata with a "nested" version?
sub appdata {
my $self = shift;
my $myself = $self->SUPER::appdata ();
return ($myself->{"appdata"} = shift)
if (@_);
return ($myself->{"appdata"});
}

sub new {
my ($class, $param_my, @param_super) = @_;
my $self
= Class::new ($class, @param_super)
or die ();
$self->SUPER::appdata ({ "param_my" => $param_my });
## .
$self;
}

And will the hack above allow for this to be repeated for
SubSubClass (and then, if done again, further)?

TIA.
 
R

Rainer Weikusat

Ivan Shmakov said:
(ISTR that there was a discussion of this somewhere in the
Perl's documentation, but I cannot find it right now.)

So, I'm implementing a subclass SubClass to the class Class:

package SubClass;
use base 'Class';

Then, how do I write a suitable constructor for SubClass, given
that I need to associate some additional data with the object?

Indeed, I may know that the object is a reference to a hash, so:

sub new {
my ($class, $param_my, @param_super) = @_;
my $self
= Class::new ($class, @param_super)
or die ();
$self->{"SubClass::param_my"}
= $param_my;
## .
$self;
}

However, do I understand it correctly that once the Class'
author switches to, say, a reference to a list, I'm out of my
luck?

If you want to do that regardless of the representation of the
superclass, you could use a hash indexed by refaddr($self)
(Scalar::Util::refaddr) to store additional attributes[*]. This will then
also need a destructor in order to delete the 'inside out' data when
an instance of the class is being destroyed.

[*] Since 'stringification' can be overloaded, the 'printed
representation' of a class can change at runtime.
 
I

Ivan Shmakov

Rainer Weikusat said:
[...]
So, I'm implementing a subclass SubClass to the class Class:
package SubClass; use base 'Class';
Then, how do I write a suitable constructor for SubClass, given that
I need to associate some additional data with the object?
[...]

If you want to do that regardless of the representation of the
superclass, you could use a hash indexed by refaddr ($self)
(Scalar::Util::refaddr) to store additional attributes [*]. This
will then also need a destructor in order to delete the 'inside out'
data when an instance of the class is being destroyed.

Indeed, that may work. Thanks!

Now, what if I'm facing this issue from the other side?
Is there a particular technique that'd allow for /my/ class to
be easily subclassed in the way described?

TIA.
[*] Since 'stringification' can be overloaded, the 'printed
representation' of a class can change at runtime.
 
R

Rainer Weikusat

Ben Morrow said:
Quoth Rainer Weikusat said:
Ivan Shmakov <[email protected]> writes:
[...]
However, do I understand it correctly that once the Class'
author switches to, say, a reference to a list, I'm out of my
luck?

If you want to do that regardless of the representation of the
superclass, you could use a hash indexed by refaddr($self)
(Scalar::Util::refaddr) to store additional attributes[*]. This will then
also need a destructor in order to delete the 'inside out' data when
an instance of the class is being destroyed.

Don't use a plain hash for this job, use a fieldhash (created with
Hash::Util::Fieldhash). It will track object destruction automatically,
and will handle changing all the keys when a new thread is created in a
threaded perl.

Please consider making that "I would prefer to use ... because of
....". To me, Hash::Util::Fieldhash is one of the (many) examples of
someone who felt somewhat bored and implemented some useless general
purpose library for some random something which didn't run away
quickly enough. And I generally don't care about the products of this
kind of 'recreational programming': Code should solve real problems
and not programming problems and 'abstractions' intended to do the
latter should only be introduced after very careful consideration and
if they provide significant benefits. In case of 'abstractions
provided by third party code', it is prudent to be even more careful/
reluctant wrt using them because

- they will contain bugs which will need to be dealt with at
some point in time

- they will also continue to be buggy in the 'official
version' because if the people who control the code cared
about the issue, they wouldn't be there to begin with (IOW,
I will not only need to fix the code but will be forced to
maintain a fork everthereafter)

- sooner or later, they will be changed in a
backwards-incompatible way
 
R

Rainer Weikusat

Ben Morrow said:
Please consider minding your own manners before criticising other
people's.

I figure that I could get at least a text page worth of derogatory
remarks you made about me (as opposed to statements criticising some
or all of my opinions) out of your postings without much
difficulty, the one above included. This may be your idea of "minding
one's manners" (presumably, everything is fine when targetting people
who "surely deserve it") but it is certainly not mine.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top