in reply to Re: Dynamically wrapping ancestor method calls
in thread Dynamically wrapping ancestor method calls

jbert,
You could and that is one of the ideas put forward. Do you know how it would work if you had more than one ancestor before you got to UNIVERSAL? I don't know of all the issues but it seems like there would be more than just what would happen if the symbol table was modified at runtime.

I am not sure there is a good answer, that's why I asked. To state it a different way, how can I overide perl's method resolution process and insert my own.

Cheers - L~R

  • Comment on Re^2: Dynamically wrapping ancestor method calls

Replies are listed 'Best First'.
Re^3: Dynamically wrapping ancestor method calls
by jbert (Priest) on Dec 11, 2006 at 20:09 UTC
    If you assume that the symbol tables of your superclass tree aren't going to change, you could scan them in the same order that perl does (recursively take @ISA from each one and walk up the hierarchy), and thus build up a complete list of possible methods on the subclass.

    Since that ordering is documented, you aren't really abusing internals knoweldge to do that.

    It seems to me that that should work. It still isn't very nice though. I still like the proxy object, actually. That seems to work pretty well.

    Out of interest, may I ask about the the original problem which is being addressed by the automagic wrappering?

      Out of interest, may I ask about the the original problem which is being addressed by the automagic wrappering?

      I'm the author of Audio::XMMSClient. This module provides an asynchronous interface th xmms2's client library. This is quite powerful but not very easy to use, especially very simple scripts or unit tests which don't need the async interface most of the time.

      Therefor I wanted to write a wrapper, Audio::XMMSClient::Sync, around it that does just the same as Audio::XMMSClient does on all method calls, except for those which return some kind of request handle to be used in asynchronous clients. In that case it should just block until the request is completed, unpack the response into some perl structure and return that.

      That way code that looked like that with the async api..

      my $con = Audio::XMMSClient->new(...); $con->connect or die $con->last_error; my $res = $con->medialib_get_info( $some_song ); $res->wait; my $value = $res->value;

      becomes that..

      my $con = Audio::XMMSClient::Sync->new(...); $con->connect or die $con->last_error; my $value = $con->medialib_get_info( $some_song );

      Cheers, Flo

        Ah, I see.

        So you could achieve what you want by putting a wrapper function around the return statements of the relevant methods in Audio::XMMSClient.

        return $s->_process_handle($handle);
        where _process_handle just returns its arg for async behaviour or does the sync-wait-and-return-data for the sync behaviour. You could select between the two either by subclassing (and overriding _process_handle), or even passing in sync => 0/1 to the ctor.

        If that isn't palatable for some reason, this sounds a little bit like a job for that modern buzzword Aspect Oriented Programming. This isn't really my area of expertise, but as I understand it, it allows you to effectively install pre- or post- handlers into your existing codebase, selected by various criteria. Adding handlers to massage the return values of a given class sounds within it's remit.

        I suspect that under the hood it is doing the same symbol table walking we've talked about before, but that should work OK in your case I think.

      jbert,
      WRT the original problem, perhaps rafl can explain. When I pressed further on IRC there was no response. Presumably this is because rafl was AFK working on alternatives.

      Cheers - L~R