in reply to Detecting constant arguments passed to subroutines

Well, I'd do:
sub is_const { !eval { ($_[0]) = $_[0]; 1; } } for (...) { if (is_const($_)) { ... } else { ... } }


japhy -- Perl and Regex Hacker

Replies are listed 'Best First'.
Re: Re: Detecting constant arguments passed to subroutines
by dcd (Scribe) on May 17, 2001 at 01:24 UTC
    The is_const code doesn't seem to detect undef as a constant, although Devel::Peek reports it as READONLY
    perl -w -le 'sub is_const { !eval { ($_[0]) = $_[0]; 1; } } print "undef is ",(is_const(undef)?"":"not")," a constant"' undef is not a constant perl -MDevel::Peek -le 'Dump(undef)' SV = NULL(0x0) at 0x8120d38 REFCNT = 2147483622 FLAGS = (READONLY)
      I just noticed the REFCNT the Devel::Peek::Dump(undef) printed
      That can't be right, can it?
        Perhaps it's that high so that it never "dies"? And the reason it doesn't say undef is constant (from my function) is because undef = $foo is illegal, but (undef) = $foo isn't. Fix:
        sub is_const { defined($_[0]) and !eval { ($_[0]) = $_[0]; 1 } }


        japhy -- Perl and Regex Hacker
        undef is a very popular value! :)
Re: Re: Detecting constant arguments passed to subroutines
by dcd (Scribe) on May 17, 2001 at 10:32 UTC
    After more research I found a function that I was looking for
    sub is_const {use B;B::SVf_READONLY & B::svref_2object(\$_[0])->FLAGS} my $m="va"; our $n=3; my $u=undef; our $u2=undef; for $x ($m, $n, $u, $u2, 4, "a", undef) { print "$x ";$x="VAR" unless is_const($x); print $x,"\n\n" }
    but it too doesn't catch undef being passed it. For what I'm doing now, I don't think I'll encounter this condition. I think that japhy's is_const is 'better' than the flags code that I came across - at least it's easier to read.

    What do you think?

      I just found the real functions I was looking for readonly in Scalar::Util. I haven't figured out yet why calling it indirectly via the is_const function doesn't detect that undef is a constant, as perl dies with an error when trying to modify the undef constant, but at least the readonly is easier to read and comprehend. If anyone can explain the undetect undef constant in is_const I'd be greatful.
      use Scalar::Util 'readonly'; sub is_const { readonly($_[0]); } print "undef is readonly\n" if readonly(undef); print "undef not detected in is_const\n" unless is_const(undef); for $x (4, "a", undef) { print "$x ";$x="VAR" unless readonly($x); print $x,"\n"; } for $x (4, "a", undef) { print "$x ";$x="VAR" unless is_const($x); print $x,"\n"; }
        It is a difference between:
        sub is_const { readonly($_[0]); }
        sub is_const { readonly(@_); }
        sub is_const { readonly($_); }
        
        --
        Lubomir Host 'rajo'
        http://rajo.platon.sk
Re: Re: Detecting constant arguments passed to subroutines
by Anonymous Monk on May 17, 2001 at 01:02 UTC
    Thanks, assigning the value to itself would avoid stringifying