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

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

Hello monks,

Ok, at the end I've manged to resolve on my own (deleting from %INC ), but I still have doubts.

I'm trying to test a different executable path to be used in a module and specified by setting an %ENV variable.

I supposed to use die inside a BEGIN block in the module if the specified executable is incorrect:

# Win32::Backup::Robocopy code BEGIN{ if( $ENV{PERL_ROBOCOPY_EXE} ){ my $robo = File::Spec->rel2abs( $ENV{PERL_ROBOCOPY_EXE} ); die "$robo does not exists!" unless -e $robo; die "$robo is not executable!" unless -x $robo; } }

It seemed ok to me on quick test: the module dies if rubbish is passed (probably the check must be improved.. suggestions?)

But when testing this feauture I discovered the module is present anyway in %INC even if died (the require returns true? how can I return 0 from the BEGIN block?).

So with this version of test ( update the same errors appears even without all BEGIN blocks):

#!perl use 5.010; use strict; use warnings; use Test::More; use Test::Exception; BEGIN # 1) this file should not exists { my $try = 'c:\robocopy.exe'; note("try using $try"); $ENV{PERL_ROBOCOPY_EXE} = $try; dies_ok { require Win32::Backup::Robocopy } 'expected to die with not existent executable'; #delete $INC{'Win32/Backup/Robocopy.pm'}; print "--->$_ \n" for grep{/Robocopy/} keys %INC; } BEGIN # 2) the HOSTS file exists in every win version, but is not exec +utable { my $try = -e 'C:\Windows\System32\drivers\etc\HOSTS' ? 'C:\Windows\System32\drivers\etc\HOSTS' : # systenative used if a 32bit perl. See # filesystem redirection oddities 'C:\Windows\Sysnative\drivers\etc\HOSTS'; note("try using $try"); $ENV{PERL_ROBOCOPY_EXE} = $try; dies_ok { require Win32::Backup::Robocopy } 'expected to die with not executable file'; #delete $INC{'Win32/Backup/Robocopy.pm'}; print "--->$_\n" for grep{/Robocopy/} keys %INC; } BEGIN # 3) this has to be the standard one { my $try = -e 'C:\Windows\System32\robocopy.exe' ? 'C:\Windows\System32\robocopy.exe' : 'C:\Windows\Sysnative\robocopy.exe'; note("try using $try"); $ENV{PERL_ROBOCOPY_EXE} = $try; #delete $INC{'Win32::Backup::Robocopy'}; ok (require Win32::Backup::Robocopy, 'default executable path'); } done_testing();

I got Attempt to reload Win32/Backup/Robocopy.pm aborted.

# try using c:\robocopy.exe ok 1 - expected to die with not existent executable --->Win32/Backup/Robocopy.pm # try using C:\Windows\System32\drivers\etc\HOSTS ok 2 - expected to die with not executable file --->Win32/Backup/Robocopy.pm # try using C:\Windows\System32\robocopy.exe Attempt to reload Win32/Backup/Robocopy.pm aborted. Compilation failed in require at .\t\01-ENV.t line 45. BEGIN failed--compilation aborted at .\t\01-ENV.t line 46.

Uncommenting the delete the test runs OK, but why is the module in %INC if the require died? There are better ways to do this?

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.