Tricky localization/scope question

Randy J. Ray rjray at blackperl.com
Tue Jul 28 01:01:46 BST 2009


So, let's assume there's a module called "Test::Without"[1] that lets you tell
Perl that for the current file/lexical-scope, you want @INC to lie and say that
 a given module/package[2] does not exist in the search path even though it
does. And this module exports a sub called "test_without" that you use
lexically (as opposed to "use Test::Without" which would be processed at
compile-time) in a fashion similar to:

	{
	    test_without 'Compress::Zlib'; # My actual use-case

	    ...
	    eval "$some_code_that_would_load_Compress_Zlib";
	    like($@, qr/.../, "Because I want the absence to cause failure");
	}

The tricky part that I can't seem to quite get right, is how to properly
localize the changes made to @INC so that it gets properly restored when the
scope exits. That is, I don't want the user to have to explicitly "undo" their
previous calls.

This is similar to the "lib" pragma, so I suspect that it's possible. But this
is going to primarily affect library-loading triggered by eval, so I can't
implement it the same way-- lib.pm just changes @INC whenever it's called, so
regardless of scope your @INC will have the state of the result of all "use
lib" and "no lib" calls from the script as a whole (unless they themselves are
in eval'd strings). Alas, pragmata are pretty much always designed to operate
during the compile stage, and I need something controllable during execution.

Anyone know how I might go about this? I'd settle for a solution that looks like:

	{
	    use Test::Without 'Compress::Zlib'; # My actual use-case

	    ...
	    eval "$some_code_that_would_load_Compress_Zlib";
	    like($@, qr/.../, "Because I want the absence to cause failure");
	}

...but that would just be a clever import() implementation, which could just as
easily be my syntactically-sugar "test_without()".

Randy
[1] A reasonably-safe assumption, given that I'm writing it at the moment. I
have a hack in place and would rather have it be more generalized.
[2] Or a regexp, for that matter. This is Perl, after all, and we get such
functionality for free while Java et al struggle with their after-the-fact
regexp libraries.
-- 
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Randy J. Ray      Sunnyvale, CA      http://www.rjray.org   rjray at blackperl.com

Silicon Valley Scale Modelers: http://www.svsm.org


More information about the london.pm mailing list