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

I have an object of an unknown class and I want to invoke a method of which I will know the name only at execution time.

I can test if the object contains this method with

if ( $obj->can( $method ) ) { # now I want to invoke $method on $obj

How?

Thanks for any hints

Regards Thedi gerber@id.ethz.ch

Replies are listed 'Best First'.
Re: Invoke a method on an object
by Corion (Patriarch) on Jan 13, 2009 at 10:19 UTC

    The easiest way is to do this:

    $obj->$method(@args)

    But you can also call the code reference you got back from ->can:

    my $method = $obj->can($method_name); $method->( $obj, @args );

    As $method is not bound to $obj, you have to supply $obj as the first parameter.

      Thanks, thats all I need

      Best regards

      Thedi

      Since I believe he is talking about $method being a string, wouldn't the first version need no strict 'refs', and a leading ampersand?

      for(split(" ","tsuJ rehtonA lreP rekcaH")){print reverse . " "}print "\b.\n";

        No:

        perl -Mstrict -le "sub P::p{print 'p'};my $p=bless {},'P';my $m='p';$p +->$m;"
Re: Invoke a method on an object
by moritz (Cardinal) on Jan 13, 2009 at 10:18 UTC
    $obj->can( $method ) returns a sub ref that you can execute like this: $obj->can( $method )->($obj, @args).

    See the UNIVERSAL documentation for details (can, isa and the likes are defined there).

Re: Invoke a method on an object
by Bloodnok (Vicar) on Jan 13, 2009 at 12:10 UTC
    More of a comment on my continuing inadequacies, but hey, here goes...

    I seem to recall trying the can() approach recommended by both Corion & moritz, but the attempt failed and have not tried it since. In retrospect, I only now (it _was_ a number of years ago) realise that my attempt didn't include the class/object ref. as the first arg - Doh !!!

    Or, put another way, it's nice to have one, or more, of our learned friends/colleagues/monks to occasionally point out the obvious :D

    I'll bet it doesn't apply here, but one thing to beware of, as was pointed out for me elsewhere, is that using either isa or can as the method name will undoubtedly cause problems (see Arrgh, can() appears to work for non-object !! for details).

    A user level that continues to overstate my experience :-))