G'day nameofmyuser,
Welcome to the Monastery.
Perl provides a number of special blocks which are executed at various points during the lifetime of the program: "BEGIN, UNITCHECK, CHECK, INIT and END". You can use these to check your assumptions about what's happening at these various points.
[Warning: Do read the linked documentation, especially the begincheck example. Some of those blocks are executed in FIFO order; and some in LIFO order. It's not intuitively obvious which is which.]
Your assumptions appear to be correct; although, the phrase "@test array is allocated at compile time" could be misinterpreted. To be clear, in both of these:
my $var1; my $var2 = 'val2';
The variables are declared at compile time; but no assignment occurs at this time. The "$var2 = 'val2'" part of that second statement occurs at runtime.
Here's an example using some of those special blocks. It's just a start: modify and extend as necessary.
#!/usr/bin/env perl -l use strict; use warnings; my $hashref = { a => 1, b => 2 }; my @array = qw{c d e}; use constant { HR_ARRAY => [ sort values %$hashref ], AREF => \@array, }; BEGIN { print join ' ', 'B1:', sort(keys %$hashref), @array } BEGIN { print join ' ', 'B2:', @{+HR_ARRAY}, @{+AREF} } INIT { @array = qw{f g h} } INIT { print join ' ', 'I1:', sort(keys %$hashref), @array } INIT { @array = qw{i j k} } INIT { print join ' ', 'I2:', @{+HR_ARRAY}, @{+AREF} } print join ' ', 'R1:', sort(keys %$hashref), @array; print join ' ', 'R2:', @{+HR_ARRAY}, @{+AREF};
Output:
B1: B2: I1: f g h I2: i j k R1: a b c d e R2: c d e
Using constant for references is generally a bad choice. It makes the token that points to the reference a constant; but, it does not make the values of the reference constants. Consider these:
$ perl -E 'use constant AREF => [1..4]; say "@{+AREF}";' 1 2 3 4 $ perl -E 'use constant AREF => [1..4]; say "@{+AREF}"; AREF = []' Can't modify constant item in scalar assignment at -e line 1, at EOF Execution of -e aborted due to compilation errors. $ perl -E 'use constant AREF => [1..4]; say "@{+AREF}"; AREF->[2] = 99 +; say "@{+AREF}"' 1 2 3 4 1 2 99 4
In terms of workarounds: one of the Anonymous Monks showed a BEGIN block; you could potentionally use an INIT block with a variation of what my code showed for AREF; you could also just use two constants, something like this:
use constant { ONE => 1, ..., FOUR => 4 }; use constant NUM_AREF => [ ONE .. FOUR ];
[Note: I've used NUM_AREF which could probably be improved upon; however, HASHREFCONST is a poor, and highly misleading, choice for an arrayref constant: it will make subsequent code difficult to understand, and runs a high risk of being the source of coding errors.]
If you tell us how this code is intended to be used, we can probably offer more concrete suggestions.
See also: enum — a CPAN module which you might find useful.
— Ken
In reply to Re: Using hashref values in constant declarations.
by kcott
in thread Using hashref values in constant declarations.
by nameofmyuser
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |