Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Constants refferences

by leonidlm (Pilgrim)
on Aug 21, 2008 at 14:10 UTC ( [id://705796]=perlquestion: print w/replies, xml ) Need Help??

leonidlm has asked for the wisdom of the Perl Monks concerning the following question:

Hi all
Sorry for asking 2 questions the same day, but I am writing a big perl program right now, and of course it brings some new questions with it.
So to my question:
I can't understand why I need to use the following syntax for constants:
use constant { ARRAY_REF = [1,2,3,4,5], STRING => '.+?', }; # I NEED TO USE '\' with the constant if ($line =~ /${\STRING}/); # while on the other side I use '+' with the CONSTANT HERE print "hey!" if (grep {/ERROR/} @{+ARRAY_REF});
Someone :) ?

Replies are listed 'Best First'.
Re: Constants refferences
by Tanktalus (Canon) on Aug 21, 2008 at 14:19 UTC

    For interpolation.

    For strings, perl will only interpolate variables starting with $ or @. So you need that. But ${} will dereference, so you need to take a reference. Really, this is a limitation of the constant module in creating constants that aren't usable everywhere that variables are. See Readonly for a slower alternative that interpolates properly.

    For arrays, ARRAY_REF really returns a reference already, so when you dereference with @{}, it's already set. However, Perl may be getting confused as to whether ARRAY_REF is the name of your variable or a function or ... so the + disambiguates this. You could just as easily use @{ARRAY_REF()}, again, because ARRAY_REF really is a function call.

    Generally, I haven't found much need for constant - I've found that constants aren't and variables don't, so why bother. :-P

Re: Constants refferences
by kyle (Abbot) on Aug 21, 2008 at 14:32 UTC

    The short answer is that ARRAY_REF is a reference and STRING is not.

    What you put between ${} or @{} needs to be a reference. By itself, STRING is not a reference—it's just a string. To get a reference to that string, use the backslash. Hence: "${\STRING}". It's the same as "${\'.+?'}".

    If you have a bareword between ${}, or a literal string, that's taken as the name of a variable ("${STRING}" is the same as "$STRING"). If you're using strict, then that's going to bomb (unless that variable's been declared somewhere).

    ARRAY_REF is already a reference, so you don't have to backslash it. You do, however, have to keep "@{ARRAY_REF}" from being interpreted as "@ARRAY_REF", and so the "+" is there to mark it as an expression and not just a bareword.

      If you have a bareword between ${}, or a literal string, that's taken as the name of a variable ("${STRING}" is the same as "$STRING").

      It appears to be more complicated than that:

      use strict ; use warnings ; my $x = 57 ; print "\${x} = '", ${x}, "'\n" ; print "\${'x'} = '", ${'x'}, "'\n" ;
      gives:
      ${x} = '57' Can't use string ("x") as a SCALAR ref while "strict refs" in use .. +.
      Turning off "strict refs" gives:
      ${x} = '57' Use of uninitialized value in print ... ${'x'} = ''
      Replacing my $x by our $x, gives:
      ${x} = '57' ${'x'} = '57'
      The interpretation of the bareword case doesn't look desperately useful to me... Anybody know why Perl doesn't treat it as a subroutine/constant ?

      Sadly, this wouldn't help "${CONSTANT}" but it would mean that @{REF_ARRAY_CONSTANT} would do what might be expected.

        Ambiguous use of ${x} resolved to $x at - line 4.
Re: Constants refferences
by dHarry (Abbot) on Aug 21, 2008 at 15:16 UTC

    I am with brother Tanktalus. I would like to add that the usage of Readonly is also a Perl Best Practice. if you can, use it unless the performance issue is more important to you. The constant in Perl is a bit ugly, In Perl6 they will fix it, see Make constants look like variables for the limitations of constant and how they will solve it in Perl6.

      Adding another related question:
      Can I load a constant variable values at runtime ?
      For example if I have a configuration file that overwrites couple of the constants ?
        No. Just use package variables instead.

        What's special about constants is that they are replaced with their value when a statement that uses them is compiled. It doesn't make sense to replace them after they're no longer used.

        Note that is possible to execute code (such as loading your config file) before other code (such as the code using the constants) is compiled. But why bother.

        This is one place where Readonly shines. You can create your variables, initialize them and then mark as read only.

        Also worth noting is that arrays and hash references point to data structures that can be modified. This is covered in the constant perldoc.

        I have found constants useful for simple things like naming array indexes data structures. Otherwise, if I need to be sure a data-structure is immutable, I use Readonly or lock hashes using Hash::Util, depending on the complexity of the structure.


        TGI says moo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://705796]
Approved by Tanktalus
Front-paged by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2024-04-23 13:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found