How to test for existance ?

Discussion in 'Perl Misc' started by no spam, Feb 21, 2005.

  1. no spam

    no spam Guest

    Here's a small script to show what I am trying to do:
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #!/usr/bin/perl -w

    sub print_yep
    {
    print "yep...\n";
    }


    $function1 = "print_yep";
    $function2 = "rubbish";

    $vector->{ACTION1} = \&$function1;
    $vector->{ACTION2} = \&$function2;

    print "something's fishy !\n" if (! exists $vector->{ACTION2});

    $vector->{ACTION1}();
    $vector->{ACTION2}();

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    How can I test if a function exist or not ?
    Shouldn't this print "something's fishy" ??
    I've tried to use defined, to deference in different ways, but I can't get
    it working.


    Thanks,


    Yves.
    ----
    Yves Dorfsman
    http://www.cuug.ab.ca/dorfsmay
    http://www.SollerS.ca
     
    no spam, Feb 21, 2005
    #1
    1. Advertising

  2. no spam <> wrote in news:mFdSd.447549$6l.334107@pd7tw2no:

    > Here's a small script to show what I am trying to do:
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > #!/usr/bin/perl -w


    use warnings;

    is preferable because it allows you to switch specific types of warnings
    on/off of various scopes.

    Also, you are missing:

    use strict;

    > sub print_yep
    > {
    > print "yep...\n";
    > }
    >
    >
    > $function1 = "print_yep";
    > $function2 = "rubbish";
    >
    > $vector->{ACTION1} = \&$function1;
    > $vector->{ACTION2} = \&$function2;


    At this point, it would be instructive to use Data::Dumper to print what
    $vector actually contains. Because of auto-vivification, exists will not
    tell you anything useful. You should also have checked for the
    documentation for defined to see:

    defined EXPR
    defined Returns a Boolean value telling whether EXPR has a value other
    than the undefined value "undef".

    that it would have been less than useful in this case.

    > print "something's fishy !\n" if (! exists $vector->{ACTION2});
    >
    > $vector->{ACTION1}();
    > $vector->{ACTION2}();


    I am sure others who know more about this stuff than I do will show a way
    of doing this by checking the symbol table, but my first inclination would
    have been to wrap the call in an eval.

    > Shouldn't this print "something's fishy" ??


    No.

    > I've tried to use defined, to deference in different ways,


    ITYM 'dereference'.

    use strict;
    use warnings;

    use Carp;

    sub print_yep {
    print "yep...\n";
    }

    my $vector = {
    ACTION1 => 'print_yep',
    ACTION2 => 'rubbish',
    };

    sub dispatch {
    my $table = shift;
    my $action = shift;
    my $dispatch_to = \&{$table->{$action}};
    my @r = eval {
    $dispatch_to->(@_);
    };
    if( $@ ) {
    carp 'Something is fishy';
    @r = ();
    }
    return wantarray ? @r : $r[0];
    }

    dispatch($vector, 'ACTION1');
    dispatch($vector, 'ACTION2');

    __END__
     
    A. Sinan Unur, Feb 21, 2005
    #2
    1. Advertising

  3. no spam wrote:

    > Here's a small script to show what I am trying to do:
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > #!/usr/bin/perl -w
    >
    > sub print_yep
    > {
    > print "yep...\n";
    > }
    >
    >
    > $function1 = "print_yep";
    > $function2 = "rubbish";
    >
    > $vector->{ACTION1} = \&$function1;
    > $vector->{ACTION2} = \&$function2;
    >
    > print "something's fishy !\n" if (! exists $vector->{ACTION2});
    >
    > $vector->{ACTION1}();
    > $vector->{ACTION2}();
    >
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    > How can I test if a function exist or not ?


    OK first thing you are checking for existance in the wrong way.

    exists($vector->{ACTION2}) reports if the hash element exists.

    exists(&{$vector->{ACTION2}}) reports if the function referenced by the
    hash element exists.

    Unfortunately this only works for symbolic references because as Sinan
    mentioned the act of creating a hard reference is autovivificational.

    You should be able to get around this is you use defined() (which gives
    slightly different information[1]) but you can't. The reason for this
    is a truely fascinating bug in Perl that I described in my Usenet Gems
    talk YAPC::Europe::2004. (Slides are available on
    http://birmingham.pm.org/ ).


    [1] exists() is true but defined() false for functions for which there
    is a forward declaration but no definition yet. This may often apply to
    functions that are autoloaded.
     
    Brian McCauley, Feb 21, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ajit
    Replies:
    5
    Views:
    1,038
    Nicolas
    Sep 26, 2003
  2. james

    Re: Co-existance with VS 6?

    james, Apr 14, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    500
    Michael D. Ober
    Apr 22, 2005
  3. no spam

    How to test for existance ?

    no spam, Feb 13, 2005, in forum: Perl
    Replies:
    0
    Views:
    471
    no spam
    Feb 13, 2005
  4. Skybuck Flying

    Call oddities: &Test() vs &Test vs Test

    Skybuck Flying, Oct 4, 2009, in forum: C Programming
    Replies:
    1
    Views:
    705
    Skybuck Flying
    Oct 4, 2009
  5. Jacob
    Replies:
    2
    Views:
    99
    Evertjan.
    Jul 7, 2003
Loading...

Share This Page