Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re: Reference assessment techniques and how they fail

by chromatic (Archbishop)
on Feb 17, 2008 at 06:06 UTC ( #668389=note: print w/ replies, xml ) Need Help??


in reply to Reference assessment techniques and how they fail

Note that this technique can't detect a code reference because it would call the referenced sub.

It calls the overloaded sub, which has to return a code reference to execute. If you write defined &$some_object, perl will not call the returned code reference, but the expression will evaluate to true.


Comment on Re: Reference assessment techniques and how they fail
Select or Download Code
Re^2: Reference assessment techniques and how they fail
by kyle (Abbot) on Feb 17, 2008 at 17:18 UTC

    Good point, but there's actually another problem I forgot to mention. In a &{}, undef is code.

    use strict; use warnings; use Test::More 'tests' => 3; sub is_code { no warnings qw( void uninitialized ); return eval { defined &{$_[0]}; 1 }; } sub real_sub { die 'real sub called' } my $sub_ref = sub { die 'sub ref called' }; my $undef; ok( is_code( \&real_sub ), 'real sub ref is code' ); ok( is_code( $sub_ref ), 'lexical sub ref is code' ); ok( is_code( $undef ), 'undef is code' );

    This isn't a big deal, I guess. We just have to change is_code to return defined $_[0] && eval { defined &{$_[0]}; 1 };. Still, I'd rather call something that figures out what it is than call it to figure out what it is.

      Good point, but there's actually another problem I forgot to mention. In a &{}, undef is code.

      That's not true. Why is your eval always returning 1 unless it dies? With

      sub is_code { no warnings qw( void uninitialized ); return eval { defined &{$_[0]} }; }

      things look more reasonable. If undef were code, it'd be a serious bug.

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        Ah, you're right. I was thinking of the wrong exception and wrote the wrong test.

        use Test::More 'tests' => 5; sub is_code { no warnings qw( void uninitialized ); return eval { defined &{$_[0]} }; } sub real_sub { die 'real sub called' } my $sub_ref = sub { die 'sub ref called' }; my $undef; ok( is_code( \&real_sub ), 'real sub ref is code' ); ok( is_code( $sub_ref ), 'lexical sub ref is code' ); ok( ! is_code( $undef ), 'undef is not code' ); ok( ! is_code( 'string' ), 'string is not code' ); ok( is_code( 'real_sub' ), 'string is code' );

        So you still need an extra check in is_code.

        sub is_code { no warnings qw( void uninitialized ); return '' ne ref $_[0] && eval { defined &{$_[0]} }; }

        That's fairly simple, but I think I still prefer the battery of ref, Scalar::Util::reftype, Scalar::Util::blessed and overload::Method.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (9)
As of 2015-07-06 16:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (77 votes), past polls