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.


In reply to Local for lexicals by JadeNB

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.