Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Beware of POSIX constants

by tlm (Prior)
on Oct 03, 2005 at 15:28 UTC ( [id://496962]=perlmeditation: print w/replies, xml ) Need Help??

Dear monks,

Just a short meditation to alert you to the evils that lurk in POSIX constants. For example

% perl -MPOSIX=CHAR_MAX -wle 'print( CHAR_MAX )' 127 % perl -MPOSIX=CHAR_MAX -wle 'print( CHAR_MAX + 1 )' 127
No difference between printing CHAR_MAX and CHAR_MAX + 1! A quick consultation with MO=Deparse provides the necessary insight:
% perl -MPOSIX=CHAR_MAX -MO=Deparse,-p -e 'print( CHAR_MAX + 1 )' print(CHAR_MAX(1)); -e syntax OK
But check this out:
% perl -Mconstant=CHAR_MAX,127 -wle 'print( CHAR_MAX + 1 )' 128 % perl -Mconstant=CHAR_MAX,127 -wle 'print( CHAR_MAX( 1 ) )' Too many arguments for main::CHAR_MAX at -e line 1, at end of line Execution of -e aborted due to compilation errors.
It appears that rolling one's own CHAR_MAX with constant produces a more civilized item than POSIX::CHAR_MAX.

I haven't delved into the POSIX module to get to the bottom of this but we can conclude that, although POSIX constants are subs, they don't behave as nicely as those produced with the constant pragma. They can bite, so watch out.

Thanks to tye for the words o' wisdom.

the lowliest monk

Replies are listed 'Best First'.
Re: Beware of POSIX constants
by merlyn (Sage) on Oct 03, 2005 at 15:46 UTC
Re: Beware of POSIX constants
by Zaxo (Archbishop) on Oct 03, 2005 at 15:42 UTC

    The difference is in the subs' prototypes,

    $ perl -Mconstant=CHAR_MAX,127 -e'print defined(prototype "CHAR_MAX")? +"Yes\n":"No\n"' Yes $ perl -MPOSIX=CHAR_MAX -e'print defined(prototype "CHAR_MAX")?"Yes\n" +:"No\n"' No $
    The expression 1 + CHAR_MAX works as expected for either constant or POSIX.

    After Compline,
    Zaxo

Re: Beware of POSIX constants
by Perl Mouse (Chaplain) on Oct 03, 2005 at 16:01 UTC
    This is a result of POSIX's autoloading behaviour. POSIX::CHAR_MAX is defined at runtime, too late for prototypes to have any effect.
    #!/usr/bin/perl use strict; use warnings; use POSIX; print defined &POSIX::CHAR_MAX ? "Yes 1\n" : "No 1\n"; my $var = CHAR_MAX; print defined &POSIX::CHAR_MAX ? "Yes 2\n" : "No 2\n"; __END__ No 1 Yes 2
    Perl --((8:>*

      The delayed loading happens as you show, but even after the delayed load, the now-defined function still lacks a prototype:

      use POSIX qw( CHAR_MAX ); BEGIN { my $x= CHAR_MAX(); } BEGIN { print defined(\&CHAR_MAX), $/; } for(qw( CHAR_MAX POSIX::CHAR_MAX )) { my $proto= prototype($_); $proto= "..." if ! defined $proto; print "$_($proto)\n"; } print CHAR_MAX, $/; print CHAR_MAX+1, $/; __END__ Produces: 1 CHAR_MAX(...) POSIX::CHAR_MAX(...) 127 127

      - tye        

        The delayed loading happens as you show, but even after the delayed load, the now-defined function still lacks a prototype

        Yes, I don't think Perl Mouse was suggesting it would get a prototype. But so what? Would adding a prototype solve any problems? Usually, the entire program has been compiled at that point already, so adding a prototype doesn't gain anything.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-24 21:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found