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

Re: `local` on lexicals (2) - sorry

Thread Previous | Thread Next
From:
shmem
Date:
August 10, 2021 00:05
Subject:
Re: `local` on lexicals (2) - sorry
Message ID:
alpine.DEB.2.21.2108100203580.4388@mgm-net.de
Ooops. I hit Ctrl-x instead of Ctrl-c. Please ignore.

From the keyboard of shmem [10.08.21,02:03]:

> From the keyboard of Paul "LeoNerd" Evans [09.08.21,15:19]:
>
>> 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.
>
> This opens a tin of worms, the tin being "scoping" and the worms "rules".
>
> People already have a hard time grokking the differences between local,
> package global and "global global" scope, the differenres between "my"
> and "our" and the aliasing effect of "our" in a multiple package file.
>
> Quick, what would sub foo print here?
>
>    my $x = "outer";
>
>    if (1) {
> 	my $x = "cond inner";
> 	foo();
>    }
>
>    sub foo {
> 	print "$x\n";
>    }
>
> And what would it print if that line were in place?
>
> 	local $x = "cond inner";
>
>> 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 main difference between lexical my variables and localized globals
> is their behavior in space vs. time in a programmer's view, not so much
> the difference between moving away the variable or the value.
> Lexicals are bound to a scope, e.g. a block i.e. in space, localized
> variables are visible in the entire code path starting from where the
> localizing took place, until its conclusion.
>
> Said otherwise, local is for localizing and aliasing a global, whereas
> "my" says: "this is mine, it pertains to here" and to pass it around
> you have to explicitly do so, as parameter to a subroutine, taking a
> ref from it or whatever.
>
> A "local my $foo" blurs that difference and introduces a "timely" scoping
> for lexicals. Or wouldn't it? Anyways, aliasing a lexical would need another
> metaphor and a different keyword than "local". Perhaps "alias"?
>
> "local" is about localizing a global; aliasing a lexical is a different
> thing, and
>
>> 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
>> 
>> 
>
> 0--gg-
>
>

0--gg-

-- 
_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                               /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
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