in reply to Re: Re: Calling can method
in thread Calling can method

You can't safely call $x->can('foo') though, although you can always call UNIVERSAL::can($x, 'foo'), which is where the idiom comes from. True, it's overkill for the class case, but for the instance case, it's mandatory.

-- Randal L. Schwartz, Perl hacker

Replies are listed 'Best First'.
Re: Re: Re: Re: Calling can method
by gildir (Pilgrim) on May 30, 2001 at 17:48 UTC
    Well, I wonder in what circumstances I cannot call $x->can('foo') safely.

    Only scenario that comes to my mind is when author of class that implements object $x overrides method 'can'. But if such an author would do this, he is supposed to know what he is doing, as 'can' is a well known method together with 'isa'.

        Or when it doesn't contain a class name:
        package Test; sub foo {}; package main; if (Test->can('foo')) { print "Hardcoded can works!\n"; } my $t = 'Test'; if ($t->can('foo')) { print "Variable can works!\n"; }
        Now you or I wouldn't usually let that pass in a code review, which is why I go the extra step of invoking UNIVERSAL::can(). But we both know one dirty little secret of OO Perl, that it's the class name that's important, not the fact that something has been blessed.
      When can't you call $x->can('foo') safely? When $x can't can(), of course!
      for $x ('main', undef, \1) { if (UNIVERSAL::can($x, 'can')) { # ok print "can can\n"; $x->can('foo'); print "\n"; } else { # error: Can't call method "can" on undefined value/unblessed refe +rence ... print "can't can\n"; eval { $x->can('foo') }; print "$@\n"; } }

        Clarification: The else part wouldn't generate an error for 'main' but would/does for the other two (well, it wasn't clear to me at first but I think that is more my problem than chipmunk's).

        One case you didn't mention is "strings that don't start with a \w character":

        $x= '*fred'; print $x->can('can'); Can't call method "can" without a package or object reference
        and, yes, it is (currently, at least) only the first character that matters for this test.

        BTW, these errors are fatal (which is why chipmunk used eval, otherwise the loop would not have continued).

        Updated many times while I tried to make some sense.

                - tye (but my friends call me "Tye")