in reply to Calling SUPER in MethodMaker-generated methods

<update> Nevermind. It looks like the eval is just trapping the "Can't locate..." error. Strange that it prints the correct results, then. I'll look into it further when I get back from class tonight.</update>

You'll notice that the error says perl is looking for the method in the CustomMethodMaker class, instead of Bug or FixedBug, like it's supposed to.

The issue is that perl appears to be binding SUPER at the time the anonymous sub is created, to the package in which it was created. I'm really not sure why this is happening, but you can get around it by wrapping the call to the SUPER method in an eval.

# In CustomMethodMaker.pm, line 31 # Was: @parent_slots = $self->$to_execute(); # Now: eval { @parent_slots = $self->$to_execute() };

With this change, the test program outputs the following on my system:

id, type, description date_fixed, repairer

If someone more knowledgeable about the internals of Perl's OO could explain why this is happening, I'm rather curious.

bbfu
Black flowers blossom
Fearless on my breath

Replies are listed 'Best First'.
Re: Re: Calling SUPER in MethodMaker-generated methods
by danb (Friar) on Jul 08, 2003 at 20:24 UTC
    Thanks, I really appreciate you taking the time to look into this, and I think you are on to something. I tried the same change that you tried, and I got the same results. However,
    • The correct results are:
      id, type, description id, type, description, date_fixed, repairer
      see http://www.perlmonks.org/index.pl?node_id=272437 for an example that doesn't use Class::MethodMaker.
    • I don't think eval is trapping the error, because there isn't any @$ around after the eval. Therefore, I think that the eval is a valid statement, it just doesn't do what I want.
    • If you try commenting out the same statement, you should get the same results as eval'ing it.

    -Dan

      Actually, the eval is trapping the error. When I put a die $@ if $@; after the eval, it propagates the same error. I haven't tried using the string form of eval but I don't expect that to work any better than the block eval (though it might if it forces perl to bind SUPER at run time, and thus bind it to the base class instead of CustomMethodMaker, which is why I thought to try eval in the first place).

      The reason it works without Class::MethodMaker is (near as I can tell, anyway) that you're creating the sub in the same class for which you want to find the super class. In other words, it might be that if you wrote a third class that installs the method (in which SUPER is called) into the base class, it wouldn't work.

      It's also possible that the error is actually being generated somewhere else in the call chain when the required method is called. I didn't have time to do a full trace of the code earlier. Creating a simple test module that installs the SUPER-calling method into the example which doesn't use Class::MethodMaker would tell you if the issue is actually with using SUPER outside the base class, though, so that's maybe a good avenue to explore.

      Sorry I can't look into it any more right now. I'm at school and don't have access to Perl. :(

      HTH, anyway.

      bbfu
      Black flowers blossom
      Fearless on my breath

        Actually, the eval is trapping the error. When I put a die $@ if $@; after the eval, it propagates the same error.

        Duh, you're right. :-) I was testing for @$ instead of $@. /me slaps forehead.

        The reason it works without Class::MethodMaker is (near as I can tell, anyway) that you're creating the sub in the same class for which you want to find the super class. In other words, it might be that if you wrote a third class that installs the method (in which SUPER is called) into the base class, it wouldn't work.

        I think you're right. Could it possibly be that I've discovered a feature that is impossible for Perl? Nahh... probably I just haven't found the answer yet. :-)

        Creating a simple test module that installs the SUPER-calling method into the example which doesn't use Class::MethodMaker would tell you if the issue is actually with using SUPER outside the base class, though, so that's maybe a good avenue to explore.

        I'll give that a shot (not sure if I can do it, but I'll try).

        -Dan