Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Detecting constant arguments passed to subroutines

by dcd (Scribe)
on May 17, 2001 at 00:23 UTC ( [id://81070]=perlquestion: print w/replies, xml ) Need Help??

dcd has asked for the wisdom of the Perl Monks concerning the following question:

perltrap.pod has an example that shows how perl5 will trap modification of a constant.
$foo = "x"; &mod($foo); for ($x = 0; $x < 3; $x++) { &mod("a"); } sub mod { print "before: $_[0]"; $_[0] = "m"; print " after: $_[0]\n"; }
perl5 reports this error as
Modification of a read-only value attempted...
Short of doing an eval { } like:
eval { $_[0] .= '' }; if ($@ =~ /Modification of a read-only value attempted/) {
to try to modify to the constant ahead of time, what other ways does perl provide detect that a parameter to a sub is a constant? I've seen that Devel::Peek can report that the flags of a variable are READONLY.
$ perl -MDevel::Peek -le 'Dump("hello")' SV = PV(0x8121a3c) at 0x812b36c REFCNT = 1 FLAGS = (POK,READONLY,pPOK) PV = 0x812f498 "hello"\0 CUR = 5 LEN = 6
Does a module that returns the FLAGS exist?

Replies are listed 'Best First'.
Re: Detecting constant arguments passed to subroutines
by japhy (Canon) on May 17, 2001 at 00:42 UTC
    Well, I'd do:
    sub is_const { !eval { ($_[0]) = $_[0]; 1; } } for (...) { if (is_const($_)) { ... } else { ... } }


    japhy -- Perl and Regex Hacker
      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?
      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"; }
      Thanks, assigning the value to itself would avoid stringifying

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://81070]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-24 23:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found