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

I thought perl changed back and forth as needed. I am trying to read a one byte integer from a file (which is indeed 18). Why am I getting these errors, and what is the proper way to do this?
read FILE, my $foo, 1; sprintf ('%u', $foo);
That produces:
Useless use of sprintf in void context at ./test.pl line 5. Argument "^R" isn't numeric in sprintf at ./test.pl line 5.

Replies are listed 'Best First'.
Re: I don't understand string versus numeric context
by Corion (Patriarch) on Jan 02, 2010 at 08:23 UTC

    sprintf does not output anything. Maybe you wanted printf? Also, the byte you read from the file needs to be converted to a number before you can output it via %u. Most likely you want ord or unpack for that.

Re: I don't understand string versus numeric context
by ikegami (Patriarch) on Jan 03, 2010 at 06:12 UTC

    The first warning is simple. sprintf is a function that returns a formatted string. Yet you simple discarded that string. That makes no sense, so you got a warning. Perhaps you wanted printf?

    "Numerical context" is a fancy way of saying the argument needs to be a number, and it will be coerced into one if necessary. It's usually very obvious when a number is required. For example, the arguments of addition must be numbers, and so does the argument for %u. Unfortunately, ^R doesn't look anything like a number, so a warning is issued ("isn't a number") and it's treated as zero. You seem to want the character's ordinal value.

    printf('%u', ord($foo));

    Perhaps you're from a C background where everything is a number. In Perl, it's more like everything is a string.

    # C Perl # ---- ---- printf('%u', 4); # 4 4 printf('%u', '4'); # 52 4 printf('%u', 0x12); # 18 18 printf('%u', '\x12'); # 18 0* * - warns "isn't numeric"
Re: I don't understand string versus numeric context
by morgon (Priest) on Jan 04, 2010 at 00:52 UTC
    I thought perl changed back and forth as needed.

    Think about it like this:

    A Perl-scalar is not something has only holds a single value, bit rather it consists of a number of "slots" that contain values for the different contexts in which the scalar can be used.

    Normally these values are "the same" and are computed by Perl as needed (e.g. a scalar containing a 4 in it's integer-slot will get the value "4" (a string!) in it's string-slot when used in a string-context), but not always.

    A good example for this are references. Observe:

    my $ref = []; # reference to an array my $a = $ref + 0; # force numeric context my $b = "$ref"; # force string-contect print "$a $b\n";
    As you can see in numeric context the value becomes the memory-address whereas in string-context it also shows the type of the reference "ARRAY(0x.....)".
A reply falls below the community's threshold of quality. You may see it by logging in.