Re: my within brackets
by jwkrahn (Abbot) on Oct 14, 2021 at 20:24 UTC
|
my $y;
...
my ( $x, $y, $z ) = split / +/, $rname;
You will get a warning about an earlier declaration of $y. In this case you could do:
my $y;
...
( my $x, $y, my $z ) = split / +/, $rname;
| [reply] [d/l] [select] |
Re: my within brackets
by LanX (Saint) on Oct 14, 2021 at 18:07 UTC
|
> But, is there some subtle difference my quick test has not uncovered?
It's the same and it's explicitly documented to be so.
See my VARLIST
The rest is standard list assignment.
| [reply] |
|
Win8 Strawberry 5.8.9.5 (32) Thu 10/14/2021 17:49:15
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings -MO=Deparse,-p
my ($u, $v) = split /,/, 'U,V';
print "'$u' '$v' \n";
(my $w, my $x) = split /,/, 'W,X';
print "'$w' '$x' \n";
^Z
use warnings;
use strict 'refs';
(my($u, $v) = split(/,/, 'U,V', 3));
print("'${u}' '${v}' \n");
(my($w, $x) = split(/,/, 'W,X', 3));
print("'${w}' '${x}' \n");
- syntax OK
Win8 Strawberry 5.8.9.5 (32) Thu 10/14/2021 18:54:22
C:\@Work\Perl\monks
>perl -Mstrict -Mwarnings
my ($u, $v) = split /,/, 'U,V';
print "'$u' '$v' \n";
(my $w, my $x) = split /,/, 'W,X';
print "'$w' '$x' \n";
^Z
'U' 'V'
'W' 'X'
Same results with Perl version 5.30.3.1.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
D:\tmp\pm>perl -Mstrict -Mwarnings -MO=Concise
my ($u, $v) = split /,/, 'U,V';
__END__
9 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter v ->2
2 <;> nextstate(main 1 -:1) v:*,&,{,x*,x&,x$,$ ->3
8 <2> aassign[t4] vKS ->9
- <1> ex-list lK ->7
3 <0> pushmark s ->4
6 </> split(/","/)[t3] lK/IMPLIM ->7
4 <$> const[PV "U,V"] s ->5
5 <$> const[IV 3] s ->6
- <1> ex-list lKPRM* ->8
7 <0> padrange[$u:1,2; $v:1,2] RM/LVINTRO,range=2 ->8
- <0> padsv[$u:1,2] sRM*/LVINTRO ->-
- <0> padsv[$v:1,2] sRM*/LVINTRO ->-
- syntax OK
D:\tmp\pm>perl -Mstrict -Mwarnings -MO=Concise
(my $u, my $v) = split /,/, 'U,V';
__END__
9 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter v ->2
2 <;> nextstate(main 1 -:1) v:*,&,{,x*,x&,x$,$ ->3
8 <2> aassign[t4] vKS ->9
- <1> ex-list lK ->7
3 <0> pushmark s ->4
6 </> split(/","/)[t3] lK/IMPLIM ->7
4 <$> const[PV "U,V"] s ->5
5 <$> const[IV 3] s ->6
- <1> ex-list lKPRM* ->8
7 <0> padrange[$u:1,2; $v:1,2] RM/LVINTRO,range=2 ->8
- <0> padsv[$u:1,2] sRM*/LVINTRO ->-
- <0> padsv[$v:1,2] sRM*/LVINTRO ->-
- syntax OK
D:\tmp\pm>
Now, spot the difference! ;-)
| [reply] [d/l] |
|
|
|
|
it's explicitly documented
I had looked at the docs for my and didn't find it very explicit at all. It says "If more than one variable is listed, the list must be placed in parentheses" but makes no reference to having the my statement inside the parenthesis. Or am I missing something subtle in the documentation?
This declaration seems unusual and I don't recall seeing it anywhere else which is why it stood out.
| [reply] [d/l] [select] |
|
this
> "If more than one variable is listed, the list must be placed in parentheses"
means:
If VARLIST is
$x,$y,$z
you must write
my ($x,$y,$z)
The alternative
my $x,$y,$z
would only declare $x because of precedence, like
(my $x),$y,$z
Hence an alternative to what we want is
my $x,my $y,my $z
But since we need a list assignment on the LHS, we still need to put it all into parens
(my $x,my $y,my $z) = split ...
because this
my $x,my $y,my $z = split ...
would only assign to $z because of precedence°, like
(my $x),(my $y),(my $z = split ...)
HTH! :)
Errata
s/declare/assign to/ choroba++
UPDATES
°) Even worse, it would only be a scalar assignment to $z, i.e. the number of possible splits.
| [reply] [d/l] [select] |
Re: my within brackets
by talexb (Chancellor) on Oct 14, 2021 at 19:50 UTC
|
You've already got some answers, but I just wanted to throw my weight behind
my ($pname, $sname) = split / +/, $rname, 2;
as the usual and customary way to write that code. (I would use brackets with the split statement, but that's just my C experience speaking.)
Alex / talexb / Toronto
Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.
| [reply] [d/l] |
|
the usual and customary way to write that code
Yes - I would always write it as my ($x, $y).
It was precisely because it was not written that way that I noticed it as odd!
WRT brackets in the split, I used to include them but have moved away from doing so as I feel it is easier to read without them. There was a time when I used brackets for virtually everything, including print statements! I do use them where they are not strictly necessary any time that precedence might be in less then obvious.
| [reply] [d/l] [select] |
|
| [reply] |
Re: my within brackets
by eyepopslikeamosquito (Archbishop) on Oct 14, 2021 at 23:35 UTC
|
Bod, for future reference, note that B::Deparse is a handy way to see how the Perl parser interprets your code. Running:
> cat bod-oh-my.pl
(my $pname,my $sname)=split / +/,$rname,2;
> perl -MO=Deparse bod-oh-my.pl
my($pname, $sname) = split(/ +/, $rname, 2);
bod-oh-my.pl syntax OK
verifies that your razor-sharp Perl intuitions were spot on today.
Update: In case you're interested, -MO=Deparse feels like an old friend to me,
after using it time after time while testing and verifying Acme::EyeDrops and when
playing golf. :)
| [reply] [d/l] [select] |
|
| [reply] |
Re: my within brackets
by jo37 (Deacon) on Oct 14, 2021 at 20:19 UTC
|
my may be used almost everywhere, as in the common idioms
open my $fh, '<', $file;
or
while (defined (my $it = get_it())) {
do_with_it($it);
}
Greetings, -jo
$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
| [reply] [d/l] [select] |
|
It's more than that. my() even counts as (my) at the grammar level.
Aside from their use of overriding precedence, their use in flow control statements, and their use in function prototypes and parameter lists, parens are syntactically significant in five places:
$x = 4; # Scalar assignment operator (sassign)
($x) = 4; # List assignment operator (aassign)
$x x 4 # String repetition operator (repeat)
($x) x 4 # Scalar repetition operator (repeat/DOLIST)
\$x, $y # The referencing isn't distributed.
\($x, $y) # The referencing is distributed.
use Mod; # Calls import.
use Mod (); # Doesn't call import.
@a = ; # Illegal
@a = (); # Stub operator
my ($x, $y) is considered the same as (my $x, my $y) in all five of those circumstances.
my ($x) = 4; # Same as: (my $x) = 4;
my ($x) x 4 # Same as: (my $x) x 4
\my ($x, $y) # Same as: \(my $x, my $y)
use Mod my(); # Same as: use Mod ();
@a = my(); # Same as: @a = ();
| [reply] [d/l] [select] |
Re: my within brackets
by perlfan (Vicar) on Oct 14, 2021 at 17:49 UTC
|
I can't point to the docs, but it's parenthesis do not affect scope only precedence. There could be some exceptions, but that's generally how I think about it. E.g.,
(my $line); # scoped outside of `while` block
while ($line = <>) {
}
or
while (my $line = <>) { # $line scoped only inside of `while` block
}
Treating my in a distributive way inside the parens shows your implicit understanding. I think. :-) | [reply] [d/l] [select] |
|
$ perl -M5.010 -e'sub f { 4,5,6 } say scalar( my $y = f )'
6
$ perl -M5.010 -e'sub f { 4,5,6 } say scalar( my ($y) = f )'
3
See Re^2: my within brackets above | [reply] [d/l] |