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

Hi, I was wondering if there was a way to determine the type of a var in Perl ( number, string, array, etc). I'm very confused about the pack/unpack documentation and I was hoping to use the above to figure out exactly what those functions returned. Thanx jra

Replies are listed 'Best First'.
Re: Determine type of variable
by Ovid (Cardinal) on Apr 09, 2002 at 17:59 UTC

    The type of variable (scalar, array, or hash), is typically determined by the sigil attached to the front of the variable name ($,@, and %, respectively). However, if you're looking for traditional data types like int, float, char, etc, you need to start using regular expresssions to determine that. Perl's type system is based around data structures, not data types.

    As a side note, if you're not sure what data type a variable is, you probably have a deeper programming issue that you should probably look at. Typically it should be obvious what data type you're dealing with. For example, if you are using a C-style for loop, you probably have an integer.

    for ( my $i = 0; $i < 10; $i++ ) { # do stuff }

    However, the nifty thing about the above snippet is this: it doesn't matter what data type $i is. Yes, there are cases where this is important, but most of the time, Perl allows you to focus on the actual problem you're trying to solve (how can I import this banking data?) instead of focusing on the minutia (should this be a short or a long?). This is a big win with Perl, but it's a tough concept for many to get used to.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Determine type of variable
by vladb (Vicar) on Apr 09, 2002 at 18:01 UTC
    You can always try the ref() command to figure out whether the variable you are dealing with is an array, a hash, or a scalar. Of course, this method works on a reference to the actual variable. Say like this:
    my %hash = (foo => bar); my @arr = (1); my $var = \%hash; my $var1 = \@arr; my $var2 = 2; print ref $var; print ref $var1; print ref $var2;
    Will print:
    HASH ARRAY
    * the last line is '' for 'not reference'.

    I'm not sure if you really want to go any further from this and actually attempt to determin whether a variable is a string or an integer (or float). For that you could use regular expressions..
    my $num = 15; if ($num =~ /^[+-]?\d+$/) { print "Dealing with an integer\n"; }
    You could also play around with other forms of the match to distinct between float and integer values. However, in many cases when anyone has to go as far as to having to determine precise type of a variable, there's a big chance his/her code is wrong.

    "There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith
Re: Determine type of variable
by Fletch (Bishop) on Apr 09, 2002 at 18:01 UTC

    In perl in general, you don't worry about the type of values. Use it and perl will (in most cases) do the right thing. pack and unpack are intended for manipulating raw values (as you would typically use in C). As for the type of variables, that's what the initial sigil is for ($@%*& et al).

(tye)Re: Determine type of variable
by tye (Sage) on Apr 10, 2002 at 20:32 UTC

    You can think of Perl scalars as just being strings. Using any of these strings in a place that wants a numeric value will cause the string to (try to) be interpretted as a decimal numeral. There are some details beyond this that almost never matter.

    pack creates a "raw" string of bytes from multiple input values. unpack creates multiple output values from a "raw" string of bytes.

    The documentation for pack and unpack are terse enough that I usually have to resort to experimentation to flush out the details even though I am very familiar with them already. "perl -de 0" and its "x" command are very useful for this.

    So most of the pack formats take a string holding the decimal representation of a number, and encode that number into the "raw" format mentioned in the description of that format character, returning the "packed" string that holds the bytes of that "raw-formatted" data concatenated together.

    The exceptions are the formats that mention "string" in their description along with "x", "X", and "@".

    So:

    > perl -de 0 [...] DB<1> x pack("C","65") 0 'A' DB<2> x unpack("C*","\0\cA A") # yields ("0","1","32","65") 0 0 1 1 2 32 3 65 DB<3> x pack("n","1") 0 "\c@\cA"
    where I've put quotes around many of the "numbers" even though they aren't required just to emphasize that Perl, to a great extent, simply treats them as strings that happen to contain valid decimal representations for numbers.

            - tye (but my friends call me "Tye")