Question

I'm trying to write a pragma for defining a bunch of constants, like this:

use many::constant
    one_constant => 1,
    other_constant => 2,
;

The relevant portion of my import looks like

package many::constant;

use strict;
use warnings;

sub import {
    my ($class, @constants) = @_;

    my $caller_nms = do {
        no strict 'refs';
        \%{caller.'::'}
    };

    while (my ($name, $value) = splice @constants, 0, 2) {
        *{$caller_nms->{$name}} = sub () { $value };
    }
}

I expect the $caller_nms stash to auto-vivify when assigned to like this, but I'm getting an error "Can't use an undefined value as a symbol reference". Is there a way to get this assignment to work like I expect? I ended up changing the assignment to:

my $caller_glob = do {
    no strict 'refs';
    \*{caller.'::'.$name}
};
*$caller_glob = sub () { $value };

but that feels less elegant to me.

Was it helpful?

Solution

Just use use constant as a baseline and actually examine the source: constant.pm.

That's essentially what it does as well:

my $pkg = caller;
# ...
{
    no strict 'refs';
    my $full_name = "${pkg}::$name";
    # ...
    my @list = @_;
    *$full_name = sub () { @list };
}

Also, note that the constant module has this feature: constant #Defining multiple constants at once

use strict;
use warnings;

use constant {
    one_constant => 1,
    other_constant => 2,
};

print one_constant, ' - ', other_constant, "\n";

Outputs:

1 - 2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top