Randy J Ray

NAME

Env::Export - Export %ENV values as constant subroutines

SYNOPSIS

    use Env::Export 'PATH';

    # This will fail at compile time if the $ENV{PATH}
    # environment variable didn't exist:
    print PATH, "\n";

    # regular constant sub, works fully qualified, too!
    package Foo;
    print main::PATH, "\n";

DESCRIPTION

This module exports the requested environment variables from %ENV as constants, represented by subroutines that have the same names as the specified environment variables.

Specification of the environment values to export may be by explicit name, shell-style glob pattern or by regular expression. Any number of names or patterns may be passed in.

SUBROUTINES/METHODS

The only subroutine/method provided by this package is import, which handles the exporting of the requested environment variables.

EXPORT

Any environment variable whose name would be a valid Perl identifier (must match the pattern ^[A-Za-z_]\w*$) may be exported this way. No values are exported by default, all must be explicitly requested. If you request a name that does not match the above pattern, a warning is issued and the name is removed from the exports list.

EXTENDED SYNTAX

The full range of syntax acceptable to the invocation of Env::Export covers keywords and patterns, not just simple environment variable names. Some of the keywords act as flags, some only do their part when they appear in the arguments stream.

Specifying Names

In addition to recognizing environment variables by name, this module supports a variety of extended syntax in the form of keywords, regular expressions and shell-style globbing.

Regular expressions

Names can be specified by passing a pre-compiled regular expression in the list of parameters:

    use Env::Export qr/^LC_/;

This would convert all the environment variables that start with the characters LC_ (the locale/language variables used for character sets, encoding, etc.) to subroutines. You wouldn't have to specify each one separately, or go back and add to the list if/when you added more such variables.

All Perl regular-expression syntax is accepted, so if you have both PATH and Path defined, and happen to want both (but not PATHOLOGY), you could use the following:

    use Env::Export qr/^path$/i;

At present, regular expressions have to be pre-compiled (objects of the Regexp class). Env::Export will not attempt to evaluate strings as regular expressions.

Globbing

In addition to regular expressions, a simple form of shell-style "globbing" is supported. The ? character can be used to match any single character, and the * character matches zero or more characters. As these actually correspond to the regular expression sequences . and .*, what is actually done is that the pattern is converted to a Perl regular expression and evaluated against the list of viable %ENV keys. The converted patterns are also anchored at both ends.

This invocation:

    use Env::Export 'ORACLE*';

is exactly the same as this one:

    use Env::Export qr/^ORACLE.*$/;

The :all keyword

This is the only one of the keywords that adds symbols to the list of eventual exported entities. When it is encountered, all of the keys from %ENV that are valid identifiers (match the previously-specified pattern) are set for export. Note the keywords in the next section, though, and the examples shown later, as these can affect what actually gets produced by referring to :all.

Keywords and Flags

In addition to the :all keyword, the following are recognized. The first four act as flags, with the "no" version turning off the behavior and the shorter version enabling it. The last keyword operates in a different way.

:[no]warn

Enable or disable warnings sent by Env::Export. By default, warnings are enabled. If the user tries to redefine an existing subroutine, a warning is issued. If warnings are disabled, then it will not be. Note that the warning that signals an invalid export pattern cannot be suppressed by this keyword. (It can by caught by $SIG{__WARN__}, if you like.)

:[no]override

Enable or disable overriding existing functions. By default, overriding is disabled, and you will see a warning instead that you tried to define a function that already exists. If :override is set, then the function in question is replaced and no warning is issued.

Note that Perl itself will issue a mandatory warning if you redefine a constant subroutine, and this warning cannot be suppressed (not even by the no warnings pragma). The :nowarn keyword will not prevent it, either. It can be caught by the __WARN__ pseudo-signal handler, if you choose.

:[no]prefix [ARG]

