http://www.perlmonks.org?node_id=416063

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

Hi monks. I am using WIN32::API in WSH-Script using ActiveStates PerlScript-Extension. eg.
use Win32::API; $timer = Win32::API->new( "winmm.dll", "long timeGetTime()" );
but the module complains
>> Win32::API::parse_prototype: WARNING unknown output parameter type +'long' at C:/Perl/site/lib/Win32/API.pm line 273.
i tracked this down. it is because WSH-Script run eval()ed, and therefore the modules INIT-Block does not run.
i wonder if it is possible to call the INIT-Block expliciatly ?
tx, holli

Replies are listed 'Best First'.
Re: call a modules INIT-section
by gaal (Parson) on Dec 19, 2004 at 21:44 UTC
Re: call a modules INIT-section (B tricks)
by ysth (Canon) on Dec 20, 2004 at 02:43 UTC
    It is, but it is only easily possible (that is, without using special XS code) for 5.8.1 and above.
    # pass a module name # returns list or count of coderefs for unrun INITs in the given modul +e # empty list/undef if something goes wrong sub get_inits_for_module { use 5.008001; use B; my $mod = shift; eval { map $_->object_2svref, grep $_->GV->STASH->NAME eq $mod, B::init_av->ARRAY } }
    Remove the grep line to get unrun INITs for any module.

    In general, any module should provide something that can be called to initialize it for circumstances where INIT doesn't get run, so you shouldn't ever have to do this.

Re: call a modules INIT-section
by dragonchild (Archbishop) on Dec 20, 2004 at 13:38 UTC
    The solution stvn and I used in Class::LazyLoad was to provide a function you can call if the INIT step isn't called. I'm surprised Win32::API wouldn't provide the same functionality ...

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: call a modules INIT-section (fix for Win32::API::Type)
by ihb (Deacon) on Mar 20, 2005 at 12:45 UTC

    I took a glance at Win32::API::Type which is the module that uses INIT. It seems like the author has misunderstood the purpose of INIT blocks. There's no need for the code to execute at INIT time. With some hackery you can work around this. The idea goes like this: add an INC hook that if Win32::API::Type gets used it locates the file it wants to use, reads the file, removes the INIT, opens a filehandle to the modified source and returns the filehandle. Code-wise it can look like

    use 5.008; use File::Slurp qw/ read_file /; unshift @INC => sub { return undef unless $_[1] eq 'Win32/API/Type.pm'; my $f = your_favourite_module_locate_routine(...); my $src = read_file($f); $src =~ s/INIT (?={)//; open my $fh, '<', \$src or die "I have no idea if or why this would ever die, but anyw +ay: $!"; return $fh; };
    As for locating which file to load there's a number of modules on CPAN that does that.

    ihb

    See perltoc if you don't know which perldoc to read!