Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^2: Beware of POSIX constants (sorta)

by tye (Sage)
on Oct 03, 2005 at 16:38 UTC ( [id://496986]=note: print w/replies, xml ) Need Help??


in reply to Re: Beware of POSIX constants
in thread Beware of POSIX constants

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        

Replies are listed 'Best First'.
Re^3: Beware of POSIX constants (sorta)
by Anonymous Monk on Oct 03, 2005 at 23:14 UTC
    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.

      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.

      Yes, I don't think tye was suggesting that just adding a prototype would be enough to solve any problem. But so what? Would defining the function earlier solve any problems? The function doesn't have a prototype so defining it early doesn't gain anything. (:

      But, in fact, you don't have to define the function earlier. You can still use "POSIX's autoloading behaviour" to delay the defining of the function's body, you just have to fix the exporting of the function to export a prototype (by declaring the function that you haven't defined yet).

      Here's an example of how to do that making the bold assumption that all POSIX exported items with ALL_CAPS names are supposed to be constants (and mostly ignoring POSIX's current implementation for the sake of making a quick demonstration):

      BEGIN { require POSIX; package POSIX; my $import= \&POSIX::import; *import= sub { warn "import( @_ )\n"; my( $pkg )= @_; eval "sub $_(); 1" || warn "$@" for grep /^[A-Z_]+$/, @_[1..$#_]; goto &$import; }; my $auto= \&POSIX::AUTOLOAD; *AUTOLOAD= sub { if( $AUTOLOAD =~ /^[A-Z_:]+$/ ) { warn "Auto-loading $AUTOLOAD.\n"; my $val = constant( ( split /::/, $AUTOLOAD )[-1] ); if( $! == 0 ) { goto &$AUTOLOAD if eval "sub $AUTOLOAD() { $val }; 1"; warn "$@"; } } goto &$auto; }; } use POSIX 'CHAR_MAX'; print "CHAR_MAX(", prototype("CHAR_MAX"), ")\n"; print CHAR_MAX+1, $/;

      which outputs:

      $ perl posix.pl import( POSIX CHAR_MAX ) CHAR_MAX() Auto-loading POSIX::CHAR_MAX. 128

      Which shows that Perl was forced to autoload the function after the line that prints the prototype and yet the problem is fixed.

      - tye        

        Currently, POSIX doesn't require you to import anything - and I think your solution does. Furthermore, your solution fixes the problem of the missing prototype at the cost of why POSIX's constants don't have prototypes: in order to reduce the overhead of 'use POSIX', functions are autoloaded - you don't pay compile costs for functions you don't need. Your solution does a string eval for each all caps function. Then you might as well have listed all of them in POSIX.pm.
        Perl --((8:>*

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://496986]
help
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found