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

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.

Replies are listed 'Best First'.
Re^4: Problem with Inheriting a Super Class
by PyrexKidd (Monk) on Sep 20, 2011 at 00:00 UTC

    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.

        First, thanks for this example, I now understand what is happening clearly. (I'm still not 100% on exactly what the typeglob is doing, however, this I have a much better understanding.)<bt/> I thought my first try would have solved my problem but when it didn't and all iterations produced the exact same results, without error, that should have been my first clue... Anyway, my real blonde moment is this:
        I created another working copy so I could bang on the code and not worry about messing up the original. I stuck this in my snmp_monitor/brances/ dir. Well, because I was being lazy, I declared my lib path with `use lib '/root/snmp_monitor/trunk';` so when I was making changes under /root/snmp_monitor/branches it was having no effect because the app was still using /root/snmp_monitor/trunk.

        /facedesk

        Thanks for your continued patience