Acme-constant

 view release on metacpan or  search on metacpan

lib/Acme/constant.pm  view on Meta::CPAN

        }
    };
    # Make a block, to make a scope for strict "refs".
    {
        # Because of symbol table modifications, I have to allow
        # symbolic references.
        no strict qw(refs);
        *{"${package}::$name"} = $constant;
    }
}

sub import {
    my $package = caller;

    # The first argument is this package name
    my $name = shift;

    # Without arguments, simply fail.
    if (@_ == 0) {
        Carp::carp qq[Useless use of "$name" pragma];
    }

    # When called with one argument, this argument would be hash
    # reference.
    elsif (@_ == 1) {
        my %hash = %{shift()};
        # each is safe here, as %hash is lexical variable.
        while (my ($name, $value) = each %hash) {
            generate_constant $package, $name, $value;
        }
    }

    # Otherwise, assume one constant, that possibly could return a list
    # of values.
    else {
        my $name = shift;
        generate_constant $package, $name, @_;
    }
    return;
}

# Return positive value to make Perl happy.
'Acme!';

__END__

=head1 NAME

Acme::constant - Like constant, except actually not.

=head1 SYNOPSIS

    use Acme::constant ACME => 42;
    print "ACME is now ", ACME, ".\n";
    ACME = 84;
    print "But now, ACME is ", ACME, "\n";

    use Acme::constant LIST => 1, 2, 3;
    print "Second element of list is ", (LIST)[1], ".\n";
    (LIST) = (4, 5, 6);
    print "But now, the second element is ", (LIST)[1], "\n";

=head1 DESCRIPTION

This pragma lets you make inconstant constants, just like the constants
the users of Ruby or Opera (before Opera 14, that is) already enjoyed.

Unlike Perl constants, that are replaced at compile time, Acme
constants, in true dynamic programming language style, can be modified
even after declaration.

Just like constants generated with standard C<use constant> pragma, the
constants declared with C<use Acme::Constant> don't have any sigils.
This makes using constants easier, as you don't have to remember what
sigil do constants use.

=head1 NOTES

As the Perl compiler needs to know about which barewords are keywords,
constants have to defined in C<BEGIN> section. Usually, this is not a
problem, as C<use> statement is automatically put in implicit C<BEGIN>
section, but that also means you cannot dynamically create constants.
For example, in the example below, the C<DEBUG> constant is always
created, with value 1, as C<use> is processed when Perl parser sees
it.

    if ($ENV{DEBUG}) {
        use Acme::constant DEBUG => 1; # WRONG!
    }

It's possible to dynamically use this module using L<if> module,
however, this is likely to cause problems when trying to use constant
that doesn't exist.

    use if $ENV{DEBUG}, Acme::constant => DEBUG => 1;

You can also use directly use C<import> method, in order to
conditionally load constant.

    BEGIN {
        require Acme::constant;
        Acme::constant->import(DEBUG => 1) if $ENV{DEBUG};
    }

Howver, usually the good idea to declare constant anyway, as using
undefined constants in strict mode causes Perl errors (and sometimes
could be parsed incorrectly).

    use Acme::constant DEBUG => $ENV{DEBUG};

Constants belong to the package they were defined in. When you declare
constant in some module, the constant is subroutine declared in it.
However, it's possible to export constants with module such as
L<Exporter>, just as you would export standard subroutine.

    package Some::Package;
    use Acme::constant MAGIC => "Hello, world!\n";

    package Some::Other::Package;
    print Some::Package::MAGIC; # MAGIC directly won't work.

=head2 List constants

Just like standard L<constant> module, you can use lists with this
module. However, there are few catches you should be aware of.

To begin with, you cannot use list constants in scalar context. While
L<constant> module lets you do this, I believe allowing something like
this can open can of worms, because constant with one element is just
as valid constant (that wouldn't return 1). Something like this won't
work.

    use Acme::constant NUMBERS => 1..6;
    print 'Found ', scalar NUMBERS, " numbers in NUMBERS.\n"; # WRONG!

Instead, to count number of elements in the constant, you can use the
C<() => trick, that lets you count elements in any sort of list.

    use Acme::constant NUMBERS => 1..6;
    print 'Found ', scalar(() = NUMBERS), " numbers in NUMBERS.\n";

Also, as C<use> statement arguments are always parsed in the list



( run in 1.787 second using v1.01-cache-2.11-cpan-39bf76dae61 )