By default, the created functions are given the exact same names as the environment variables they represent. If you prefer, you can specify a prefix that will be applied to any names generated after the :prefix keyword is read. This keyword requires a single argument, a string, and will prepend it to all function names until either a new prefix is given by a subsequent :prefix, or until :noprefix is read. The :noprefix keyword clears any current prefix.

The following invocation:

    use Env::Export qw(:prefix ENV_ HOME PAGER :noprefix SHELL);

will result in the creation of ENV_HOME, ENV_PAGER and SHELL as functions.

These keywords control whether the functions created reflect subsequent changes in the underlying environment. By default, the created functions use a copy of the value of the given key at creation-time, so that they may potentially be in-lined as constant subroutines. However, this means that a change to the environment variable in question (by a third-party library, for example) will never be reflected in the function. Specifying :link causes all subsequent functions to read the environment value each time, instead. This is applied to each function created until :nolink is encountered.

In this example:

    use Env::Export qw(:link PATH :nolink HOME);

The function HOME will never change (as it is highly unlikely to), while PATH will reflect any changes made to $ENV{PATH} anywhere else in the running program.

:split ARG

Several common environment variables act as lists of values separated by a common delimiter (usually a colon, :). These include "PATH", "LD_LIBRARY_PATH", etc. Since users may want to always treat these values as arrays, to save you the trouble of always splitting the elements out each time you access the value the :split keyword allows you to specify the delimiter that should be applied. The function that gets created will then return an array rather than a single element (although the array may have only one element, of course). The delimiter may be a constant string or a pre-compiled regular expression:

    use Env::Export qw(:split : PATH);

or

    # Exports HOME() as an array of pathname elements:
    use Env::Export (':split' => qr{/|\\}, 'HOME');

The :split keyword does not carry over to multiple specifications, and must appear immediately before the name or pattern it applies to. It does, however, apply to all names that match a pattern. Thus, the following:

    use Env::Export qw(:split : *PATH*);

will match all environment variables that contain PATH in their name, and treat them all as arrays with : as the delimiter.

EXAMPLES

Here are some further examples, with explanations:

use Env::Export qw(:all :prefix a :split : *PATH*);

Exports all valid %ENV keys as (scalar) functions. Additionally, any keys that contain PATH in the name are exported a second time with a prepended to the function name, and return arrays created by splitting the value of the environment variable on the : character. Thus, you would have both PATH() that returned the contents of $ENV{PATH}, and aPATH() that returned the elements of the path after splitting.

Exports PATH() as a scalar function that always reflects the current value of $ENV{PATH}. Because the :split keyword was not immediately before "PATH", it was not applied!

Every valid key in %ENV is exported, with each new function name having a prefix of ENV_ ("ENV_HOME", "ENV_PATH", etc.). Additionally, each function reflects the current value of its underlying environment variable, no warnings are issued (at least, not by Env::Export), and any existing functions are overridden by the newly-created ones.

CAVEATS

While the :override and :nooverride keywords can manipulate the behavior around redefining existing subroutines, Perl will always issue a warning if you redefine an existing constant subroutine. This warning cannot be suppressed by the no warnings 'redefine' pragma.

DIAGNOSTICS

Env::Export only issues warnings, and should not throw any exceptions.

SEE ALSO

constant, "Constant Functions" in perlvar

AUTHOR

Randy J. Ray <rjray at blackperl.com>

Original idea from a journal posting by Curtis "Ovid" Poe (<ovid at cpan.org>), built on a sample implementation done by Steffen Mueller, <smueller at cpan.org>.

BUGS

Please report any bugs or feature requests to bug-env-export at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Env-Export. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT

LICENSE AND COPYRIGHT

This file and the code within are copyright (c) 2009-2011 by Randy J. Ray.

Copying and distribution are permitted under the terms of the Artistic License 2.0 (http://www.opensource.org/licenses/artistic-license-2.0.php) or the GNU LGPL 2.1 (http://www.opensource.org/licenses/lgpl-2.1.php).




Hosting generously
sponsored by Bytemark