in reply to Re: Reading the script code from itself
in thread Reading the script code from itself

Thank you!

What I want to acheive is to have a package full of constants needed by a project. I just want constants to be exportable by tags, but I don't want to indicate constant names twice, as I want to do it only once - when I'm defining those constants.

So, I'd love it to look like that:

# :tag1 use constant constant1 => 1; use constant constant2 => 2; use constant constant3 => 3; # :tag2 use constant constant4 => 4; use constant constant5 => 5; use constant constant6 => 6; # :tag3 use constant constant4 => 4; use constant constant5 => 5; use constant constant6 => 6; @EXPORT_TAGS = some_cool_internal_subrotine_making_the_hash_of_tags_to +_be_exported();

P.S. I'm already using a complicated structure of configuration files in this project, but I want to have constants somewhere in the code where they can't be changed by an user (as configuration files acutally can be changed).

Replies are listed 'Best First'.
Re^3: Reading the script code from itself
by Anonymous Monk on May 29, 2014 at 13:24 UTC

    Disclaimer: I find the design questionable... you should consider not using constant (in fact Conway's Perl Best Practices recommends against it, e.g. Perl::Critic::Policy::ValuesAndExpressions::ProhibitConstantPragma) and look at alternatives such as using a locked hash (or even a function) to return your "constant" values.

    As is said, Perl gives you just enough rope to hang yourself with, so here you go:

    package ConstExporter; use warnings; use strict; my %CONSTANTS = ( foo => "abc", bar => "xyz", quz => "123", ); sub import { my ($class, @export) = @_; my ($callpack) = caller; for my $exp (@export) { die "bad constant name '$exp'" unless exists $CONSTANTS{$exp}; no strict 'refs'; *{"${callpack}::$exp"} = sub () { $CONSTANTS{$exp} }; } } 1;

    Use it in the usual way: use ConstExporter qw/foo bar/;

      Thank you! :)

      V.Melnik