Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Odd behaviour of chomp()

by sundialsvc4 (Abbot)
on Oct 20, 2015 at 12:30 UTC ( #1145424=note: print w/replies, xml ) Need Help??


in reply to Odd behaviour of chomp()

I have my doubts as to whether all of these bugs have actually been found and fixed in Perl.   (The result "0" is simply wrong, whether a flawed optimizer did it or not.)   There are many functions in Perl, like chomp, which were plainly designed to be used “in one ‘right’ way,” and which in however-many releases have never worked properly in any other way.   If the function (like chomp) is designed to “do something to” its right-hand side, i.e. treating the argument as a so-called “lvalue,” you should never in Perl use that same variable as an lvalue, as you did in this case by using an assignment statement.   It’s Forrest Gump’s box of chocolates:   you never know what you’re gonna get.

Perl’s lineage and inspiration definitely draws from awk, and it still shows, especially in its use of perlvars, particularly "$_".   There’s a whole lot of “implied context” going on here, and from a pure language-design standpoint that means ambiguity, and that means trouble.   For example, consider the following three Perl one-liners, shown with their output on Perl 5.19:

$ perl -e '$_="foo\n"; chomp; print "$_\n";' foo $ perl -e '$_="foo\n"; $_=chomp; print "$_\n";' 1 $ perl -e '$_="foo\n"; $_=chomp($_); print "$_\n";' 1 # (tpyo correctud) $ perl -e 'my $foo = "foo\n"; $foo = chomp($foo); print "$foo\n";' 0

The first case is what is used 99% of the time, because “the function is an English verb.”   Effectively, it is an imperative statement.   You want to “chomp” a string, and it does.   If you use the implied-variable "$_" it also produces the documented result, even though nobody actually does that.   If you use your own variable, it does not.   Given that you probably don’t have the latest Perl installed on your machine and probably can’t change it, you have to code-around bugs like these.   If the function is a verb, use it as a verb only.

Replies are listed 'Best First'.
Re^2: Odd behaviour of chomp()
by Laurent_R (Canon) on Oct 20, 2015 at 15:48 UTC
    To me, all the four examples you provide return a perfectly valid result, or at least exactly the result I would expect. So nothing wrong with them IMHO.

    Contrary to the OP's question, which really appears to be displaying an actual bug.

    Update: Of course, I meant: all the four examples as originally provided by sundialsvc4 return a perfectly valid result. The last example, as it stand now, does no longer return a valid result, but that example was changed by its author almost 24 hours after I posted my comment above. Fortunately, hippo provided a copy-and-paste of the last example as it was originally posted and as it was when I answered, thus showing that this comment was right at the time.

      Many thanks to you all!

      Conclusions like "It's a bug" or "It appears to be a bug" are perfectly ok for me ;-)

      The corrected example merely repeats the originally reported bug.

      Certainly won’t be the first time that an optimizer produced incorrect results.   Delphi-6 had a similar bug, too, that vexed me for a time.   It is almost a general rule-of-thumb that, if calling any function that modifies one of its inputs, do not assign the result back to the same variable.   Optimizers like to remove “unnecessary” loads and stores, and they like to re-order things, and it becomes a gray area.   Just put the result down someplace else.

Re^2: Odd behaviour of chomp()
by hippo (Canon) on Oct 20, 2015 at 13:36 UTC
    $ perl -e 'my $v = "foo\n"; $foo = chomp($foo); print "$foo\n";' 0

    What would you expect this to print given that $foo is undefined when chomped? I consider this output to be entirely the correct result of that code. Why would you have it differ and in what way?

      Oops, a tpyo.
Re^2: Odd behaviour of chomp()
by shmem (Chancellor) on Oct 27, 2015 at 08:28 UTC

    Your post doesn't add anything new to this thread. Mine adds a correction to your last paragraph

    The first case is what is used 99% of the time, because “the function is an English verb.” Effectively, it is an imperative statement. You want to “chomp” a string, and it does. If you use the implied-variable "$_" it also produces the documented result, even though nobody actually does that. If you use your own variable, it does not. Given that you probably don’t have the latest Perl installed on your machine and probably can’t change it, you have to code-around bugs like these. If the function is a verb, use it as a verb only.

    which is wrong. "If you use your own variable, it does not." Of course it does! It is perfectly ok to use chomp on "your own variable." It would be interesting to find why assignment to $_ works, but fails with $line - but you don't even try, you just post the bizarre statement that this happens because “the function is an English verb.”

    And then
    If the function is a verb, use it as a verb only.

    Wait, what?!? Where did you get that from? Where in the perl docs is stated, that "English Verbs" only behave correctly on "implied $_"? So we should never use a "own variable" with print,split, shift, unshift and so on?

    See, sundialsvc4, these assertions which you just pull out from your pool of speculations, not knowledge, are what many monks here annoy and what they detest and condemn as misleading, specially to newbies, even if they make for a good laugh for experienced perlers.

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2019-07-15 18:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?