Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^2: Problem with Inheriting a Super Class

by PyrexKidd (Monk)
on Sep 19, 2011 at 21:29 UTC ( [id://926808]=note: print w/replies, xml ) Need Help??


in reply to Re: Problem with Inheriting a Super Class
in thread Problem with Inheriting a Super Class

Hello Chromatic,

Thanks for your reply. I tried both 'our @ISA' and 'my @ISA' without change to the apparent behavior. Now trying with use parent I am receiving the same results.

What really blows my mind, is when I dump the object itself it shows the correct parameters, when I use the object methods to call the parameters is when I am seeing incorrect results.

With that in mind, could this be what is causing my problems?

# create accessor methods for defined parameters for my $datum (keys %{$self}) { no strict "refs"; *$datum = sub { shift; # XXX: ignore calling class/object $self->{$datum} = shift if @_; return $self->{$datum}; }; }

Since this is loaded in the SNMPMonitor::Plugin package, but then inherited to SNMPMonitor::Plugin::Atest (and subsequently Btest) could Btest be overwriting the methods in the symbol table?
After I just typed that I attempted to remove the line :

shift; # XXX: ignore calling class/object
which had no effect.

Even better, (to add to what blows my mind), when I use the methods to access the data I am seeing this bug, when I access the variables directly, I do not have this issue.
...
This must mean that it is an issue with my method of creating accessors for the object, right?

Replies are listed 'Best First'.
Re^3: Problem with Inheriting a Super Class
by chromatic (Archbishop) on Sep 19, 2011 at 21:45 UTC
    With that in mind, could this be what is causing my problems?

    I skimmed that part the first time, but you're right. It's definitely causing you problems. Here's a hint; this is a closure:

    *$datum = sub { shift; # XXX: ignore calling class/object $self->{$datum} = shift if @_; return $self->{$datum}; };

    In other words, every time you create a new object, you create a new closure bound to that new $self. Every time you call an accessor or mutator on an existing object, that accessor or mutator uses the values of the most recently created object.

    The immediate fix is to look at the XXX comment and make that generated method not close over $self. A better fix overall is not to generate (and clobber previously generated!) accessor and mutator methods in your constructor.


    Improve your skills with Modern Perl: the free book.

      Ok, so what is the recommended way of generating accessor/mutator methods? ^This seems to be the prevailing idiom , and I *really* don't want to code them by hand (or write a program that codes them by hand) since very time I add/remove a parameter I'll have to add/remove the accessor.

      My first thought, was to set it so it does not ignor the calling class/object like so:

      *$datum = sub { my self = shift; $self->{$datum} = shift if @_; return $self->{$datum}; };

      This didn't work.

      Then, I tried doing this without the self:

      *$datum = sub { $self->{$datum} = shift if @_; return $self->{$datum}; };

      Again, no change in result.

      Then I tried without the reference to self:

      *$datum = sub { $datum = shift if @_; return $datum; };

      Surprise, this had no affect either.

      Then, I tried doing this without the typeglob. (I'm basically pissing into the wind at this point so what do I have to loose)

      $datum = sub { my self = shift; $self->{$datum} = shift if @_; return $self->{$datum}; };

      Not surprisingly, no change again...
      Here's what really stumps me, through all of these changes I would expect to see an error at least, but the program behaves *identically* through all of the changes.

      The immediate fix is to look at the XXX comment and make that generated method not close over $self.

      I guess I don't understand what you mean. How do you reference the object without referencing the object? (Which is what $self is right? a reference to the object.)

      really, thank you for all of your help.

        This didn't work.

        I find that difficult to believe.

        With that said, if you must generate accessors by hand (and you're better off using Moose), something like this should work. Please note that you should do this outside of your constructor:

        BEGIN { for my $datum (qw( name full_name root_oid plugin_oid full_oid )) { my $sub = sub { my $self = shift; $self->{$datum} = shift if @_; return $self->{$datum}; }; do { no strict 'refs'; *{ $datum } = sub }; } }

        If you don't explicitly shift off the invocant within the method, you won't access instance data.


        Improve your skills with Modern Perl: the free book.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://926808]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-18 22:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found