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

hello monks,
wanting to try out the format feature I made a format to print a sudoku table, but although the table is printed as expected, strange warnings pop up when using warnings, and it don't even run under strict, what I'm missing here ?

the code:
use strict; use warnings; my (@s,@m); $s[0] = "123456789"; $s[1] = "987654321"; $s[2] = "123456789"; $s[3] = "987654321"; $s[4] = "123456789"; $s[5] = "987654321"; $s[6] = "123456789"; $s[7] = "987654321"; $s[8] = "123456789"; push @{$m[$_]}, split //,$s[$_] for(0..$#s); # make the matrix my(@f1,@f2,@f3); @f1 = ($m[0],$m[1],$m[2]); # divide @f2 = ($m[3],$m[4],$m[5]); # into groups @f3 = ($m[6],$m[7],$m[8]); # to print format = +-----------------------+ | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f1} |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f2} |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f3} +-----------------------+ . write;
try remove strict to see the output.

Replies are listed 'Best First'.
Re: format issues
by shmem (Chancellor) on Dec 04, 2009 at 14:39 UTC
    and it don't even run under strict, what I'm missing here ?

    You are missing that the ~~ tells to repeat shifting @f1 even after it is empty. Trying to build yet another line after the third, shift @f1 returns an undefined value, which then - alas, cannot be dereferenced.

    One solution:

    my $foo = [('') x 9]; format = +-----------------------+ | @ @ @ | @ @ @ | @ @ @ |~~ @{ shift @f1 || $foo } |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{ shift @f2 || $foo } |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{ shift @f3 || $foo } +-----------------------+ . write;

    You could also push the array reference filled with empty elements ($foo) onto @f1, @f2 and @f3.

    my $foo = [('') x 9]; push @$_, $foo for \@f1,\@f2,\@f3; format = +-----------------------+ | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f1} |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f2} |-------+-------+-------| | @ @ @ | @ @ @ | @ @ @ |~~ @{shift @f3} +-----------------------+ . write;
      I see, thanks !

      so ~~ stops when there is a empty line right ? something like :
      @f1 = ($foo,$m[0],$m[1],$m[2]);
      won't get printed at all,

        Yes. From perlform:

        ~~ repeat line until all fields are exhausted

        Note: fields, not container of field arrays.

Re: format issues
by toolic (Bishop) on Dec 04, 2009 at 15:23 UTC
    shmem has answered your specific question, but you could also consider some alternatives.

    Several monks have recommended Perl6::Form as a viable replacement for format.

    Whenever I think of displaying tables, I reach for Text::Table:

    use strict; use warnings; use Text::Table; my @s; $s[0] = "123456789"; $s[1] = "987654321"; $s[2] = "123456789"; $s[3] = "987654321"; $s[4] = "123456789"; $s[5] = "987654321"; $s[6] = "123456789"; $s[7] = "987654321"; $s[8] = "123456789"; my $tb = Text::Table->new( \'| ', '', \'| ', '', \'| ', '', \' |' ); for (@s) { my @grps = $_ =~ /(\d{3})/g; map { s/(.)/$1 /g } @grps; # add space after each digit $tb->add(@grps); } my $rule = $tb->rule(qw/- +/); my @rows = $tb->body(); print $rule; my $r = 1; for (@rows) { print $_; print $rule unless $r % 3; $r++; } __END__ +-------+-------+--------+ | 1 2 3 | 4 5 6 | 7 8 9 | | 9 8 7 | 6 5 4 | 3 2 1 | | 1 2 3 | 4 5 6 | 7 8 9 | +-------+-------+--------+ | 9 8 7 | 6 5 4 | 3 2 1 | | 1 2 3 | 4 5 6 | 7 8 9 | | 9 8 7 | 6 5 4 | 3 2 1 | +-------+-------+--------+ | 1 2 3 | 4 5 6 | 7 8 9 | | 9 8 7 | 6 5 4 | 3 2 1 | | 1 2 3 | 4 5 6 | 7 8 9 | +-------+-------+--------+
Re: format issues
by biohisham (Priest) on Dec 04, 2009 at 15:03 UTC