It's a long title, but I'm afraid I can't take a single word out without losing the true meaning of the question. I'll give a quick description of what I'm trying to achieve first, then a long rambling on why I want it done this way. Skip the rambling if you intend to directly answer abiding with the question title :-)
Quick description
Assuming the existence of a lexicalize
builtin that does just what I want, here goes:
package Whatever;
{
lexicalize $Other::Package::var;
local $var = 42;
Other::Package->do_stuff; # depends on that variable internally
}
Whys and whynots
For a bit of context, I'm whitebox-testing a third-party module.
I want the variable localized because I want it changed for a limited time only, before the tests move on to something else. local
is the best way I found to do this without depending on knowing the module's choice for an initial value.
I want a lexical binding for two main reasons:
- I don't want to pollute the test file's higher-level namespace.
- I want something shorter than the fully-qualified name. It's not in the sample code for brevity, but I use the identifier a lot more than what's shown, with calculations and updates relative to its previous value.
I couldn't decently use our
because it won't grab a variable from another package: “No package name allowed for variable $Other::Package::var in "our".” Cheating to temporarily enter Other::Package's scope doesn't cut it: if I use a block ({ package Other::Package; our $var }
) then the binding doesn't last long enough to be useful; and if I don't (package Other::Package; our @var; package main
) then I need to know and copy the previous package's name, which prevents moving that piece of code around too much.
While doing my homework before asking a previous form of this question, I discovered Lexical::Var
, which seemed like it would be exactly what I needed. Alas: “Can't localize through a reference.”</p>
I've also tried my best on my gut feeling of my *var
-based forms, but kept bumping into syntax errors. I've learned more than I cared to about scoping and binding today :-)
I can't think of a reason why what I want shouldn't be possible, but I can't find the right incantation. Am I asking for an unfortunate unimplemented edge case?