in reply to How to set a set of our and @EXPORT variables concisely?

I'd just go with the use vars approach. Your only mistake was not initializing your variables at compile time. This is a very common mistake and is often misdiagnosed.

use base qw( Exporter ); our @EXPORT; BEGIN { @EXPORT= qw( $MC_CONFIG_DBI_DRIVER $MC_CONFIG_DB_NAME $MC_CONFIG_DB_USER $MC_CONFIG_DB_PWD $MC_CONFIG_FILE $MC_CONFIG_FEED_LOGS $MC_CONFIG_ARCHIVE_LOGS ); } use vars @EXPORT;

You see, in your original code, the my @var declares the @var array at compile time but doesn't initialize it (fill it with values) until run time. But use vars happens at compile time so you end up passing use vars an empty array.

The our trick can only half work since the "create lexical alias" part of our only has effect until the end of the current scope. So your map might be able to declare a bunch of package globals for you but the lexical aliases to them would disappear at the end of the enclosing block (either the block in the map statement or the next one -- I'd have to test to say for sure). But to get that to work probably requires eval, which also forces an enclosing block so there is no way to script doing our on a list of variable names unless you want to enclose almost your entire module inside an extra eval.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: How to set a set of our and @EXPORT variables concisely?
by princepawn (Parson) on Nov 21, 2000 at 19:03 UTC
    There we go! Thanks tye. I knew it could be done and thank you for showing how it can be done.

    The only problem is: supposedly use vars is deprecated so this example must use our to remain viable in years to come. So, to use our, I guess we have to use eval

    use base qw( Exporter ); our @EXPORT; BEGIN { @EXPORT= qw( $MC_CONFIG_DBI_DRIVER $MC_CONFIG_DB_NAME $MC_CONFIG_DB_USER $MC_CONFIG_DB_PWD $MC_CONFIG_FILE $MC_CONFIG_FEED_LOGS $MC_CONFIG_ARCHIVE_LOGS ); eval "our $_;" for @EXPORT; }

      But as you found out, the our declares a global variable but the lexical alias to it goes away when you leave the enclosing scope (either the eval or the BEGIN, I'm not absolutely sure which and it would be hard to test but it doesn't really matter here).

      So you still have to fully qualify the variable name in the rest of your script. As I already said, there is no good fix for this other than use vars.

      I see no mention of use vars being depricated. The closest thing I found was "NOTE: The functionality provided by this pragma has been superseded by `our' declarations". Since using our makes your script not work on even very slightly old versions of Perl, there will still be many scripts using use vars for quite a long time. So deleting vars.pm would be quite stupid of the perl porters, especially since it would be impossible to write version-portable code via something like:

      BEGIN { if( 5.6 < $^V ) { eval 'our $x; 1' or die $@; } else { require vars; vars->import( '$x' ); } }
      for the exact same reasons that our doesn't work for your code.

      So don't worry about vars.pm going away until you actually read that is has been deprecated (not "superseded").

      Note that our makes for slightly more efficient code, and this is probably why the use vars documentation points you in that direction a little strongly. This efficiency is pretty trivial so I wouldn't sacrifice maintainability (by having two lists of variables to keep in sync) for it.

              - tye (but my friends call me "Tye")
    A reply falls below the community's threshold of quality. You may see it by logging in.