Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

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

by Anonymous Monk
on Dec 14, 2012 at 14:30 UTC ( [id://1008844]=note: print w/replies, xml ) Need Help??


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

update: after tobyinks 3rd update I see that order of operations plays a role, I still think you should perlbug it, because at least the perlop, and warnings, need to warn more about this ...

Documenting Auto-increment and Auto-decrement is great, but needs to warn about MORE, like this case, or  foo($1,$2)  <c>foo("$1","$2")

Even B::Lint doesn't warn about it

B::Concise shows no difference between the two

Even the mighty perlcritic doesn't warn about undefined behaviour

But I actually knew about this and forgot

warnings/lint/critic need to recognize and warn me cause I'll probably forget :)

It ought to be easy to recognize an unquoted $1 as a function argument and issue a warning , at least for perlcritic -- if that concise output is any indication, lint might be slightly harder

Maybe perltrap/Common Perl Pitfalls could also use some updating

 

This part below written before your butterjunkeffect update, on the approach to solving this problem

Ick :) Um, do you really want to find the cause, or do you want a better way to write it?

I'm not inclined to try debugging a program that hacks a tree as a string, I'm inclined to create a tree first (say an array of array or Tree ) and then navigate (calculate distance)

update: tobyink is probably right as to cause

Those rosalind newick trees could be drawn with ascii Dumping trees to a console.

Replies are listed 'Best First'.
Re^4: $1 not "freezing" in an addition
by tobyink (Canon) on Dec 14, 2012 at 14:57 UTC

    "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'

      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'

      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.

Log In?
Username:
Password:

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

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

    No recent polls found