When writing tests, the general boilerplate for optional tests which are totally skipped when a module is not installed, is:
eval "use Test::Pod 1.18"; plan skip_all => "Test::Pod 1.18 required for testing POD" if $@;
And then we remember that "eval STRING
" must not be used where "eval BLOCK
" may be enough. So I was tempted to write (and did it a few times):
eval { use Test::Pod 1.18 }; plan skip_all => "Test::Pod 1.18 required for testing POD" if $@;
This has the horrible disadvantage of not working ;-) The essential difference of "eval STRING
" and "eval BLOCK
" are that compilation issues are deferred in the former while happening earlier (at compile time) in the later. But the "use Foo
" thing is a compile-time statement and then, as soon as Perl compiles the code, it executes the equivalent BEGIN
block which will thus fail noisily.
$ perl -e "eval { use Foo };" Can't locate Foo.pm in @INC (@INC contains: ... ) at -e line 1. BEGIN failed--compilation aborted at -e line 1.In turn,
eval "use Foo"
will do the right thing, executing the loading of the module at the opportune moment and storing the error message in $@
if that's the case. If you insist, you may use "eval BLOCK
" yet in an expanded form:
eval { require Foo; Foo->VERSION(2.3); Foo->import }
(That's exactly how rjbs did it in one of his recent distributions.)
Well, of course you knew that. But now that I wrote it, I don't even have to articulate it again some next time.
And now a shameless plug: one of the reasons Devel::Hide was written was to allow me to test code which should fail gracefully when certain modules are not present. Even in a machine, where those modules are indeed installed.
$ perl -Mblib t/99_pod.t 1..30 ok 1 - Foo.pm ... ok 30 - Bar.pm $ perl -Mblib -MDevel::Hide=Test::Pod t/99_pod.t Devel::Hide hides Test/Pod.pm 1..0 # Skip Test::Pod 1.18 required for testing POD