++ed by:

1 PAUSE user
1 non-PAUSE user.

Eric Strom


here::declare - easily declare compile time variables


version 0.02


    use here::declare;

    use const qw($ONE 1 $TWO 2);

    use my [qw(x y z)] => [$ONE + $TWO, 4, 5];

    use our '@foo' => [$x, $y, $z];

is equivalent to:

    our ($ONE, $TWO);
    BEGIN {
        *ONE = \'1';
        *TWO = \'2';

    my ($x, $y, $z);
    BEGIN {
        ($x, $y, $z) = ($ONE + $TWO, 4, 5);

    our @foo;
    BEGIN {
        @foo = ($x, $y, $z);

without all that tedious typing.


all aspects of here::declare must normally be imported using use ...; statements.

without arguments, an initial use here::declare; line creates all five pseudo-modules ( my our state const const2 ). if you only want some, pass a list of those.

in the following examples, the use my declaration will be used. its usage is equivalent to use our and use state .

a single argument with =

        use my '$x = 1';
        use my '($y, $z) = (2, 3)';

    this is the simplest transform, which given an argument matching foo = bar gets rewritten as:

        my foo; BEGIN {foo = bar}

    so the above becomes:

        my $x; BEGIN {$x = 1}
        my ($y, $z); BEGIN {($y, $z) = (2, 3)}

    while this version looks the closest to perl's native variable declarations, it is unable to pass arguments that can not easily be written in a string.

list of name/value pairs:

        use my '$say' => sub {print @_, $/};
        use my '@array' => [1, 2, 3], '%hash' => {a => 1, b => 2};

    here an arbitrarily long list of name/value pairs is passed to the declarator.

    if the name is a $scalar then the corresponding value will be copied into the newly created variable at compile time. it is safe to pass any type of scalar as a value, and it will not be stringified. bareword and -bareword names will be interpreted as $bareword which can cut down on the number of quotes you need to write ( use my say = sub {...}; >)

    if the name is an @array or %hash the corresponding values must be ARRAY or HASH references, which will be dereferenced and copied into the new variables.

    so the above becomes:

        my $say;   BEGIN {$say   =   here::fetch(1)}
        my @array; BEGIN {@array = @{here::fetch(2)}}
        my %hash;  BEGIN {%hash  = %{here::fetch(3)}}

    where here::fetch is a subroutine that returns the values passed into the declarator, which gets around needing to serialize the values.

[array of names] => list or array of values:

        use my [qw($x $y $z)] => 1, 2, 3;
        use my [qw($foo @bar %baz)] => ['FOO', [qw(B A R)], {b => 'az'}];

    this usage is exactly like the list of name/value pairs usage except the names and values are passed in separately. the names must be an array reference. the values can be an array reference or a list.

    as a syntactic shortcut, the above two lines could also be written:

        use my '($x, $y, $z)' => 1, 2, 3;
        use my '($foo, @bar, %baz)' => 'FOO', [qw(B A R)], {b => 'az'};

    which of course expands to something equivalent to:

        my ($x, $y, $z);
        BEGIN {$x = 1; $y = 2; $z = 3}
        my ($foo, @bar, %baz);
        BEGIN {$foo = 'FOO'; @bar = qw(B A R); %baz = (b => 'az')}

    ignoring the complexities of here::fetch

const and const2

        use const '$FOO' => 'BAR';
        use const2 DEBUG => 1;

    which expands to:

        our $FOO; BEGIN {*FOO = \'BAR'}
        sub DEBUG () {1} our $DEBUG; BEGIN {*DEBUG = \DEBUG}

    these declarations only accept $scalar , bareword or -bareword names (interchangeably), but otherwise the usage is similar to use my ...

    the single argument syntax is not supported with these two declarations.


    you can remove the pseudo-modules manually:

        no here::declare;

    or let the declaration fall out of scope if B::Hooks::EndOfScope is installed:

            use here::declare;
            use my ...; # works
        use my ...; # error


if you don't like the installation of pseudo-modules, you can pass use here::declare a list of any of the pseudo-module names each containing at least one upper case character. this will cause that name to be exported into your namespace as a subroutine.

    use here::declare 'MY';

    use here MY [qw($x $y)] => [0, 0];


here::declare is built on top of the " here " framework.

in writing this module, I was pushed by p5p to make the interface a bit closer to the native my and our keywords. I did this with Devel::Declare in Begin::Declare. Begin::Declare is certainly closer in usage to the keywords, but the dependency on Devel::Declare might prevent installation for some people. in addition, this module (despite using Filter::Util::Call) is a little safer to use than Begin::Declare since the use statement required by this module more clearly delineates the scope of its actions.


Eric Strom, <asg at cpan.org>


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


copyright 2011 Eric Strom.

this program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

see http://dev.perl.org/licenses/ for more information.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 302:

L<> starts or ends with whitespace