I love my variable and am looking for various ways of using it.
I will show you a bit of code.
$ perl -e 'my $x;$x->{foo}' # OK
$ perl -e '(my $x)->{foo}' # NG
I expected that autovivification would be applied to the
variable in the later case as well as in the first case, but
the results were different.
Therefore I wrote the following patch.
I would like your responses to that.
--- pp_hot.c.orig 2004-05-21 10:49:37.000000000 +0900
+++ pp_hot.c 2004-05-21 10:50:32.000000000 +0900
@@ -202,13 +202,13 @@
dSP; dTARGET;
XPUSHs(TARG);
if (PL_op->op_flags & OPf_MOD) {
- if (PL_op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(PAD_SVl(PL_op->op_targ));
- else if (PL_op->op_private & OPpDEREF) {
+ if (PL_op->op_private & OPpDEREF) {
PUTBACK;
vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
SPAGAIN;
}
+ else if (PL_op->op_private & OPpLVAL_INTRO)
+ SAVECLEARSV(PAD_SVl(PL_op->op_targ));
}
RETURN;
}
regards
--
Shinya Hayakawa
haya...@livedoor.jp
If you look at what contexts permit and forbid autovivification, you'll
see that the situation in perl is currently complex and probably not
very consistent. Anyway, in general lvalue contexts don't permit it; a
lexical declaration can be seen as this; and you still can write, in a
rather obfuscated way,
(my $x = {}) -> {foo}
Your patch looks correct at a first glance, but I'm not very inclined to
apply it, unless the crowd comes up with good reasons why to.
The patch incorrectly removes introduction:
for (1..4) {
(my $x)->{foo} = 1;
print "$_: already exists!!\n" if exists $x->{bar};
$x->{bar} = 1;
}
with the patch outputs:
2: already exists!!
3: already exists!!
4: already exists!!
--
The Enterprise is captured by a vastly superior alien intelligence which
does not put them on trial.
-- Things That Never Happen in "Star Trek" #10
I stand corrected, thanks!
On Friday 21 May 2004 6:29 pm, Dave Mitchell wrote:
> The patch incorrectly removes introduction:
>
> for (1..4) {
> (my $x)->{foo} = 1;
> print "$_: already exists!!\n" if exists $x->{bar};
> $x->{bar} = 1;
> }
>
> with the patch outputs:
>
> 2: already exists!!
> 3: already exists!!
> 4: already exists!!
Thanks.
I rewrote the patch as follows.
--- pp_hot.c.orig 2004-05-21 10:49:37.000000000 +0900
+++ pp_hot.c 2004-05-21 18:43:46.000000000 +0900
@@ -204,7 +204,7 @@
if (PL_op->op_flags & OPf_MOD) {
if (PL_op->op_private & OPpLVAL_INTRO)
SAVECLEARSV(PAD_SVl(PL_op->op_targ));
- else if (PL_op->op_private & OPpDEREF) {
+ if (PL_op->op_private & OPpDEREF) {
PUTBACK;
vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
SPAGAIN;
--
Shinya Hayakawa
haya...@livedoor.jp
Thinking about this some more; it could be argued that since op.c has already
gone to the trouble of marking the padsv op with the OPpDEREF flag, that
its a bug in pp_padsv for then ignoring that flag if it happens also to
be marked with OPpLVAL_INTRO. That is to say, ($x)->{foo} autovivifies
but (my $x)->{foo} doesn't. Clearly the OP's patch was wrong because it
threw out the baby with the bathwater, but maybe something like the
following (untested):
--- pp_hot.c Mon May 3 23:57:33 2004
+++ pp_hot.c+ Fri May 21 11:58:22 2004
@@ -205,7 +205,7 @@
if (PL_op->op_flags & OPf_MOD) {
if (PL_op->op_private & OPpLVAL_INTRO)
SAVECLEARSV(PAD_SVl(PL_op->op_targ));
- else if (PL_op->op_private & OPpDEREF) {
+ if (PL_op->op_private & OPpDEREF) {
PUTBACK;
vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
SPAGAIN;
--
"You're so sadly neglected, and often ignored.
A poor second to Belgium, When going abroad."
-- Monty Python - "Finland"
which is the OP's second version :)
I still don't see why this would be a worthwhile language change. I've
no opinion on this in fact.
I have nothing in principle against including this, except that it is
missing tests. Perhaps you could have a go at adding some tests to
explore the edge cases around this - a good starting point, for example,
would be to find a test case that exposes the problem with your first
attempt at this patch.
Hugo
On Friday 21 May 2004 5:47 pm, Rafael Garcia-Suarez wrote:
> If you look at what contexts permit and forbid autovivification, you'll
> see that the situation in perl is currently complex and probably not
> very consistent. Anyway, in general lvalue contexts don't permit it; a
> lexical declaration can be seen as this;
The current Perl sourcecode may incorporate a mistake in OPpDEREF
what I did before(like OPpLVAL_INTRO).
> and you still can write, in a
> rather obfuscated way,
>
> (my $x = {}) -> {foo}
What you proposed is exactly what I have been doing but
there is nothing I can do apart from the above :-)
If this is successful I will rather prefer to write as follows:
++my $x->{foo} if cond();
...
--
Shinya Hayakawa
haya...@livedoor.jp
my $x if cond()
is a Perl idiom that currently has an undefined behaviour. Unless
someone cleaned that up in the past weeks (while I was recovering
from a death in the family and a dead notebook).
Liz
Speaking of autovivification, how about such cases in reverse, That is,
when non-reference value is assigned with --, ++, +=, etc ? i.e.
perl -le '$x = {}; print ++$x'
You may expect '1' but this prints a random number, or numified version
of "HASH(0xdeadbeef)" plus 1. While this makes sense to those who
knows camel anatomy, this is somewhat asymmetrical and confusing....
[A few minutes later...]
Hey, watch this!
> % perl -le 'my $x=42; $x->[0]=3.14; print $x; print $x->[0]; print
> ref($x)'
> 42
> 3.14
>
> % perl -le 'my $x; $x->[0] = 3.14; print $x; print $x->[0]; print
> ref($x)'
> ARRAY(0x801180)
> 3.14
> ARRAY
See the difference? The first one has 42 assigned a priori. I have
duplicated this even on good old 5.00503, not to mention 5.8.4.
Dan the Camel (?:Ab)user
P.S. I found more of Hawakawa-kun's my abuses at
http://shibuya.pm.org/slides/bkcon2004/hayakawa.pdf
I only hope you don't do that in your PRODUCTION CODES....
> Hey, watch this!
>
> >% perl -le 'my $x=42; $x->[0]=3.14; print $x; print $x->[0]; print
> >ref($x)'
> >42
> >3.14
> >
> >% perl -le 'my $x; $x->[0] = 3.14; print $x; print $x->[0]; print
> >ref($x)'
> >ARRAY(0x801180)
> >3.14
> >ARRAY
>
> See the difference? The first one has 42 assigned a priori. I have
> duplicated this even on good old 5.00503, not to mention 5.8.4.
>
Maybe you should try that again with use strict.
Ronald
You can even nest....
> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e 'print "$x, $x->[0], $x->[0][0]"'
> 42, 3.14, 6.022e+23
And Devel::Peek says as follows. Strangely ROK is nowhere to be seen.
> % perl -MDevel::Peek -le 'my $x=42; $x->[0]=3.14;
> $x->[0][0]=6.022e23;' \
> -e 'Dump $x;Dump $x->[0];Dump $x->[0][0]'
> SV = PVIV(0x801828) at 0x801234
> REFCNT = 1
> FLAGS = (PADBUSY,PADMY,IOK,POK,pIOK,pPOK)
> IV = 42
> PV = 0x401930 "42"\0
> CUR = 2
> LEN = 3
> SV = PVNV(0x811734) at 0x80a924
> REFCNT = 1
> FLAGS = (NOK,POK,pNOK,pPOK)
> IV = 3
> NV = 3.14
> PV = 0x405280 "3.14"\0
> CUR = 4
> LEN = 35
> SV = NV(0x80e814) at 0x80f12c
> REFCNT = 1
> FLAGS = (NOK,pNOK)
> NV = 6.022e+23
And Storable "respects" this undocumented feature....
> % perl -MStorable -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e 'store \$x=>"x"; my $y = retrieve "x"; print "$$y, $$y->[0],
> $$y->[0][0]"'
> 42, 3.14, 6.022e+23
But this magic fades as you modify the value thereof....
> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e '$x=0; print "$x, $x->[0], $x->[0][0]"'
> 0, ,
But when you assign the same initial value it persists.... Maybe thanks
to optimizer ?
> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e '$x=0; print "$x, $x->[0], $x->[0][0]"'
> 42, 3.14, 6.022e+23
> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e '$x+=0; print "$x, $x->[0], $x->[0][0]"'
> 42, 3.14, 6.022e+23
> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
> -e '$x=2*3*7; print "$x, $x->[0], $x->[0][0]"'
> 42, 3.14, 6.022e+23
Dan the Zombie Hunter
Whoa, slow down there! You're missing the forest for the trees.
These are just simple symbolic references.
Ronald
Yes, use strict 'refs' does trap this.
> % perl -Mstrict=refs -le 'my $x=42; $x->[0]=3.14; print "$x, $x->[0]"'
> Can't use string ("42") as an ARRAY ref while "strict refs" in use at
> -e line 1.
That does explain what perl is actually doing. They just turn into
symbolic references.
> % perl -le 'my $x=42; $x->[0]=3.14; print ${"42"}[0]'
> 3.14
> % perl -le 'my $x=42; $x->[0]=3.14; print "42"->[0]'
> 3.14
The latter form is really funny. In a way you can use this as a hidden
global scalar.
That's also why the following worked.
On May 22, 2004, at 05:09, Dan Kogai wrote:
> But when you assign the same initial value it persists.... Maybe
> thanks to optimizer ?
>
>> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
>> -e '$x=0; print "$x, $x->[0], $x->[0][0]"'
>> 42, 3.14, 6.022e+23
>> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
>> -e '$x+=0; print "$x, $x->[0], $x->[0][0]"'
>> 42, 3.14, 6.022e+23
>> % perl -le 'my $x=42; $x->[0]=3.14; $x->[0][0]=6.022e23;' \
>> -e '$x=2*3*7; print "$x, $x->[0], $x->[0][0]"'
>> 42, 3.14, 6.022e+23
Okay. I understand. I think I can go to bed now. But IMHO '->' groks
symbolic references is a bad idea since we already have ${"sym"}
notation already....
Dan the Symbolically Referenced Man
On Friday 21 May 2004 11:04 pm, h...@crypt.org wrote:
> I have nothing in principle against including this, except that it is
> missing tests. Perhaps you could have a go at adding some tests to
> explore the edge cases around this - a good starting point, for example,
> would be to find a test case that exposes the problem with your first
> attempt at this patch.
I wrote the patch which includes the tests.
Thank you so much for your resposes to my
recent mail. Would please indicate me if there
were any mistakes.
--- pp_hot.c.orig 2004-05-21 10:49:37.000000000 +0900
+++ pp_hot.c 2004-05-24 21:20:41.000000000 +0900
@@ -204,7 +204,7 @@
if (PL_op->op_flags & OPf_MOD) {
if (PL_op->op_private & OPpLVAL_INTRO)
SAVECLEARSV(PAD_SVl(PL_op->op_targ));
- else if (PL_op->op_private & OPpDEREF) {
+ if (PL_op->op_private & OPpDEREF) {
PUTBACK;
vivify_ref(PAD_SVl(PL_op->op_targ), PL_op->op_private & OPpDEREF);
SPAGAIN;
--- t/op/my.t.orig 2004-05-24 20:27:08.000000000 +0900
+++ t/op/my.t 2004-05-25 00:01:53.000000000 +0900
@@ -2,7 +2,7 @@
# $RCSfile: my.t,v $
-print "1..31\n";
+print "1..32\n";
sub foo {
my($a, $b) = @_;
@@ -99,3 +99,12 @@
# Supposed to be copy-on-write via force_normal after a THINKFIRST check.
print "$full $fonts{nok}\n";
}
+
+sub foo3 {
+ ++my $x->{foo};
+ print "not " if defined $x->{bar};
+ ++$x->{bar};
+}
+eval { foo3(); foo3(); };
+print "not " if $@;
+print "ok 32\n";
--
Shinya Hayakawa
haya...@livedoor.jp
Thanks, applied to bleedperl as change #22874.
--
In the 70's we wore flares because we didn't know any better.
What possible excuse does the current generation have?