in reply to Import constants as scalar instead of bareword sub

I don't understand your objection to "bareword subs". Perl understands them perfectly well if they are defined before they're called.

In practice, it's pretty rare that constants need to be interpolated, except maybe when debugging with print.

You can make $EINTR a constant with:

*EINTR = \4;
but that kind of thing is not always portable between systems. Because the value must be a reference to a literal in source, afaik that would require some kind of source filter to get portability. Not worth it, IMO.

After Compline,
Zaxo

Replies are listed 'Best First'.
Re^2: Import constants as scalar instead of bareword sub
by perrin (Chancellor) on Nov 02, 2005 at 19:41 UTC
    People are constantly (pun intended) being bitten by bareword subs not getting interpolated. A classic example is when they are used as a hash key, or on the left side of the => operator. And I often need them interpolated in strings, like SQL statements, which is really ugly with subs. I never use subs as constants for this reason.
Re^2: Import constants as scalar instead of bareword sub
by xdg (Monsignor) on Nov 02, 2005 at 22:22 UTC
    You can make $EINTR a constant with:
    *EINTR = \4;
    but that kind of thing is not always portable between systems. Because the value must be a reference to a literal in source, afaik that would require some kind of source filter to get portability.

    Out of curiousity, I'd like to understand better why you think this isn't portable? The value could also be a reference to a literal in an eval, not just the source itself. For example, here's a quick test I wrote (without the kind of robust error checking on the inputs that I'd write for a real module, of course.)

    ConstantVars.pm

    package ConstantVars; use strict; use warnings; sub import { my $package = shift; die "Odd number of arguments to ConstantVars" if ! @_ % 2; my %constants = @_; my $caller = caller; while (my ($key,$value) = each %constants) { eval qq( *${caller}::${key} = \\"${value}" ); } } 1;

    test_constants.pl:

    use strict; use warnings; use ConstantVars ( PI => 3.14159, VERSION => 1.01, ); print "PI is $PI in version $VERSION\n";

    Prints:

    PI is 3.14159 in version 1.01

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re^2: Import constants as scalar instead of bareword sub
by itub (Priest) on Nov 02, 2005 at 20:50 UTC
    Another option is the Readonly module, available on CPAN. I've never tried it, but some people recommend it.
      I've read about it in Perl Best Practices book and I've tried it. It looks very promising (especially with Readonly::XS helper module).

      But Devel::DProf show it's still use tie()ed scalar (and so call FETCH() on each scalar access) even with Readonly::XS installed.

      This was sadly news, because I feel like with Readonly::XS it should just 'mark' SV as read-only and doesn't tie() it. :-(

Re^2: Import constants as scalar instead of bareword sub
by sauoq (Abbot) on Nov 03, 2005 at 02:44 UTC
    but that kind of thing is not always portable between systems. Because the value must be a reference to a literal in source, afaik that would require some kind of source filter to get portability.

    You lost me there. Can you give an example of this construct not being portable? I actually prefer this style of constants, so if there is a reason I should avoid it, I'd very much like to understand it.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re^2: Import constants as scalar instead of bareword sub
by powerman (Friar) on Nov 02, 2005 at 21:47 UTC
    Why not portable? Why source filters? I sure it as simple as:
    eval q{*O_NONBLOCK = \\}.O_NONBLOCK;
    This code work, and work even a little (1-20%) faster than usual scalar! It's portable and can be executed automatically in import() if it see user try to import $O_NONBLOCK instead of O_NONBLOCK.