Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: Determining the fully qualified name of a global variable.

by Athanasius (Monsignor)
on Jan 27, 2013 at 03:44 UTC ( #1015558=note: print w/ replies, xml ) Need Help??


in reply to Determining the fully qualified name of a global variable.

This clueless newbie seeks com[m]ents on/improvements to Xyzzy.pm.

Well, OK, since you asked... ;-)

  • End every module with an explicit 1; to return a true value.

  • Closures are great, but why complicate the code when you don’t need to? In this case, named subroutines do the same job.

  • return undef; is redundant. From return:

    If no EXPR is given, returns an empty list in list context, the undefined value in scalar context, and (of course) nothing at all in void context.
  • Likewise in this construct:

    eval { my $obj = B::svref_2object(shift); $obj->GV->STASH->NAME . "::" . $obj->GV->NAME; } || undef;

    The block form of eval is used to trap exceptions, and “the value returned is the value of the last expression evaluated inside the mini-program” but “If there is a syntax error or runtime error, or a die statement is executed, eval returns undef in scalar context or an empty list in list context”. So the || undef is redundant here.

  • unless ... else ... is an unnecessary double negative. Just swap the blocks and the logic becomes clear.

Here is my version of module Xyzzy.pm:

package Xyzzy; use strict; use warnings; use B; use B::Deparse; use Carp; use Devel::FindRef; use Devel::Symdump; use Exporter; our @ISA = qw( Exporter ); our @EXPORT_OK = qw( FullyQualify ); sub FullyQualify { my ($global) = @_; my @return; if (ref $global) { if (ref $global eq 'CODE') { # $ref is a ref to an autovivified sub if (B::Deparse->new->coderef2text($global) eq ';') { Carp::cluck 'FullyQualifySubName was passed a coderef +' . 'to a sub that has been autovivified!'; } else { push @return, code_ref($global); } } elsif ((ref $global) =~ m[ ^ (?: ARRAY | HASH | SCALAR ) $ ]x) { push @return, var_ref($global); } else { push @return, 'Your ref is a \'' . join(' ', @{ [ ref $global ] }) . ' ref\'!' +; } } else # ! ref $global { my $module; if ($global =~ m[^(.+)::]) # already qualified { $module = Devel::Symdump->new($1); } else # in this caller { my $caller = (caller)[0]; $module = Devel::Symdump->new($caller); $global = $caller . '::' . $global; } push @return, code_ref(eval '\&' . $global) if grep { m[ ^ $global $ ]x } $module->functions(); push @return, var_ref (eval '\%' . $global) if grep { m[ ^ $global $ ]x } $module->hashes(); push @return, var_ref (eval '\@' . $global) if grep { m[ ^ $global $ ]x } $module->arrays(); push @return, var_ref (eval '\$' . $global) . (@return ? '?' : + '') if grep { m[ ^ $global $ ]x } $module->scalars(); } return @return; } sub code_ref { my ($ref) = @_; return eval { my $obj = B::svref_2object($ref); $obj->GV->STASH->NAME . '::' . $obj->GV->NAME; }; } sub var_ref { my ($ref) = @_; my @globals = grep { $_->[0] =~ m[^the global] } Devel::FindRef:: +find($ref); return $globals[0]->[0] =~ s[^the global ][]r; } 1;

Note that I have consolidated the 5 return statements into a single return at the end of sub FullyQualify. Not necessarily an improvement (although I am a big fan of structured programming), but in this case I think it makes the code easier to follow.

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,


Comment on Re: Determining the fully qualified name of a global variable.
Select or Download Code
Re^2: Determining the fully qualified name of a global variable.
by Anonymous Monk on Jan 27, 2013 at 09:01 UTC

    unless ... else ... is an unnecessary double negative. Just swap the blocks and the logic becomes clear.

    LOL

Re^2: Determining the fully qualified name of a global variable. ('return undef')
by LanX (Canon) on Jan 27, 2013 at 09:28 UTC
    > 'return undef;' is redundant. From return:
    If no EXPR is given, returns an empty list in list context, the undefined value in scalar context, and (of course) nothing at all in void context.

    Sorry for nitpicking but it's not equivalent. =)

    In list context  return undef is true, cause a one-element list (undef) will be returned.

    DB<106> sub tst {return undef} DB<107> print "true" if ( @list=tst() ) true

    But empty returns are always false:

    DB<108> sub tst {return} DB<109> print "true" if ( @list=tst() ) DB<110>

    Cheers Rolf

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (11)
As of 2014-12-22 21:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (130 votes), past polls