Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Re^4: $1 not "freezing" in an addition

by tobyink (Canon)
on Dec 14, 2012 at 14:57 UTC ( [id://1008850]=note: print w/replies, xml ) Need Help??


in reply to Re^3: $1 not "freezing" in an addition
in thread $1 not "freezing" in an addition

"It ought to be easy to recognize an unquoted $1 as a function argument and issue a warning"

The problem occurs in:

return $1 + sub_that_does_regex_capturing(...);

$1 is not a function argument in that. $1 hasn't been a function argument in any of the examples in this thread.

The problem is writing an expression where one of the operands has a side-effect that can alter the value of another operand. This is very hard to detect through static analysis of source code; it's probably not especially easy to detect at run-time either. Heuristics may be able to catch some common cases.

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^5: $1 not "freezing" in an addition
by grondilu (Friar) on Dec 14, 2012 at 15:36 UTC

    Interesting. This gave me the idea of trying this code:

    $_ = 1; print $_ + $_++;

    Amazingly enough, this prints 3, not 2

    But this does print 2:

    $_ = 1; print 0+$_ + $_++;

      I can count as high as 7...

      sub r { $_[0] } # no-op? sub rr :lvalue { $_[0] } # no-op? $_ = 1; print ($_) + $_++; $_ = 1; print r($_) + $_++; $_ = 1; print $_ + $_++; $_ = 1; print $_ + ++$_; $_ = 1; print r(++$_) + r(++$_); $_ = 1; print ++$_ + ++$_; $_ = 1; print rr(++$_) + rr(++$_)++;

      (Requires Perl 5.16, though you can get up to 6 in Perl 5.10 and above.)

      Update: 0..10

      use v5.16; no v5.17; no strict 'subs'; sub r { $_[0] } # no-op? sub rr :lvalue { $_[0] } # no-op? $_ = 1; say ( $ ++ _ ) + $_++; $_ = 1; say ($_) + $_++; $_ = 1; say r($_) + $_++; $_ = 1; say $_ + $_++; $_ = 1; say $_ + ++$_; $_ = 1; say r(++$_) + r(++$_); $_ = 1; say ++$_ + ++$_; $_ = 1; say rr(++$_) + rr(++$_)++; $_ = 1; say ++rr(++$_) + rr(++$_); $_ = 1; say ++rr(++$_) + rr(++$_)++; $_ = 1; say ++rr(++$_) + ++rr(r(rr(++$_)++));
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re^5: $1 not "freezing" in an addition
by Anonymous Monk on Dec 14, 2012 at 16:14 UTC

    The problem occurs in... This is very hard to detect through static analysis of source code; it's probably not especially easy to detect at run-time either.

    Yes, I recognized that, but since PPI certainly detects  $1 and s/// as $1 and substitution operator, I see no reason perlcritic couldn't do the same, it uses PPI

    I also recognize the abilities of warnings/lint, they actually run the code and can detect this case as well -- sure it might be too much to ask from warnings (could be slow) , but its not too much to ask of lint :)

      I see no reason perlcritic couldn't do the same

      PPI won't descend into functions or methods and can't descend into XS. You can only get so far with static analysis when trying to find all modifications of a global variable at or below your current call site.

        PPI won't descend into functions or methods

        Doesn't stop perlcritic from doing the descending, or running B::Xref

        and can't descend into XS

        descending into XS is not insurmountable either

        You can only get so far with static analysis when trying to find all modifications of a global variable at or below your current call site.

        You can well get pretty far I tell you what

        who says we have to find them all? or even descend? or even all globals?

        I see no use case for relying on the behaviour we see here , so IMHO it seems like a very safe low level warning for every  $global ... func to be turned into  "$global" ... func, esp for $1

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-19 05:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found