Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^4: Reference assessment techniques and how they fail

by kyle (Abbot)
on Feb 17, 2008 at 19:50 UTC ( #668443=note: print w/ replies, xml ) Need Help??


in reply to Re^3: Reference assessment techniques and how they fail
in thread Reference assessment techniques and how they fail

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.

use strict; use warnings; use Test::More 'tests' => 16; use Scalar::Util qw( blessed reftype ); my $side_effect = 0; package OverloadCode; use overload '&{}' => sub { $side_effect = 1; sub {} }; package main; sub is_code_eval { no warnings qw( void uninitialized ); return '' ne ref $_[0] && eval { defined &{$_[0]} }; } sub is_code_util { my $suspected_code = shift; return 0 if '' eq ref $suspected_code; return 1 if 'CODE' eq reftype $suspected_code; if ( blessed $suspected_code && overload::Method( $suspected_code, '&{}' ) ) { return 1; } return 0; } sub real_sub { $side_effect = 1 } check_method( \&is_code_util, 'utils' ); check_method( \&is_code_eval, 'eval' ); sub check_method { my ( $tester, $name ) = @_; $side_effect = 0; my $sub_ref = sub { $side_effect = 1 }; my $overcode = bless {}, 'OverloadCode'; my $undef; ok( $tester->( \&real_sub ), "$name: real sub ref is code" ); ok( $tester->( $sub_ref ), "$name: lexical sub ref is code" ); ok( ! $tester->( $undef ), "$name: undef is code" ); ok( ! $tester->( 'string' ), "$name: string is not code" ); ok( ! $tester->( 'real_sub' ), "$name: real_sub as string is not c +ode" ); ok( $tester->( $overcode ), "$name: overloaded reference is cod +e" ); # this test fails for the eval method ok( ! $side_effect, "$name: no side effect" ); is( $undef, undef, "$name: \$undef is still undef" ); }


Comment on Re^4: Reference assessment techniques and how they fail
Select or Download Code

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (13)
As of 2015-07-28 14:19 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 (256 votes), past polls