webby has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I've got a small question about the best way to preserve class data across calls to a cgi. In particular, I would like to set class defaults for an attribute, and preserve these defaults after inheriting the methods. For example, If I have the following code:
#!/usr/bin/perl package a; my $bar = 'bar'; sub foo { my $self = shift; @_ ? $bar = shift: $bar; } package b; use base 'a'; sub new { my $class = shift; my $self = bless {}, ref($class)||$class; $self->foo('cow'); return $self; } package main; my $object = do "persistB.obj"; print $object->foo();
where persistB.obj is simply a pre-built instance of class B:
$VAR1 = bless( {}, 'b' );
then the call to $object->foo() return 'bar', instead of the intended 'cow'.

Now, back in the real world I need this to work for a project involving multiple objects inheriting common functions. In the interest of ease, I would like to have a simply setup routine that each class definition uses to set defaults for various attributes, keeping most of the implementation in some parent class.

I originally thought of having a BEGIN code block call a subroutine in the child object, but that won't work as BEGIN doesn't get any arguments passed to it.

Any ideas?

TIA,
webby

Replies are listed 'Best First'.
Re: Persistent Class data
by PodMaster (Abbot) on Oct 13, 2002 at 09:10 UTC
    Um, yeah, use Data::Dumper, or Data::DumpXML see XML-ish Data::Dumper?, which won't work always, or use Storable or even FreezeThaw.

    Whichever fits the bill for you.

    update: I hope this clears things up.

    As you see, your little bless trick won't work quite so well. Most of the time, Data::Dumper/Storable can handle such things properly, but not always.

    You'd be better off storing a simple hash, from which you create a new object, like

    #persistB.obj $VAR1 = { foo => 'bar' }; my $object = do "persistB.obj"; $object = b->new($object);
    When you bless something directly, you avoid all the stuff b::new does. By properly serializing your variables with one of the modules I mentioned above, you avoid this issue (there are other issues of course, but the docs for the modules above discuss them).

    You'll also be wanting to reconsider the implications of

    my $self = bless {}, ref($class)||$class;
    See Re: perl oo for discussion about that.

    ____________________________________________________
    ** The Third rule of perl club is a statement of fact: pod is sexy.

      Alas, I can't quite see how this answers the question (which was about class data, not instance data). Could you be a bit clearer?

      Thanks.
      Thankyou - The example that you used doesn't quite work in my real world situation, but serializing is it. I'll change all of my Data::Dumper calls to Data::Dumper::Toaster, and specify a method to call that re-populates class data.