Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Readonly vars as input to other modules

by cmilfo (Hermit)
on Aug 21, 2008 at 20:33 UTC ( [id://705979]=perlquestion: print w/replies, xml ) Need Help??

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

I would like to do something like this as the top of my program to allow the log level and log file for Log::StdLog to be specified in the configuration file.

use Config::Std; use Readonly; Readonly my $DEFAULT_LOG_LEVEL => q{warn}; Readonly my $DEFAULT_LOG_FILE => $PROGRAM_NAME . q{.log}; Readonly my $DEFAULT_CONFIG_FILE => $PROGRAM_NAME . q{.cfg}; read_config $DEFAULT_CONFIG_FILE => my %config; use Log::StdLog { level => ($config{'log'}{'level'} || $DEFAULT_LOG_LEVEL), file => ($config{'log'}{'file' } || $DEFAULT_LOG_FILE ) };

The problem I'm running into is that I can't pass the Readonly variables to Log::StdLog since the use happens before the Readonly calls. I can solve the problem by using a BEGIN block (see below), but I'd like a way to do it that does not have the Readonly variables listed out twice.

my $EMPTY_STRING ; my $DEFAULT_LOG_LEVEL ; my $DEFAULT_LOG_FILE ; my $DEFAULT_CONFIG_FILE ; my %config = (); use Config::Std; use Readonly; BEGIN { Readonly $EMPTY_STRING => q{}; Readonly $DEFAULT_LOG_LEVEL => q{warn}; Readonly $DEFAULT_LOG_FILE => $PROGRAM_NAME . q{.log}; Readonly $DEFAULT_CONFIG_FILE => $PROGRAM_NAME . q{.cfg}; read_config $DEFAULT_CONFIG_FILE => %config; } use Log::StdLog { level => ($config{'log'}{'level'} || $DEFAULT_LOG_LEVEL), file => ($config{'log'}{'file' } || $DEFAULT_LOG_FILE ) };

Ideas?

One route I did try was using the BEGIN block for the read_config line (for DEFAULT_CONFIG_FILE) and then using a require/import for the Log::StdLog call. The problem was STDLOG was not set up for use.

Thank you for the input!

Casey

Replies are listed 'Best First'.
Re: Readonly vars as input to other modules
by moritz (Cardinal) on Aug 21, 2008 at 20:38 UTC
    Instead of promoting the the definitions of the constants to compile time, you can instead load the module at run time:
    use Config::Std; use Readonly; Readonly my $DEFAULT_LOG_LEVEL => q{warn}; Readonly my $DEFAULT_LOG_FILE => $PROGRAM_NAME . q{.log}; Readonly my $DEFAULT_CONFIG_FILE => $PROGRAM_NAME . q{.cfg}; read_config $DEFAULT_CONFIG_FILE => my %config; require Log::StdLog; Log::StdLog->import({ level => ($config{'log'}{'level'} || $DEFAULT_LOG_LEVEL), file => ($config{'log'}{'file' } || $DEFAULT_LOG_FILE ) });

    Note that this also means that import of various subs and symbols happens at run time, so it might or might not work for you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://705979]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2024-04-18 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found