Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Problem with AUTOLOAD and Windows

by Brutha (Friar)
on Nov 23, 2011 at 12:19 UTC ( [id://939645]=perlquestion: print w/replies, xml ) Need Help??

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

In an AUTOLOAD routine I get a mysterious 'No such file or directory' error message. I need some help to interpretit.

I still have not managed to manually make the DBD::DB2 package as described in Node DBD::DB2 with ActiveState Perl 5.12 on Windows. But this time I am a bit further. The compile seems to be correct and the problem has to do with 'use autoload' and defining a standard AUTOLOAD procedure. So what have I done.

First made all fresh from a DBD-DB2-1.82 download from CPAN and debugged into DBD::DB2::Constants::AUTOLOAD (line 1572). This routine is more or less exactly, what the docs gave as an example. Debugging gave me the following:

DB<4> c DBD::DB2::Constants::AUTOLOAD(blib\lib/DBD/DB2/Constants.pm:1572): 1572: my $val = constant($constname, @_ ? $_[0] : 0); DB<4> p $constname SQL_PARAM_INPUT_OUTPUT DB<5> l 1572==>b my $val = constant($constname, @_ ? $_[0] : 0); 1573: if ($! != 0) { 1574: if ($! =~ /Invalid/) { 1575: $AutoLoader::AUTOLOAD = $AUTOLOAD; 1576: goto &AutoLoader::AUTOLOAD; 1577 } 1578 else { 1579: croak "Your vendor has not defined DBD::DB2::C +onstants macro $constname"; 1580 } 1581 } DB<5> n constant 'SQL_PARAM_INPUT_OUTPUT',0 Now I'm here and return 2 DBD::DB2::Constants::AUTOLOAD(blib\lib/DBD/DB2/Constants.pm:1573): 1573: if ($! != 0) { DB<5> p $! No such file or directory DB<6> p $val 2 DB<7>

This looks like the Constants.xs works as expected (I introduced the two additional output lines), it returns the correct value for the constant, but the '$!' makes no sense. That lets the code jump into the 'undefined macro' branch and fail. Where does this come from? As the /Invalid/ condition shows there seem to be similar cases. Did anybody see this before?

I work on a German Windows XP machine with Visual C and ActiveState Perl. I tried Perl versions 5.8, 5.10 and 5.12 (5.14 not yet). All selfmade DBD::DB2 modules behave the same under these environments. The premade PPM from one of the repositories for 5.8 and 5.10 returns an empty string for $! and therefore works. But I still have not found a ppm for newer Perl versions containing the DB2 module yet.

Any help is appreciated.

And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
(Terry Pratchett, Small Gods)

Replies are listed 'Best First'.
Re: Problem with AUTOLOAD and Windows
by Corion (Patriarch) on Nov 23, 2011 at 12:30 UTC

    It seems that the C code uses $! as an (ill-advised) way to communicate "constant not found" to the caller, instead of die-ing right from the C code. The C code seems to set $! to ENOENT, so the most consistent way to handle that from the Perl code would be to check $! for ENOENT instead of trying to do string matching:

    ... manually coded string lookup table ... not_there: errno = ENOENT; return 0; }

    I would look towards POSIX to get at the value of ENOENT for your OS, and then use that for the comparison.

      The AUTOLOAD part of the code did not change from the first CPAN version of this module 11 years ago as is more or less the same as advised cpan-AutoLoader. Nevertheless, the constant is found. Here are my trace modifications from the XS:

      static double constant(name, arg) char *name; int arg; { errno = 0; printf ("constant '%s',%d\n", name, arg); switch (*name) { ... if (strEQ(name, "SQL_PARAM_INPUT_OUTPUT")) #ifdef SQL_PARAM_INPUT_OUTPUT printf("Now I'm here and return %d\n",SQL_PARAM_INPUT_OUTPUT ) +; return SQL_PARAM_INPUT_OUTPUT; #else goto not_there; #endif ...

      Otherwise this is unmodified code from CPAN (or IBM as You like).

      This code should work, it has to be either with my local (missing) configuration, localization or ... well, I have no clue.

      And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
      (Terry Pratchett, Small Gods)

Re: Problem with AUTOLOAD and Windows ($!)
by tye (Sage) on Nov 23, 2011 at 16:37 UTC

    There are tons of things that can set $!, many of which are not evident on the Perl script. If you are going to check for $! being 0 or not, then you need to set $! to 0 immediately before the code that might set $! and check $! immediately after calling that code.

    It isn't terribly surprising that $! was often left at 0 on previous runs. It also isn't terribly surprising that $! wasn't left at 0 on a recent run.

    So make two fixes to your AUTOLOAD code. Add $! = 0; right before you call the XS code. Don't even look at $! unless the XS code returns 0.

    - tye        

Re: Problem with AUTOLOAD and Windows
by Brutha (Friar) on Dec 02, 2011 at 10:11 UTC

    Thank You for all Your advice.

    As modifying standard modules is risky - especially if you update and forget your changes - I tried a brute force method for testing and succeeded. I simply installed the module despite the error, ran my tests and scripts and they worked.

    Well, I know that the this does not prove *all* cases and the absence of future problems, but it helps for the moment. Tye, I keep Your advice for $! in mind, that might help me survive if needed.

    And it came to pass that in time the Great God Om spake unto Brutha, the Chosen One: "Psst!"
    (Terry Pratchett, Small Gods)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2024-03-28 17:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found