Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Whatever happened to chomp?

by zentara (Archbishop)
on Dec 14, 2003 at 14:44 UTC ( [id://314638]=perlquestion: print w/replies, xml ) Need Help??

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

I learned from some older books, and part of the conventional wisdom was to chomp all input, but I was looking at an example today, and it looks like some kind of "autochomp" is occurring. For instance, in the following code, $data clearly matches 2, but the 2 still has a newline on it, since when I print it without a newline, the newline is there. So why does "$data == 2" match? I would expect the hidden newline to interfere. I would expect "$data =~ /2/" to match; but == matching dosn't seem right to me. What am I missing?
#!/usr/bin/perl use strict; use warnings; while (my $data = <DATA>) { #chomp $data; print $data; if ($data == 2){print "->got 2\n"} } print "Enter a 2\n"; my $input = <>; if ($input == 2){print "->got 2\n"} __DATA__ 1 2 3 4

Replies are listed 'Best First'.
Re: Whatever happened to chomp?
by jsprat (Curate) on Dec 14, 2003 at 14:57 UTC
    2 is a number, and perl is trying to DWYM with the numerical compare (==). Try putting
    one two three four

    in __DATA__, and

    change the conditional to if ($data eq '2'). Now see what effect chomp has...

    Update: Struck out the data section and added bit about numerical compare to the first sentence. I shouldn't have included the red herring (one, two, three). The original point was supposed to be that perl will treat a variable like a number in numerical context (== instead of eq).

      2 is a number.

      No, 2 could be a number or a string base on the context as how you use it. A better answer is to point out what he really misunderstood: the context.

      It is pretty straight to simply change == to eq, and quot 2:

      use Tk; use Tk::NoteBook; use strict; use warnings; use strict; use warnings; while (my $data = <DATA>) { chomp $data; print $data; if ($data eq "2"){print "->got 2\n"} } print "Enter a 2\n"; my $input = <>; chomp $input; if ($input eq "2"){print "->got 2\n"} __DATA__ 1 2 3 4
Re: Whatever happened to chomp?
by Limbic~Region (Chancellor) on Dec 14, 2003 at 14:58 UTC
    zentara,
    I am pretty sure this has nothing to do with chomp, but with Perl always trying to DWYM. Reading perldoc perlop I see that == will return true if the two arguments are numerically equal. Consider the following:
    perl -e 'print "yeah\n" if "p2p" == "f2b"'
    I am not sure if the behavior is well documented though.

    Cheers - L~R

      L~R:
      perl -e "use warnings; print qq{yeah$/} if 'p2p' == 'f2b'; print 'p2p' + + 0" Argument "f2b" isn't numeric in numeric eq (==) at -e line 1. Argument "p2p" isn't numeric in numeric eq (==) at -e line 1. Argument "p2p" isn't numeric in addition (+) at -e line 1. yeah 0
      Non-numeric arguments are treated as 0 in numeric operations. == is a numeric comparision operator, its string equivalent being eq.
      I remember reading somewhere (maybe the camel or llama book) that numbers in string representations may have a newline character after them, which would explain why you don't need to chomp. I couldn't find the passage, though.
      Cheers,
      CombatSquirrel.
      Entropy is the tendency of everything going to hell.

        You are thinking of '3bar' == '3foo'. It doesn't matter what is after the number, the numeric value of a string with leading digits is the decimal value of those digits. Strings without leading digits are equal to zero.

        CombatSquirrel,
        The missing warnings and strictures were intentional. I was trying to demonstrate the extent Perl would go to try and DWYM. I guess I should have been more clear - thanks.
        perl -e 'print "yeah\n" if "3p" == "f2b"'
        Cheers - L~R
Re: Whatever happened to chomp?
by derby (Abbot) on Dec 14, 2003 at 15:33 UTC
    As others have pointed out, it is perl DWYM but exactly how does it do that? Well if you look at perl internals, a scalar value can be a string, an integer or a double (or another scalar). By context, it determines which value to use. In a numeric context (==), it will use one of the numeric (integer or double), in a string context, (eq), the string value.

    Check this out:

    #!/usr/bin/perl use strict; use warnings; use Devel::Peek qw( Dump ); while (my $data = <DATA>) { chomp $data; print Dump( $data ); if ($data == 2){print "->got 2\n"} } print "Enter a 2\n"; my $input = <>; print Dump( $input ); if ($input == 2){print "->got 2\n"} __DATA__ 1 2 3 4

    -derby

Re: Whatever happened to chomp?
by ysth (Canon) on Dec 14, 2003 at 17:01 UTC
    In numeric context, perl will not warn if a number matches something like:
    /^(?: 0\ but\ true | (?: \s* # leading spaces ignored [-+]? # optional sign (?: (?i: inf|infinity|nan ) | # any case of inf or nan (?: \d+ (?:\.\d*)? | \.\d+ ) # digits, optional . (?: [eE] [-+]? \d+ )? # optional exponent ) \s* # trailing spaces (including "\n") ) )\z /x;
    The case you are hitting is the "trailing spaces" being silently ignored.

    If compiled with numeric locale support, either . or the locale's radix will work.

Re: Whatever happened to chomp?
by Zaxo (Archbishop) on Dec 14, 2003 at 23:02 UTC

    In numeric context, perl accepts numbers in a variable until it runs out of them:

    $ perl -e' $_ = "123abc"; print 0+$_, $/' 123 $

    After Compline,
    Zaxo

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-25 21:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found