http://www.perlmonks.org?node_id=1071716

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

I need to do something like this.

if ($ver > 2) { require 'Config'; } else { require 'Settings'; }

Config is actually the renamed newer version of Settings and both those modules expose the same constant(a hash named CONFIG, but the values are different). But I need this inside another module definition which uses the constants defined in those modules. $ver is a param to new() method of this module. So, I am not able to put it in a BEGIN block outside the module.

Since I am using a 'require', I get Can't use bare word CONFIG. Can someone help me with this please ?

Replies are listed 'Best First'.
Re: Dynamically requiring a module
by tobyink (Canon) on Jan 23, 2014 at 09:28 UTC

    Probably easiest is to do something like:

    my $module; if ($ver > 2) { require Config; $module = "Config"; } else { require Settings; $module = "Settings"; } my $enable_foo = $module->CONFIG->{should_enable_foo};
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
Re: Dynamically requiring a module
by choroba (Cardinal) on Jan 23, 2014 at 09:30 UTC
    You have two options:
    1. Do not use the bareword. Change CONFIG to CONFIG() or &CONFIG wherever called.
    2. Define the sub CONFIG so that the parser knows it, then redefine it with constant. You might want to turn off warnings:
      sub CONFIG () {} { no warnings 'redefine'; if ($ver > 2) { require Config; Config->import; } else { require Settings; Settings->import; } }
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      This works like a charm! Thanks. The other approach of renaming it to $module->CONFIG would mean a bit more change in a lot of places(though it is just find-replace)
Re: Dynamically requiring a module
by fishmonger (Chaplain) on Jan 23, 2014 at 15:16 UTC

    Another option besides what has already been given would be to use Module::Load.

    use Module::Load; my $config = 'Config'; my $settings = 'Settings'; my $ver = 3; load $ver > 2 ? $config : $settings;
Re: Dynamically requiring a module
by Bloodnok (Vicar) on Jan 23, 2014 at 14:33 UTC
    At its' simplest, would something along the lines of the following not suffice...
    my $module = $ver > 2 ? 'Config' : 'Settings'; require $module; sub get_conf_val { no strict qw/refs/; return ${"$module\::CONFIG"}{shift()}; } my $val = get_conf_val('conf_data_name');

    A user level that continues to overstate my experience :-))
Re: Dynamically requiring a module
by Anonymous Monk on Jan 23, 2014 at 14:33 UTC

    Consider this very-useful bit of glue: UNIVERSAL::require ... There are just enough gotchas in requiring things, to make you glad to have this lil helper.