http://qs321.pair.com?node_id=766000

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

I have perl scalar variable "my $value1" and "my $value2" I read some values from in $value1 and $value2. Now The input can be both a string or integer. I need to compare $value1 and $value2. Now ideally if it is an integer or float then I should be doing IF($value1 == $value2). If it is a string then I should be doing IF($value1 eq $value2). Is there any way to differentiate between a string and integer or float for a perl scalar variable. Also The second IF (if ($value1 eq $value2)) works well for both integer and string. Is there any case where it fails to do that. Thanks for you reply Rahuketu Thanks Everybody for a quick reply. By your views I gather that I should write a strong regular expression to distinguish whether a given scalar is a string or integer(both -ve and +ve). <code>if($value =~ /regexp to match inetegers/){ $isInteger = 1; }else{ $isInteger = 0; }<\code> Thanks I will soon come up with a regexp to have your views.

Replies are listed 'Best First'.
Re: Is a integer or string.
by GrandFather (Saint) on May 25, 2009 at 10:54 UTC
    use strict; use warnings; my $str1 = "10"; my $str2 = "2"; print "$str1 lt $str2" if $str1 lt $str2;

    Prints:

    10 lt 2

    which may not be what you expect. If you need to be smart about which operator you should use then you may need to use a regular expression first to determine the nature of the two strings. Regexp::Common::number provides a set of expressions for dealing with numbers in various ways that may be of use to you.


    True laziness is hard work
Re: Is a integer or string.
by ww (Archbishop) on May 25, 2009 at 10:47 UTC
Re: Is a integer or string.
by salva (Canon) on May 25, 2009 at 11:27 UTC
    You can use a regular expresion to check that the string only contains digits or use the function looks_like_number($str) from Scalar::Util.
Re: Is a integer or string.
by toolic (Bishop) on May 25, 2009 at 12:15 UTC
Re: Is a integer or string.
by rovf (Priest) on May 25, 2009 at 11:46 UTC
    Is there any way to differentiate between a string and integer or float for a perl scalar variable.

    Is this adequate?

    use Scalar::Util qw(looks_like_number);

    -- 
    Ronald Fischer <ynnor@mm.st>
Re: Is a integer or string.
by irah (Pilgrim) on May 25, 2009 at 10:36 UTC

    There is no difference in Perl scalar variable in case of string and integer. If the value of the variable have only numbers, it treat as integer and it required "==" for comparison. If any alphabets available in variable, it treat as, string.

    Is there any case where it fails?

    In all places, the second condition will work.

    From perlintro man page,

    Scalar values can be strings, integers or floating point numbers, and Perl will automatically convert between them as required.

      perl -e "print 'Think again.' if ('1' == '1.0') && !('1' eq '1.0')"
Re: Is a integer or string.
by ikegami (Patriarch) on May 25, 2009 at 19:32 UTC
    my $equal = $x eq $y || eval { use warnings FATAL => qw( numeric ); $x == $y };

    Doesn't check if the either of the values are undef

Re: Is a integer or string.
by Marshall (Canon) on May 26, 2009 at 02:46 UTC
    I read through the suggestions below and they are great ones!

    To summarize:
    a)everything in Perl is a string until used in a numeric context.
    b)Never, ever compare float values for equality in any languag!
    c)If you compare $num1 < $num2 and both $num1 and $num2 can be converted to a number, then is is fine! If that is not true, then that's a problem.

    I present here one of my subs that can compare text or numbers. This is not "perfect" and there are problems with say the "-" sign, but is a general idea.

    sub alpha_num_cmp { my($a, $b) = @_; if (( $a =~ m/\D/) || ($b =~ m/\D/)) { #look for a non-digit return ($a cmp $b); #if so, then use string compare } return ($a <=> $b); #otherwise straight numeric comparison }
Re: Is a integer or string.
by gam3 (Curate) on May 25, 2009 at 19:11 UTC
    Here is a little piece of code you might find informative:
    #!/usr/bin/perl $a = shift; $b = shift; #for intergers only if ($a =~ /^\d+$/ && $b =~ /^\d+$/) { printf "$a == $b (%s)\n", $a == $b ? "yes" : "no"; } else { printf "$a eq $b (%s)\n", $a eq $b ? "yes" : "no"; } #or for floating point numbers if ($a =~ /^\d+(\.\d?)?$/ && $b =~ /^\d+(\.\d?)$/) { printf "$a == $b (%s)\n", $a == $b ? "yes" : "no"; } else { printf "$a eq $b (%s)\n", $a eq $b ? "yes" : "no"; }
    > perl diff 1 1.
    1 eq 1. (no)
    1 == 1. (yes)
    
    This still needs work, as it does not see that 1e2 == 100.
    
    
    
    -- gam3
    A picture is worth a thousand words, but takes 200K.
Re: Is a integer or string.
by targetsmart (Curate) on May 25, 2009 at 10:33 UTC
    characters enclosed in "" or '' make a string, numbers otherwise.(other types also exist, but in this case we take only these two)
    a string as well used as a number in some cases, and a number can be used as a string in some cases.
    in your example, you used ==, in that case, the $value1 and $value2 even though it is a string it will be converted to relevant numbers and then it will be compared.
    in case of eq, there will only be string comparison even you compare numbers.
    'use strict' pragma can warn/help in those scenarios where you do == on string, etc. but by default perl converts your values internally according to the operator or the area of use

    so this is how perl works, the programmer in his design has to differentiate and do the code appropriately.


    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
Re: Is a integer or string.
by FloydATC (Deacon) on May 25, 2009 at 11:20 UTC
    I usually just do an if ($n == int($n)) to check for numberness. Maybe there's a better way, I dunno... (obviously this doesn't work with floats)
      perl -e "print 'You should not.' if ('12ijlijlij' == int('12ihjlijlij'))"

      eq would work, however.

        No, int('12ihjlijlij') == 12, which is != '12ijlijlij'... uh.. or not.. Nevermind :o)