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

Budding novice Perl Monk here :D I have this simple code, basically it just guesses a users number in a range, using a binary search.
use strict; use warnings; sub input { print($_[0]); return <STDIN>; } my $bottom = input("Enter the bottom most number: "); my $top = input("Enter the top most number: "); input("Hit enter once you have your number!"); my $middle = int(($bottom + $top) / 2); my $guesses = 1; while(1) { my $state = input("Is it " . $middle . "(l/h/t)?: "); chomp($state); if($state eq "t") { input("I Win! It took me " . $guesses . " guesses!"); last; } elsif($state eq "l") { $top = $middle; $middle = int(($top + $bottom) / 2); $guesses++; } elsif($state eq "h") { $bottom = $middle; $middle = int((($bottom + $top) / 2) + 0.5); $guesses++; } }
So, obviously I need to chomp my $state variable, or it doesn't work. However, I don't need to chomp my number variables($top,$bottom). I'm guessing Perl automagically chomps them when doing mathematical operations? Should I chomp them manually for style? Also, anything also "wrong", or could be done better with my code? Thanks, wise Perl Monks for your time!

Replies are listed 'Best First'.
Re: Chomping numbers?
by tobyink (Canon) on Jul 18, 2013 at 06:37 UTC

    davido has already explained how Perl converts strings to numbers which should answer your question. However, I'll point out an improvement to your input function:

    sub input { print @_; my $r = <STDIN>; chomp $r; return $r; }

    That way, the input function does your chomping for you, and you don't need to litter chomp calls throughout your code.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
      TYVM guys, has helped me to understand perl a lot better. Thanks.
Re: Chomping numbers?
by Anonymous Monk on Jul 18, 2013 at 03:28 UTC
      Answered my question perfectly, meant "for style", but I guess that's a stupid question, thanks much!

        Just keep in mind that Perl has a lot of DWIMery (Do What I Mean-ery) built-in. If you treat a string as a number, Perl will let you, and will attempt to return a reasonable value. If the string starts with a number, that number becomes the numeric value. If it doesn't start with a number, its numeric value will be zero. So "123abc" has a numeric value of 123. "abc123" has a numeric value of zero.

        So Perl is happy to convert "123\n" to the numeric value 123. However, sanitizing your input at the earliest possible point is generally good practice. Getting into the habit of calling chomp on your textual input as soon as you receive it will help you to avoid forgetting about it later, and then wondering why $input ne "Hello!" # True, because we forgot to chomp.


        Dave

        davido has the correct answer but for a visual representation of his explanation, you could always use Devel::Peek ...

        ... use Devel::Peek; .... print Dump( $bottom ); my $middle = int(($bottom + $top) / 2); print Dump( $bottom ); ....
        yields:
        Enter the bottom most number: 1 Enter the top most number: 10 Hit enter once you have your number! SV = PVMG(0x1009725b0) at 0x100847c98 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 0 PV = 0x10020a3f0 "1\n"\0 CUR = 2 LEN = 16 SV = PVMG(0x1009725b0) at 0x100847c98 REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 1 NV = 0 PV = 0x10020a3f0 "1\n"\0 CUR = 2 LEN = 16 Is it 5(l/h/t)?:

        and from this, you can see no chomping has taken place but perl's DWIMery has taken your scalar (SV) and taken the string value (PV) and set its integer value (IV).

        -derby