Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Whatever happened to chomp?

by zentara (Archbishop)
on Dec 14, 2003 at 14:44 UTC ( #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
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? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2020-10-28 15:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (261 votes). Check out past polls.

    Notices?