develooper Front page | perl.perl5.porters | Postings from August 2021

`local` on lexicals

Thread Next
From:
Paul "LeoNerd" Evans
Date:
August 9, 2021 14:20
Subject:
`local` on lexicals
Message ID:
20210809151859.60e1c188@shy.leonerd.org.uk
Perl currently does not permit this:

  $ perl -E 'my $x = 123; { local $x = 456; say $x }'
  Can't localize lexical variable $x at -e line 1.

Various reasons for this, mostly around "ugh, but local moves the
variable, not the value". The vast majority of users don't want to use
it like that though - they care more about the value, the effect of
temporarily assigning a new value to the variable. Moving the variable
out of a package, hash or array is basically equivalent to saving the
value anyway, so most people don't notice the difference. This explains
why it doesn't work on plain lexicals.

The upshot is that it's not very convenient. Perhaps back in the 5.6
era that wasn't too bad - there weren't really any situations where
localizing a lexical would make much sense. But in more modern
scenarios there are two big cases that come to mind:

  1) aliased lexicals:

    $ perl -E 'use experimental qw(declared_refs refaliasing);
       my @arr = (qw( a b c ));
       my \$a1 = \$arr[1];
       local $a1 = "d";'
    Can't localize lexical variable $a1 at -e line 1.

  2) Object::Pad instance slots:

    $ perl -MObject::Pad -E 'class Thing {
       has $x;
       method m { local $x = 123 }
    }'
    Can't localize lexical variable $x at -e line 1.

I wonder.. since we have save_item() these days, whether `local on a
lexical` should just use that. If it did then both of these cases would
DWIM.

At this point I'll state my interest: I've been converting more of my
existing Perl code to using Object::Pad, and while almost everything
comes out looking a lot neater, there's one slight akwardness in code
that currently does

  sub m
  {
    my $self = shift;
    local $self->{something} = 123;
    $self->othermethod;
  }

I can't just write this as

  method m
  {
    local $something = 123;
    $self->othermethod;
  }

due to theabove problem. There isn't in fact a neat way to write this.

I did create Syntax::Keyword::Dynamically to solve this, among other
problems; but it seems a bit heavyweight to drag it in just for this.

  https://metacpan.org/pod/Syntax::Keyword::Dynamically

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

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