Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Multiple Inheritance - Howto marry tie::refhash::nestable with class::singleton

by hoppfrosch (Scribe)
on May 31, 2005 at 10:58 UTC ( #461989=perlquestion: print w/ replies, xml ) Need Help??
hoppfrosch has asked for the wisdom of the Perl Monks concerning the following question:

Hi there, I'm quite a newbie with ties and multiple inheritance in perl (shame on me ... ;-)). What I wan't to do is to have a global hash which could be accessed like a singleton (via ...->instance()) - so I may get an instance of my hash anywhere in subsequent modules without passing the hash via parameters ...

My idea is to construct a "tied Singleton" by both inheriting from tie::refhash::nestable and Class::StrongSingleton.

What I did yet in my module file:

package GlobalHash; use vars qw(@EXPORT @EXPORT_OK $VERSION $REVISION $AUTOLOAD @ISA); use Exporter; ... use Tie::RefHash; use Class::StrongSingleton; use base qw(Class::StrongSingleton Tie::RefHash::Nestable ); sub TIEHASH { my $proto = shift; my $class = ref($proto) || $proto; my $self = {@_}; $self = Tie::RefHash::Nestable->TIEHASH($self, $class); # initialize it as a singleton $self->_init_StrongSingleton(); $self->{'START'} = scalar localtime; return $self; }
This doesn't work, since $self = Tie::RefHash::Nestable->TIEHASH($self, $class); returns a Tie::RefHash::Nestable-object - but what I want to get back is a GlobalHash object ...

Any help welcome

Hoppfrosch

Comment on Multiple Inheritance - Howto marry tie::refhash::nestable with class::singleton
Select or Download Code
Re: Multiple Inheritance - Howto marry tie::refhash::nestable with class::singleton
by merlyn (Sage) on May 31, 2005 at 12:05 UTC
    First, let's get the brokenness out of the way:
    my $class = ref($proto) || $proto;
    Please read ref($proto) - just say no!.

    Now, it looks like you're enamored with shiny objects. Let's get back to the basics. You want a hash that is in every namespace? Then simply create a module that populates the hash and exports it:

    package MyGlobalHash; use base Exporter; @EXPORT = qw(%MyGlobalHash); %MyGlobalHash = (foo => "Hello, world!\n"); 1;
    And to use it:
    package RandomPackage; use MyGlobalHash; ... print $MyGlobalHash{"foo"};
    There. No singleton or tie or any of that junk needed. If that won't suffice, please clarify.

    Also keep in mind that I hate global data. You should export behavior, not data. You should avoid global data as much as possible, because it creates nasty couplings that keep you from refactoring or reusing or testing code well.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Hi,

      I agree with your aversion to global variables, but since I'm currently reengineering stepwise a large piece of code (which makes intensive use of global variables) I have to use global variables (in my first reengineering iteration) as well to keep the code working.

      On the other hand: What speaks against a global variable keeping all information needed anywhere in the code? An alternative might be passing the data by parameters - which causes a lot of typo-overhead, since the data is needed anywhere in the code.

      You were partially right with your conclusion "you're enamored with shiny objects" - first I had a singleton as global data structure. Then I wanted to have an easy access to the data members like hash access. This results in my idea of the marriage ...

      But your suggestion only meets half the truth: I'm not able to populate the hash within an unique action - the contents of the hash has to grow/change during runtime ... Therefore I need a dynamic - and not a static - global data structure.

      Beside all aspects that speak against my suggested solution: As I'm keen to improve my perl knowledge, I would like to have a solution to my problem with "multiple inheritance" and correct initialization ...

      Hoppfrosch

        What speaks against a global variable keeping all information needed anywhere in the code?

        merlyn isn't saying you shouldn't have a global repository for information. What he is saying is that you should be exporting functions/methods that the code can call to access said information. Then, if you ever need to log something or modify something as it's being set or retrieved, you have one place to do that. Or, let's say you're moving from a file-based system to a DB-based system.

        Bite the bullet and change everything to a pure singleton and call the methods to get at or set the data. This is even more important with setting data. (Though, this is starting to sound more like a stash vs. a configuration object ...)


        • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
        • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"
        ... multiple inheritance ...
        "Multiple inheritance" is almost always the wrong answer to any question. You can only inherit from classes that are compatible with each other, perhaps even specifically designed to be used as a "mixin" class. You discovered two that don't play well together, so the answer is "you can't do that there".
        Therefore I need a dynamic - and not a static - global data structure.
        There's nothing preventing any part of your code from updating the data structure. The initialization will be executed on the first "use", but then anyone is free to change it. In fact, that's my beef with that! Anyone can change it! Good luck tracking down bugs.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: Multiple Inheritance - Howto marry tie::refhash::nestable with class::singleton
by GoCool (Scribe) on May 31, 2005 at 17:32 UTC
    This doesn't work, since $self = Tie::RefHash::Nestable->TIEHASH($self, $class); returns a Tie::RefHash::Nestable-object - but what I want to get back is a GlobalHash object ...

    By reblessing the $self object into the GlobalHash class you would be able to return its object as shown below, wouldn't you?

    bless $self, 'GlobalHash';
    return $self;
Re: Multiple Inheritance - Howto marry tie::refhash::nestable with class::singleton
by brian_d_foy (Abbot) on May 31, 2005 at 19:58 UTC

    Class::Singleton and its relatives really don't do that much for you. Look under the hood and you won't find that much code. The concept of a singleton is very simple and you can just implement the 5 lines of code in your module. You can see my article on Singletons in The Perl Review 0.1.

    The Cult of Design Patterns seems to think that you should make the end programmer realize he is using a singleton, and instead of new() use something like get_instance(). I think that's the wrong way to go: in most cases the end programmer shouldn't have to think about that as long as everything works.

    That doesn't matter much in your case since the magic is hidden in the Tie interface. Before you start doing things in TIEHASH, however, you need to check if you already have the instance, and if you do, simply return it. Don't make a new object then check for an old one.

    --
    brian d foy <brian@stonehenge.com>

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://461989]
Approved by prasadbabu
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2014-09-02 00:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (18 votes), past polls