develooper Front page | perl.perl5.porters | Postings from January 2022

Re: Can't localize lexical variable $x at ...

Thread Previous | Thread Next
From:
hv
Date:
January 25, 2022 17:05
Subject:
Re: Can't localize lexical variable $x at ...
Message ID:
202201251559.20PFxwP24307@crypt.org
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
:On Tue, 25 Jan 2022 13:20:17 +0000
:hv@crypt.org wrote:
:
:> Why can't we? I think I might have known the answer once, but if I did
:> I no longer recall it.
:> 
:> I think of local() as "temporarily replace the value at this lvalue
:> with a new value, restore it at the end of the current lexical scope".
:> This is hugely useful in many situations that would otherwise require
:> more and slower code with much more opportunity for error.
:
:People often think of `local` as being equivalent to saving the old
:value of a variable, assigning a new value, and arranging to assign the
:new value back in. Perhaps equivalent to this using our new `defer`
:blocks:
:
:    {
:      my $saved_VAR = $VAR;
:      defer { $VAR = $saved_VAR; }
:      $VAR = $new;
:
:      ...
:    }
:
:That's not really how it works at all though - don't forget that
:`local` is a very old Perl feature that massively predates `my`
:variables. In fact, `local` isn't about values but about variables.

It would probably be useful to have examples where that distinction
makes a difference - I didn't see any (explicit) mention of that in
the lengthy perlsub section about local, nor in S::K::D. Are there
cases where changing an existing valid local() invocation to use
dynamically() instead would change the behaviour? My guess would be
that if anything it would revolve around magic.

[...]
:My preference would be to add a new keyword (because "local" is a
:terrible name anyway) to have the effect of temporarily assigning a new
:*value* to any lvalue expression, and arranging for its old value to be
:restored again at end of scope. In fact I already wrote a module to
:provide a `dynamically` keyword doing just that:
:
:  https://metacpan.org/pod/Syntax::Keyword::Dynamically

Yes, thanks; Ovid already mentioned this.

I confess I don't understand the choice of "dynamically" for the name:
"temporarily" would seem the obvious choice to me (and I'd very much
want to abbreviate that to "temp"). "dynamic" is a concept with a few
specific meanings in perl jargon and lots more outside of that: I think
few average perl users would instinctively guess the correct meaning
in this context.

:As compared `local` it has three key differences:
:
:  1) Can `dynamically` modify a regular lexical variable
:
:  2) Can `dynamically` modify any lvalue-returning function or method.
:     Very handy for accessor-type methods on objects:
:
:       dynamically $logger->level = LOG_DEBUG;
:
:  3) Interacts with the `async/await` syntax provided by
:     Future::AsyncAwait, to properly swap the values around when context
:     switching:
:
:       async sub f {
:         dynamically $logger->level = LOG_DEBUG;
:
:         await some_operation();
:
:         $logger->print( "Still in debug level here" );
:       }
:
:Bringing this keyword into perl core would be easy enough for the first
:two points, but the third would be a tough sell because it first
:depends on having async/await implemented in core. Arguing that into
:perl core at the moment would be a Fun and Exciting challenge ;)

As a module it does not appear to require Async even be installed, could
it not continue to act as it does now? Or is the problem that it could
not then easily be adapted (via a new release) to unknown future async
changes? Or just that it's not the done thing for core code to have
special handling for non-core modules?

I would have thought the apparent need to recompile after installing
DMD would be the bigger problem.

Hugo

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About