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

Hi, I’m teaching myself Perl, and I have what I’m sure is an ultra-basic question that has something to do with the way numbers are evaluated, but I’m stumped.

This works:
print ".102.111.111 - ", .102.111.111; #prints ".102.111.111 - foo”

However, this doesn’t:

$num=102; print ".$num.111.111 - ", .$num.111.111; #prints ".102.111.111 - "

Could somebody explain how to get the second example to work? Thanks! :)

Replies are listed 'Best First'.
Re: Syntax Problem
by Fletch (Bishop) on Nov 19, 2001 at 19:18 UTC

    You've (accidentally) stumbled upon a new (5.6) feature. Quoting perldoc perldata: ... a literal of the form v1.20.300.4000 is parsed as a string composed of characters with the specified ordinals.

    print ".102.111.111 - ", .102.111.111; #prints ".102.111.111 - foo?

    This actually parses as:

    print ".102.111.111 - ", v0.102.111.111;

    Since it's a numeric literal with multiple `.'s, it's interpreted as a v-string (there's actually a hidden \0 there as the first character). In your second example, you don't have a literal with more than two dots, so it parses as print ".$num.111.111 - ",. $num . 111.111.

      I actually did know about that feature. :) I’d read about it and to experiment, I wanted to print out a table showing the ‘v-string notation, i.e. ‘.102.111.111’, and then the word/symbol that that would result in, i.e. ‘foo’. So I’d have a table like:
      =================
      v-string | output
      =================
       111     |   o
      -----------------
       112     |   p
      -----------------
      
      etc.

      The logical way to achieve this, seemed to be a loop, that printed a line, incremented the count by one, and then printed the next line. This would show me the code and the corresponding letter. However, since I can’t print out .$scalar. I’m not sure how to achieve this...

      Thanks again for your time.

        It'd be no different than your average run-of-the-mill ASCII chart.

Re: Syntax Problem
by Washizu (Scribe) on Nov 19, 2001 at 19:17 UTC

    The . operator is used for concatenation, so it might not play nice with your code when it is used with variables. It probably thinks you are trying to concatenate $num with something else.

    Try this:

    $f=102; $o=111; print (chr ($num) . chr ($num2) . chr ($num2));

    -----------------------------------
    Washizu
    The best offense is a good offense.

      Thank you very much. :)
Re: Syntax Problem
by mce (Curate) on Nov 19, 2001 at 20:23 UTC
    Hi,
    Your question is not related to the way numbers are evaluated, but the way print works. When you use a , in your print statement, it will evaluate it as an array.

    A good debugging tool is -O::Deparse -p. This will tell you where the parentheses are and will fill in the gaps when it passes through the precompiler. Your first statements evaluates as

    print '.102.111.111 - ', '0.102111.111';
    This is OK for you?

    First of all, it looks at 102.111.111 as: concatenate (0).102 and 111.111 (which are evaluated as digits). And than will make an array with 2 elements and passes this to print. And your second to

    print ("$num.111.111 - ").$num.111.111 ;

    So, you are concatinating a string with an array, which of course is not correct.
    Bottom line: Either use string concatination in print, or use arrays, and if you use both, use parentheses.
    use strict; use warnings; { local $,="."; #so you get the . 's print ".102.111.111 - ",102,111,111; my $num=102; print ".$num.111.111 - ",102,111,111; }
    Is one of the thousand possible solutions :-)

    Added laters: Damned, I must learn to type faster
    ---------------------------
    Dr. Mark Ceulemans
    Senior Consultant
    IT Masters, Belgium

Re: Syntax Problem
by count0 (Friar) on Nov 19, 2001 at 20:22 UTC
    Additionally, something that may help you out in situations like this is B::Deparse.
    It can show you how your code looks after perl interprets it, and how it will effectively run when compiled.

    Try, for example: perl -MO=Deparse -e 'print ".102.111.111 - ", .102.111.111;'
    and: perl -MO=Deparse -e '$num=102; print ".$num.111.111 - ", .$num.111.111;'
    ... for whatever it's worth.