Carl-Joseph has asked for the wisdom of the Perl Monks concerning the following question:

On Camel2, p122, it explains that formats "are declared rather than executed, so they may occur at any point in your program." I read that and decided to place my formats at the end of my script.

However, I discovered that where I could place a format seems to be constrained by the scope of the variables on the argument line.

If the vars on the argument line are global, I can put the format anywhere. But strict doesn't like global vars (and neither do I).

I remembered reading somewhere that I could think of a hash as providing a mini-namespace, so I declared a hash using <KBD>my</KBD> at the top of my script. I use values from the hash as args to the format. (See the code below.) That way, I can limit the number of "top-level" <KBD>my</KBD> variables.

However, I'm not really happy with this solution either. I'm wondering if there's actually a clever way to get around this problem.

Thanks,

Carl-Joseph

use strict; # # Hash to act as a "mini-namespace" for the format # my %GRID; &printit( "Line 1", "Total Income", "\$5.00" ); sub printit { my( $prefix_text, $left_text, $right_text ) = @_; ( $GRID{"prefix_text"}, $GRID{"left_text"}, $GRID{"right_text"} ) = + ( $prefix_text, $left_text, $right_text ); $~ = "GRID"; write; } # # Placing my formats here. # format GRID = -------------------------------------------------------- @>>>: @<<<<<<<<<<<<<<<<<<< | @<<<<<<<<<<<<<<<<<<< $GRID{"prefix_text"}, $GRID{"left_text"}, $GRID{"right_text"}; -------------------------------------------------------- . __END__

Replies are listed 'Best First'.
Re: Format with Args at End of Script
by extremely (Priest) on Oct 03, 2000 at 04:06 UTC
    Re-updated with even fewer typos!

    You could store the format in a string like thus:

    use vars qw( %format ); BEGIN { $format{GRID} = <<'FMT1'; format GRID = -------------------------------------------------------- @>>>: @<<<<<<<<<<<<<<<<<<< | @<<<<<<<<<<<<<<<<<<< $prefix_text, $left_text, $right_text -------------------------------------------------------- . FMT1 } #look ma, three different block closing methods all #in a column down the left side, yay!

    using the local variable names you prefer and putting the format all the way at the bottom as you prefer. You do wind up with one global format storing hash but oh well.

    Then when in scope with the variables you are using in the format you do this:

    eval $format{GRID}; die "Oops eval wasn't happy with $format{GRID},\n$@" if $@;

    Lordy it's scary stuff and if you have to eval inside a loop it will suck more but it gets what you want and is sort recommended in the Camel2 on pg. 126-7.

    --
    $you = new YOU;
    honk() if $you->love(perl)

Re: Format with Args at End of Script
by merlyn (Sage) on Oct 03, 2000 at 04:08 UTC
    I may be recalling incorrectly, but I think one of the bugfixes was to make formats respect lexical variables, so that you could turn your subroutine into the following:
    sub printit { my( $prefix_text, $left_text, $right_text ) = @_; $~ = "GRID"; write; format GRID = -------------------------------------------------------- @>>>: @<<<<<<<<<<<<<<<<<<< | @<<<<<<<<<<<<<<<<<<< $prefix_text, $left_text, $right_text -------------------------------------------------------- . }
    If that doesn't work, then I recall wrong. {grin}

    -- Randal L. Schwartz, Perl hacker

Re: Format with Args at End of Script
by runrig (Abbot) on Oct 03, 2000 at 02:13 UTC
    You could use '$_' as a hash reference. Set $_->{"prefix_text"}=$prefix_text, etc. and use that in the format.
    Or just use %_, (i.e. set $_{"prefix_text}, etc.), but I'm not sure if %_ is documented anywhere if that matters.