Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autovivification strangeness with returning undef from a function #13896

Open
p5pRT opened this issue Jun 2, 2014 · 4 comments
Open

Autovivification strangeness with returning undef from a function #13896

p5pRT opened this issue Jun 2, 2014 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 2, 2014

Migrated from rt.perl.org#122017 (status was 'open')

Searchable as RT122017$

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2014

From @demerphq

We at $work have been scratching our head about some autovivification
issues.

Prior to this I *thought* I had understood chapter and verse of the
autovivification rules, however the following produces an error and I cant
explain why​:

$ perl -wle'use strict; sub thing { return }; my $subthing= thing()->{foo};'
Can't use an undefined value as a HASH reference at -e line 1.

I contend it should do the same as this​:

$ perl -wle'use strict; sub thing { return }; my $tmp= thing(); my
$subthing= $tmp->{foo};'

Or this​:

$ perl -wle'use strict; my $subthing= (my $x)->{key};'

And that the following two also should do the same thing​:

$ perl -wle'use strict; my $subthing= (undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; my $subthing= (my $x= undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

IMO all of them should autovivify, and/or be more consistent. Even if my
understanding of vivification is broken It seems to me that these two​:

$ perl -wle'use strict; my $subthing= (my $x= undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; my $subthing= (my $x)->{key};'

Should definitely do the same thing (whatever it is).

This affects all perls we have tested on going back to 5.14.

$ ./perl -v

This is perl 5, version 21, subversion 1 (v5.21.1 (v5.21.0-262-g728396c*))
built for x86_64-linux
(with 397 registered patches, see perl -V for more detail)

Copyright 1987-2014, Larry Wall

Perl may be copied only under the terms of either the Artistic License or
the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2014

From @ikegami

On Mon, Jun 2, 2014 at 10​:58 AM, yves orton <perlbug-followup@​perl.org>
wrote​:

# New Ticket Created by yves orton
# Please include the string​: [perl #122017]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=122017 >

We at $work have been scratching our head about some autovivification
issues.

Prior to this I *thought* I had understood chapter and verse of the
autovivification rules, however the following produces an error and I cant
explain why​:

$ perl -wle'use strict; sub thing { return }; my $subthing=
thing()->{foo};'
Can't use an undefined value as a HASH reference at -e line 1.

thing()->{foo} tries to autovivify an rvalue. It should throw an error.

Two surprises for me.

1.

$ perl -wle'use strict; (my $x)->{key} = "abc"; print "ok"'
ok

$ perl -wle'use strict; (my $x = undef)->{key} = "abc"; print "ok"'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; (my $x = undef) = "abc"; print "ok"'
ok

2.

$ perl -wle'use strict; sub f :lvalue { my $x } f() = "abc"; print "ok"'
ok

$ perl -wle'use strict; sub f :lvalue { my $x } f()->{x} = "abc"; print
"ok"'
Can't use an undefined value as a HASH reference at -e line 1.

I contend it should do the same as this​:

$ perl -wle'use strict; sub thing { return }; my $tmp= thing(); my
$subthing= $tmp->{foo};'

Or this​:

$ perl -wle'use strict; my $subthing= (my $x)->{key};'

And that the following two also should do the same thing​:

$ perl -wle'use strict; my $subthing= (undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; my $subthing= (my $x= undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

IMO all of them should autovivify, and/or be more consistent. Even if my
understanding of vivification is broken It seems to me that these two​:

$ perl -wle'use strict; my $subthing= (my $x= undef)->{key};'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; my $subthing= (my $x)->{key};'

Should definitely do the same thing (whatever it is).

This affects all perls we have tested on going back to 5.14.

$ ./perl -v

This is perl 5, version 21, subversion 1 (v5.21.1 (v5.21.0-262-g728396c*))
built for x86_64-linux
(with 397 registered patches, see perl -V for more detail)

Copyright 1987-2014, Larry Wall

Perl may be copied only under the terms of either the Artistic License or
the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 10, 2014

From @cpansprout

On Mon Jun 02 09​:16​:12 2014, ikegami@​adaelis.com wrote​:

On Mon, Jun 2, 2014 at 10​:58 AM, yves orton <perlbug-followup@​perl.org>
wrote​:

# New Ticket Created by yves orton
# Please include the string​: [perl #122017]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=122017 >

We at $work have been scratching our head about some autovivification
issues.

Prior to this I *thought* I had understood chapter and verse of the
autovivification rules, however the following produces an error and I cant
explain why​:

$ perl -wle'use strict; sub thing { return }; my $subthing=
thing()->{foo};'
Can't use an undefined value as a HASH reference at -e line 1.

thing()->{foo} tries to autovivify an rvalue. It should throw an error.

Two surprises for me.

1.

$ perl -wle'use strict; (my $x)->{key} = "abc"; print "ok"'
ok

$ perl -wle'use strict; (my $x = undef)->{key} = "abc"; print "ok"'
Can't use an undefined value as a HASH reference at -e line 1.

$ perl -wle'use strict; (my $x = undef) = "abc"; print "ok"'
ok

Fixing this is not straightforward. It is the ‘my $x’ itself that does the autovivification if it has been flagged to do so at compile time.

We can’t just flag it here, because the scalar assignment (= undef) executes after it, so any vivified value would be stomped on forthwith.

I have often wondered whether it would make things simpler if rv2hv (implied by ->{...}) could do the vivification. But I can’t see how easily to get from point A to point B, since the ‘$foo->{bar}’ in $foo->{bar}{baz} returns PL_sv_undef when it does not vivify and the element does not exist. rv2hv can’t just write a hash reference to PL_sv_undef.

(There is a little bit of handwaving in the preceding paragraph. I haven’t checked my facts lately, but I think that is the basic reason why vivification happens where it does.)

Maybe splitting the vivification behaviour ($foo->{bar} should vivify the element and the later ->{baz} should assign a hash reference to it) is the solution, but I fear it will be a can of worms. (Not that that has deterred me in the past, considering COW and op slabs. :-)

Maybe doing vivification in two places is the solution. But would that slow things down through extra checks? (Though how expensive is an extra SvOK?)

2.

$ perl -wle'use strict; sub f :lvalue { my $x } f() = "abc"; print "ok"'
ok

$ perl -wle'use strict; sub f :lvalue { my $x } f()->{x} = "abc"; print
"ok"'
Can't use an undefined value as a HASH reference at -e line 1.

I thought I had that one working. In fact, I do​:

$ perl5.14.4 -wle'use strict; sub f :lvalue { my $x } f()->{x} = "abc"; print "ok"'
Can't use an undefined value as a HASH reference at -e line 1.
$ perl5.18.1 -wle'use strict; sub f :lvalue { my $x } f()->{x} = "abc"; print "ok"'
ok

--

Father Chrysostomos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants