Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: Yet another does-function-exist question

by f00li5h (Chaplain)
on Apr 14, 2007 at 15:32 UTC ( #610072=note: print w/replies, xml ) Need Help??

in reply to Yet another does-function-exist question

Just call it and see what happens.

sub bar { print 'woot' } for my $thing (qw/ foo bar /){ print "$thing :$/"; eval{ no strict refs; &{$thing}(@_); # possibly a nasty symbolic reference }; warn "You can not call $thing: $@ " if $@; }

gives you something like:

foo : You can not call foo: Undefined subroutine &main::foo called at call l +ine 7. at call line 9. bar : woot

The main point being, that you can just catch the die from eval and move on.

Why ask if something looks like it will fail, when you can just suck it and see?

if you're involving objects, UNIVERSAL's can may also interest you

@_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;

Replies are listed 'Best First'.
Re^2: Yet another does-function-exist question
by xaprb (Scribe) on Apr 14, 2007 at 15:44 UTC

    I'm trying to do the opposite of what you're suggesting. I explicitly don't want to call it if it's a function.

    $func = "format_hard_drive"; print "Good news, function exists!" if eval { &$func() };

      You can do it one of two ways.

      1. Check that the thing is valid before hand (as ref $coderef in my class below does)
      2. Check when you call that the result is valid (as the trigger_event sub will do if you remove the test in the first point)

      At the risk of getting a TL;DR, here's something that takes coderefs and then dispatches events with them, as I wrote this, I realised that it's surprisingly long for a simple example ;)

      This is the class that takes care of dispatching the events (to a single handler for each event type)

      This is the client code, that registeres event handlers (to be used as callbacks) and triggers the actual events on the object. Normally, the object would find it's own events, and handle them within a run() type method (Tl's MainLoop for example)

      The class will reject 'antelope' because it's not a real coderef, although if you were to pass in 'main::antelope' as the name, and remove the check for ref $coderef, you should be able to use just names of subs. I don't see why you would want to do this, since it's the same number of characters to write \& as it is to enclose the sub's name quote likes

      Justification: this does answer your question about checking if it's callable before hand (because it uses ref $subref to decide if it can be callled (long before the events actually turn up). This is a fairly painless way to check if something is callable, you can also use anonymous subs if you want

      Hope this helps.

      @_=qw; ask f00li5h to appear and remain for a moment of pretend better than a lifetime;;s;;@_[map hex,split'',B204316D8C2A4516DE];;y/05/os/&print;
        $ perl -le 'print ref (\&no_such_sub);' CODE Useless test.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://610072]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (7)
As of 2021-01-25 18:13 GMT
Find Nodes?
    Voting Booth?