Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

work around for static vars and singleton constructors not inheriting properly?

by Anonymous Monk
on May 27, 2005 at 00:06 UTC ( #460911=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:


I writing an object oriented framework in Perl. After thorougly digesting Conway's Object Oriented Perl, I decided to build my classes around Class::MethodMaker .

However I am having a problem with static variables and also with singleton constructors. If I make three classes, base, d1, and d2 such that:

d1 ISA base d2 ISA base

where base has a Class::MethodMaker setup like this:

use Class::MethodMaker [ new => -singleton=>'new' ];

And I when write code like this:

my $a = d1->new() my $b = d2->new()

I end up with $a and $b pointing to the same instance of d1!

This makes sense; the singleton constructor in base is allowing only one instance of base to ever exists. But what I want is to have only one instance of d1, AND one instance of d2. I want the singleton constructor to inherit "properly" (as I see it).

Obviously I can make singleton constructors in the derived classes; however I am trying to keep the code in the derived classes as simple as possible, so the users of the framework don't have be burdened with any more than nessecary.

SO THE QUESTION: Is there a proper way to make the singleton constructor inherit like I want it to?

Also I have the same problem with -static variables created with Class::MethodMaker. I assume it's the exact same problem since singleton constructors are built around static (class) variables.

I have my own workaround now; I make my own singleton constructor which keeps a static reference to a hash where the keys are derived class names and the variables are existing instances of those classes.

That works pretty well but I'd like to find a way to do it more cleanly if possible.

Thanks in advance.

Replies are listed 'Best First'.
Re: work around for static vars and singleton constructors not inheriting properly?
by thcsoft (Monk) on May 27, 2005 at 01:29 UTC
    to me Class::MethodMaker looks like an overhead. the really easiest and most efficient way to create a class and instantiate it is by using and inheriting from Exporter;
    package MyClass; use strict; use vars qw/@ISA/; use Exporter; @ISA = qw/Exporter/; sub new { my $class = shift; my $self = {}; bless $self, $class; }
    and later, in a script:
    #!/usr/bin/perl -w use strict; use MyClass; my ($d1, $d2) = (MyClass->new, MyClass->new); ...
    for more information take a look at
    perldoc perlbot perldoc perltoot perldoc -f bless

    language is a virus from outer space.
      This is misleading; Exporter is not being used here and can be omitted entirely.
Re: work around for static vars and singleton constructors not inheriting properly?
by naxos (Initiate) on May 27, 2005 at 03:56 UTC

    Thanks for the response thcsoft but I'm not sure how Exporter is relevant to the static/class var and singleton constructor question. Could you clarify?

    Personally I like using C:MM because it forces me to declare class/instance vars and I get errors on mispellings. I have to admit that I haven't done any benchmarking though...

      your problem, i pretend, is maybe that Class::MethodMaker is an astonishing (and absurd, imho) effort to import java-think into perl. that's why for perl it's an overhead, even looks like. as you can see in the documentation from, the similarity to
      package Baz; BEGIN { require Foo; require Bar; push @ISA, qw(Foo Bar); }
      is conceeded.
      the thing with perl is, that everything is an agreement. every member of a class's instance is accessible directly - however, most people consider that unattractive... so:
      my $object = MyClass->new; print $object->name; print $object->{'name'};
      are identical, provided in MyClass the 'name' method is defined. moreover, the second approach will always be a tick faster, as there is no need for dereferencing a method.
      and if you really like your class to always have only one instance at the same time, try this:
      unlike java, perl does'nt even try to protect you from yourself. ;)

      language is a virus from outer space.
Re: work around for static vars and singleton constructors not inheriting properly?
by simonm (Vicar) on Jul 18, 2005 at 16:07 UTC
    Sorry for the late reply, but I don't think Class::MethodMaker will do this for you.

    My Class::MakeMethods module does have something close to what you want:

    use Class::MakeMethods::Template::ClassVar 'instance' => 'my_singleton', 'scalar' => 'my_static';

    Those methods store a value in a per-class package variable, so each subclass and its instances share a common value without influencing the superclass and other subclasses.

    For the static method, if you'd like the subclasses to default to sharing the superclass value and only override it in a few specific subclasses, use Template::Inheritable instead of Template::ClassVar.

    I haven't tested the combination of Template::ClassVar and instance; please let me know if it doesn't work as expected...

Re: work around for static vars and singleton constructors not inheriting properly?
by diotalevi (Canon) on Jul 18, 2005 at 21:19 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://460911]
Approved by pfaut
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2018-01-19 04:17 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (215 votes). Check out past polls.