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

I've got something in a .t along the lines of:
use strict; my %tests; BEGIN { %tests = ( # Stuff here ); } use Test::More tests => (keys(%tests) * 5 + 1); use_ok( Some::Class ); # Tests here

Is there a way to avoid having to declare %tests and then assign to %tests on another line?

------
We are the carpenters and bricklayers of the Information Age.

Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Replies are listed 'Best First'.
Re: BEGIN, strict, and variable assignment
by blokhead (Monsignor) on Mar 03, 2004 at 14:04 UTC
    If you put the number of tests into a plan command (not in the use Test::More statement), you don't need to have %tests available at BEGIN-time:
    use Test::More; my %tests = ( foo => .. bar => .. ); plan tests => (keys(%tests) * 5 + 1); # etc

    blokhead

Re: BEGIN, strict, and variable assignment
by TimToady (Parson) on Mar 03, 2004 at 16:44 UTC
    This doesn't do you any good right now, but the Perl 6 approach will be to add a trait that can initialize at the appropriate moment:
    my $var will begin("stuff"); # at BEGIN time my $var will check("stuff"); # at CHECK time our $var will init("stuff"); # at INIT time state $var will first("stuff"); # at FIRST use time my $var will enter("stuff"); # at block ENTRY time has $.var will build("stuff"); # at object init time
Re: BEGIN, strict, and variable assignment
by broquaint (Abbot) on Mar 03, 2004 at 13:53 UTC
    Is there a way to avoid having to declare %tests and then assign to %tests on another line?
    In a word 'no', or at least, not using lexicals. You could just use a package var however
    our %tests = ( ... ); ## or the more compatible, less line lean use vars '%tests'; %tests = ( ... );
    Or perhaps
    use Test::More tests => do { ... };
    HTH

    _________
    broquaint

      I don't see how any of these suggestions help in this situation. You still need to put the initialization into a BEGIN block (for the first two suggestions) which means the declaration needs to be separated from the initialization (except in the second case, where they are already separated) or else the variable won't be of any use outside of the BEGIN block.

      So to use any of the suggestions you made, you'd still need the declaration separated from the initialization.

      - tye        

        You're completely right, I really don't know what I was thinking. The above examples would need to be re-written as
        BEGIN { our %tests = ( ... ) } BEGIN { use vars '%tests'; %tests = ( ... ) }
        Which does indeed make them rather redundant suggestions. The suggestion from blokhead in Re: BEGIN, strict, and variable assignment looks to be the most sensible route to take.
        HTH

        _________
        broquaint

Re: BEGIN, strict, and variable assignment
by Anonymous Monk on Mar 03, 2004 at 16:04 UTC
    use vars::i '%tests' => 1, 2, 3; use Test::More tests => (keys(%tests) * 5 + 1); use_ok( Some::Class );