http://qs321.pair.com?node_id=787348

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

Is there a statement that has the same “temporary, dynamic scoping” effect for lexicals as local does for global variables? That is, is there something like my_local that will allow me to write
my $x = 1; my $f = sub { $x }; { my_local $x = 2; print $f->(), "\n"; # => 2 } print $f->(), "\n"; # => 1
Of course, I could just put my $temp = $x; $x = 2 at the top of the scope and $x = $temp at the end (or possibly even get fancy and use Guard or one of its variants to put everything at the beginning of the scope), but this isn't completely satisfactory: For example, if $x starts off tied, then it will no longer be after my $temp = $x; $x = $temp 5.

UPDATE 1: Bloodnok and ELISHEVA suggested that things might be clearer if I mentioned why I actually want to do this. I have a number of dastardly intentions, but perhaps the simplest is that I'd like to be able to write

sub lambda { my $f = $_[1]; for my $x ( $_[0] ) { return sub { local $x = $_[0]; return $f->(); } } }
(with some modification to handle multiple arguments) so that lambda $x => sub { $x**2 } is another way of writing sub { $_[0]**2 }.

UPDATE 2: All right, so this is a bad example, because replacing my $x by our $x (with no other change) makes everything work fine. Nonetheless, it still seems to me like something one might want to do, and ikegami 7 and Arunbear offer interesting internals-based approaches. tye describes how to leverage a nice observation of tilly's to do it in a more elementary way 3. Thanks for all the useful and enlightening responses!

UPDATE 3: But, unfortunately, it doesn't work.

UPDATE 4: Looking more closely at ikegami and Arunbear's solutions makes it seem 6 that everything boils down to copying out the value of a variable at the beginning of a scope and doing some trickery to copy it back in at the beginning end. What I'm looking for is something that doesn't do any copying, but, rather, literally sets aside the variable and then restores it later. (The difference between copying and not is made most apparent by naughty tied variables, as in the discussion Re^2: Local for lexicals (KISS) (and descendants) below with tye.) However, testing seems to show that even local as it stands doesn't really do this (see Re^6: Local for lexicals (untie)), so perhaps this is just a fool's quest (which I think some people have been saying since the beginning anyway :-P ).

UPDATE 5: Yes it will; it just might not have the same value as it did originally.

UPDATE 6: Falsely; see Re: Local for lexicals.

UPDATE 7: But see Re^2: Local for lexicals.

UPDATE 8: Those intermingled updates were getting pretty illegible; hopefully this is easier. I don't know how to (or whether I should) link to footnotes within my own comment, so I'll just leave others to navigate manually.