Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the data type of a scalar variable in Perl

Tags:

perl

I have a function which accepts an input from the user. The input maybe an integer, a float or a string. I have three overloaded functions which should be called based on the DATA TYPE of the entered data. For example, if the user enters an integer (say 100), the function having integer parameter should be called. If the user enters a string (say "100") the function having the string parameter should be called.

So I need to find out the data type of the entered data. With regular expressions I am able to distinguish between an integer and a float (since I just need to find out the type, I wont prefer using the library provided at cpan.org), but I am not able to figure out how to differentiate an integer from a string. Perl treats "100" and 100 as the same? Is there any way to work around this problem?

like image 667
letsc Avatar asked Jun 15 '11 17:06

letsc


2 Answers

From perldoc perldata:

Scalars aren’t necessarily one thing or another. There’s no place to declare a scalar variable to be of type "string", type "number", type "reference", or anything else. Because of the automatic conversion of scalars, operations that return scalars don’t need to care (and in fact, cannot care) whether their caller is looking for a string, a number, or a reference. Perl is a contextually polymorphic language whose scalars can be strings, numbers, or references (which includes objects). Although strings and numbers are considered pretty much the same thing for nearly all purposes, references are strongly-typed, uncastable pointers with builtin reference-counting and destructor invocation.

So for integer scalars, you'll just need to decide ahead of time how you want to process them. Perl will cheerfully convert from a number to a string or vice versa depending on the context.

like image 58
Brian Gerard Avatar answered Nov 07 '22 02:11

Brian Gerard


Perl does not make a useful distinction between numbers and string representations of those numbers. Your script should not either. You could write some code to differentiate between things that look like integers and floats, but the only way to know if it is a string is if the scalar does not look like an integer or a float.

Here is a simple routine that will return int, rat, or str for its argument. Note that 100 and '100' are both int, but something like 'asdf' will be str.

use Scalar::Util 'looks_like_number';
sub guess_type {
    looks_like_number($_[0]) ? $_[0] =~ /\D/ ? 'rat' : 'int' : 'str'
}

say guess_type 1;      # int
say guess_type "1";    # int
say guess_type 1.1;    # rat
say guess_type 'asdf'; # str

Since you are working on mapping Perl variables to C functions, you could write something like this:

sub myfunction {
    if (looks_like_number($_[0]) {
        if ($_[0] =~ /\D/) {C_float($_[0])}
        else               {  C_int($_[0])}
    }
    else {C_string($_[0])}
 }

Which should "do the right thing" when given a Perl scalar. You may also want to add in a check to see if the argument is a reference, and then handle that case differently.

like image 42
Eric Strom Avatar answered Nov 07 '22 03:11

Eric Strom