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 should be ignored when testing for existence #11846

Open
p5pRT opened this issue Jan 4, 2012 · 22 comments
Open

Autovivification should be ignored when testing for existence #11846

p5pRT opened this issue Jan 4, 2012 · 22 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 4, 2012

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

Searchable as RT107528$

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From rcolvin@people.net.au

Created by rcolvin@people.net.au

This is a bug report for perl from rcolvin@​people.net.au,
generated with the help of perlbug 1.33 running under perl v5.6.1.

-----------------------------------------------------------------
When testing the existence of a subkey in a hash, autovivification will create the top level key(s) which means subsequent tests against the top level key(s)
will give the incorrect result.

A simple code example​:

# perl -v
This is perl 5, version 12, subversion 3 (v5.12.3) built for sun4-solaris-thread-multi
# cat perl_bug.pl
#!/bin/perl
use strict;

our %list;

$list{A}{sub} = "VALUE(A)";
$list{B}{sub} = "VALUE(B)";

print "LIST\n";
foreach(sort(keys(%list)))
{
  print "\tKEY​: $_\t \$list{$_}{sub} contains '$list{$_}{sub}'\n";
}
print "\n";

print "TEST #1​: Output TRUE if \$list{A}{sub} present, otherwise output nothing​: EXPECT 'TRUE'\n";
print "\tTRUE\n" if($list{A}{sub});

print "TEST #2​: Ouput TRUE if \$list{C}{sub} present, otherwise output nothing​: EXPECT nothing\n";
print "\tTRUE\n" if($list{C}{sub});

print "TEST #3​: Output LIST again, \$list{C} should not be listed\n";
print "LIST\n";
foreach(sort(keys(%list)))
{
  print "\tKEY​: $_\t \$list{$_}{sub} contains '$list{$_}{sub}'\n";
}

print "TEST #4​: Output TRUE if \$list{D}{sub} defined, otherwise output nothing​: EXPECT nothing\n";
print "\tTRUE\n" if(defined $list{D}{sub});

print "TEST #5​: Output LIST again, \$list{D} should not be listed\n";
print "LIST\n";
foreach(sort(keys(%list)))
{
  print "\tKEY​: $_\t \$list{$_}{sub} contains '$list{$_}{sub}'\n";
}

print print "TEST #6​: Output TRUE if \$list{E}{sub} exists, otherwise output nothing​: EXPECT nothing\n";
print "\tTRUE\n" if(exists $list{E}{sub});

print "TEST #7​: Output LIST again, \$list{E} should not be listed\n";
print "LIST\n";
foreach(sort(keys(%list)))
{
  print "\tKEY​: $_\t \$list{$_}{sub} contains '$list{$_}{sub}'\n";
}

print print "TEST #8​: Output TRUE if \$list{F}{sub}{sub2} defined, otherwise output nothing​: EXPECT nothing\n";
print "\tTRUE\n" if(defined $list{F}{sub}{sub2});

print "TEST #9​: Output LIST again, \$list{E} should not be listed\n";
print "LIST\n";
foreach(sort(keys(%list)))
{
  print "\tKEY​: $_\t \$list{$_}{sub} contains '$list{$_}{sub}'\n";
}

produces the following output​:

LIST
  KEY​: A $list{A}{sub} contains 'VALUE(A)'
  KEY​: B $list{B}{sub} contains 'VALUE(B)'

TEST #1​: Output TRUE if $list{A}{sub} present, otherwise output nothing​: EXPECT 'TRUE'
  TRUE
TEST #2​: Ouput TRUE if $list{C}{sub} present, otherwise output nothing​: EXPECT nothing
TEST #3​: Output LIST again, $list{C} should not be listed
LIST
  KEY​: A $list{A}{sub} contains 'VALUE(A)'
  KEY​: B $list{B}{sub} contains 'VALUE(B)'
  KEY​: C $list{C}{sub} contains ''
TEST #4​: Output TRUE if $list{D}{sub} defined, otherwise output nothing​: EXPECT nothing
TEST #5​: Output LIST again, $list{D} should not be listed
LIST
  KEY​: A $list{A}{sub} contains 'VALUE(A)'
  KEY​: B $list{B}{sub} contains 'VALUE(B)'
  KEY​: C $list{C}{sub} contains ''
  KEY​: D $list{D}{sub} contains ''
TEST #6​: Output TRUE if $list{E}{sub} exists, otherwise output nothing​: EXPECT nothing
1TEST #7​: Output LIST again, $list{E} should not be listed
LIST
  KEY​: A $list{A}{sub} contains 'VALUE(A)'
  KEY​: B $list{B}{sub} contains 'VALUE(B)'
  KEY​: C $list{C}{sub} contains ''
  KEY​: D $list{D}{sub} contains ''
  KEY​: E $list{E}{sub} contains ''
TEST #8​: Output TRUE if $list{F}{sub}{sub2} defined, otherwise output nothing​: EXPECT nothing
1TEST #9​: Output LIST again, $list{E} should not be listed
LIST
  KEY​: A $list{A}{sub} contains 'VALUE(A)'
  KEY​: B $list{B}{sub} contains 'VALUE(B)'
  KEY​: C $list{C}{sub} contains ''
  KEY​: D $list{D}{sub} contains ''
  KEY​: E $list{E}{sub} contains ''
  KEY​: F $list{F}{sub} contains 'HASH(0x369dc)'

Thus, it would be useful if autovivification would ignore creating the top level key(s) when exit or defined is used. Or at least an easy way to disable autovivification in the language rather than having to change code flow or use
no autovivification;
with an external module which may not always be allowable in a production environment.

Perl Info

Flags:
    category=core
    severity=wishlist

Site configuration information for perl v5.6.1:

Configured by epkbjwi at Fri Jul 13 10:42:57 MET DST 2001.

Summary of my perl5 (revision 5.0 version 6 subversion 1) configuration:
  Platform:
    osname=solaris, osvers=2.6, archname=sun4-solaris
    uname='sunos s1 5.6 generic_105181-23 sun4u sparc sunw,ultra-1 '
    config_args='-de'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
    cc='gcc', ccflags ='-fno-strict-aliasing -I/usr/local/include -I/opt/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O',
    cppflags='-fno-strict-aliasing -I/usr/local/include -I/opt/local/include'
    ccversion='', gccversion='2.95.2 19991024 (release)', gccosandvers='solaris2.6'
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, usemymalloc=y, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib -L/opt/local/lib '
    libpth=/usr/local/lib /opt/local/lib /usr/lib /usr/ccs/lib
    libs=-lsocket -lnsl -ldb -ldl -lm -lc
    perllibs=-lsocket -lnsl -ldl -lm -lc
    libc=/lib/libc.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags=' '
    cccdlflags='-fPIC', lddlflags='-G -L/usr/local/lib -L/opt/local/lib'

Locally applied patches:
    


@INC for perl v5.6.1:
    /usr/local/lib/perl5/5.6.1/sun4-solaris
    /usr/local/lib/perl5/5.6.1
    /usr/local/lib/perl5/site_perl/5.6.1/sun4-solaris
    /usr/local/lib/perl5/site_perl/5.6.1
    /usr/local/lib/perl5/site_perl/5.005/sun4-solaris
    /usr/local/lib/perl5/site_perl/5.005
    /usr/local/lib/perl5/site_perl
    .


Environment for perl v5.6.1:
    HOME=/home/erobcol
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH=
    LOGDIR (unset)
    PATH=/home/erobcol/bin:/proj/env/bin/:/usr/atria/bin:/usr/atria/etc:/usr/atria/etc/utils:/usr/bin:/usr/local/bin/:/opt/local/bin/:/usr/sbin:/etc:/usr/ccs/bin:/usr/dt/bin:/usr/bin/X11:/opt/local/X11/bin/:/opt/local/gnu/bin:/usr/local/gnu/bin:/usr/ucb/:/proj/vau/dev/luva_tools/:/opt/csw/bin/:/usr/bin:/usr/openwin/bin:/usr/atria/bin
    PERL_BADLANG (unset)
    SHELL=/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From zefram@fysh.org

Robert Colvin wrote​:

When testing the existence of a subkey in a hash, autovivification
will create the top level key(s)

It's too late to change the default Perl behaviour in this
regard. However, a pragmatic module can change it. See
<http​://search.cpan.org/dist/autovivification/>.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From rcolvin@people.net.au

On Wed Jan 04 08​:48​:23 2012, zefram@​fysh.org wrote​:

Robert Colvin wrote​:

When testing the existence of a subkey in a hash, autovivification
will create the top level key(s)

It's too late to change the default Perl behaviour in this
regard. However, a pragmatic module can change it. See
<http​://search.cpan.org/dist/autovivification/>.

-zefram

Zefram,

agreed, and I threw the autovivification module in and it tested fine.
But in my opinion if the default behaviour is to create the variable
reference when I test for its existence, that is a bug.

I understand that it is too late to change, hence its severity is
"Wishlist".

The pragmatic module however is not always a solution, in some
controlled environments we have, we do not have the ability to add
modules - hence our only solution is a massive overhaul of the code to
add workarounds.

/Rob

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From @ikegami

On Wed, Jan 4, 2012 at 8​:04 AM, Robert Colvin <perlbug-followup@​perl.org>wrote​:

When testing the existence of a subkey in a hash, autovivification will
create the top level key(s) which means subsequent tests against the top
level key(s)
will give the incorrect result.

The operand of C<< exists $list{E}{sub} >> is evaluated before C<< exists

is called, so the dereference vivifies C<< $list{E} >> before C<< exists
is called.

On Wed, Jan 4, 2012 at 11​:47 AM, Zefram <zefram@​fysh.org> wrote​:

It's too late to change the default Perl behaviour in this regard.

It seems to be this is a major complaint among Perl's users. Do we want to
fix this under C<< use 5.xxx; >>?

- Eric

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From @Hugmeir

On Wed, Jan 4, 2012 at 6​:08 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

On Wed, Jan 4, 2012 at 11​:47 AM, Zefram <zefram@​fysh.org> wrote​:

It's too late to change the default Perl behaviour in this regard.

It seems to be this is a major complaint among Perl's users. Do we want to
fix this under C<< use 5.xxx; >>?

Can autovivification or something similar get into the core instead?

@p5pRT
Copy link
Author

p5pRT commented Jan 4, 2012

From @rurban

On Jan 4, 2012 3​:08 PM, "Eric Brine" <ikegami@​adaelis.com> wrote​:

On Wed, Jan 4, 2012 at 8​:04 AM, Robert Colvin <perlbug-followup@​perl.org>
wrote​:

When testing the existence of a subkey in a hash, autovivification will
create the top level key(s) which means subsequent tests against the top
level key(s)
will give the incorrect result.

The operand of C<< exists $list{E}{sub} >> is evaluated before C<< exists

is called, so the dereference vivifies C<< $list{E} >> before C<< exists
is called.

On Wed, Jan 4, 2012 at 11​:47 AM, Zefram <zefram@​fysh.org> wrote​:

It's too late to change the default Perl behaviour in this regard.

It seems to be this is a major complaint among Perl's users. Do we want
to fix this under C<< use 5.xxx; >>?

Absolutely!

- Eric

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From dcmertens.perl@gmail.com

On Wed, Jan 4, 2012 at 3​:08 PM, Eric Brine <ikegami@​adaelis.com> wrote​:

On Wed, Jan 4, 2012 at 8​:04 AM, Robert Colvin <perlbug-followup@​perl.org>wrote​:

When testing the existence of a subkey in a hash, autovivification will
create the top level key(s) which means subsequent tests against the top
level key(s)
will give the incorrect result.

The operand of C<< exists $list{E}{sub} >> is evaluated before C<< exists

is called, so the dereference vivifies C<< $list{E} >> before C<< exists
is called.

On Wed, Jan 4, 2012 at 11​:47 AM, Zefram <zefram@​fysh.org> wrote​:

It's too late to change the default Perl behaviour in this regard.

It seems to be this is a major complaint among Perl's users. Do we want to
fix this under C<< use 5.xxx; >>?

If it is such a major complaint, how might it go about getting changed? I'm
new, so forgive me if this is a faux pas, but it would appear that the
obvious solution would be to pull the autovivification module into core.
After all, the module addresses the OP's concern exactly, it does not break
normal autovivification, and it has a 100% pass rate.

So, what does it take to get something like this into core?

David

--
Sent via my carrier pigeon.

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From zefram@fysh.org

Robert Colvin via RT wrote​:

But in my opinion if the default behaviour is to create the variable
reference when I test for its existence, that is a bug.

It's not a bug. The behaviour is perfectly consistent across operators.
"exists" does not create the hash element that you ask it about.
The autovivification applies to the *hash* in which you looked.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From @ikegami

On Thu, Jan 5, 2012 at 9​:43 AM, David Mertens <dcmertens.perl@​gmail.com>wrote​:

If it is such a major complaint, how might it go about getting changed?
I'm new, so forgive me if this is a faux pas, but it would appear that the
obvious solution would be to pull the autovivification module into core.
After all, the module addresses the OP's concern exactly, it does not break
normal autovivification, and it has a 100% pass rate.

So, what does it take to get something like this into core?

The current (well reasoned) desire is to *remove* modules from the perl
distribution, or at least avoid adding any new modules.

You're saying this module works perfectly well without being bundled into
the perl distribution, so there's no need to include it.

- Eric

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From rcolvin@people.net.au

On Thu Jan 05 06​:44​:30 2012,
dcmertens.perl@​gmail.com
wrote​:

On Wed, Jan 4, 2012 at 3​:08 PM,
Eric Brine
<ikegami@​adaelis.com>
wrote​:

On Wed, Jan 4, 2012 at 8​:04
AM, Robert Colvin
<perlbug-
followup@​perl.org>wrote​:

When testing the existence
of a subkey in a hash,
autovivification
will
create the top level key(s)
which means subsequent
tests against
the top
level key(s)
will give the incorrect
result.

The operand of C<< exists
$list{E}{sub} >> is
evaluated before C<<
exists

is called, so the
dereference vivifies C<< $list
{E} >> before C<<
exists
is called.

On Wed, Jan 4, 2012 at 11​:47
AM, Zefram
<zefram@​fysh.org> wrote​:

It's too late to change the
default Perl behaviour
in this regard.

It seems to be this is a
major complaint among
Perl's users. Do we
want to
fix this under C<< use 5.xxx;
?

If it is such a major
complaint, how might it go about
getting
changed? I'm
new, so forgive me if this is a
faux pas, but it would
appear that the
obvious solution would be to
pull the autovivification
module into
core.
After all, the module addresses
the OP's concern
exactly, it does not
break
normal autovivification, and it
has a 100% pass rate.

So, what does it take to get
something like this into
core?

David

this is certainly one solution,
and possibly the easiest, though,
in my opinion, not necessarily
the correct option as it doesn't
address, as I set it, the root
cause

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From rcolvin@people.net.au

On Thu Jan 05 08​:18​:43 2012,
zefram@​fysh.org wrote​:

Robert Colvin via RT wrote​:

But in my opinion if the
default behaviour is to create
the variable
reference when I test for its
existence, that is a bug.

It's not a bug. The behaviour
is perfectly consistent across
operators.
"exists" does not create the
hash element that you ask it
about.
The autovivification applies to
the *hash* in which you looked.

-zefram

indeed it may be consistent,
though it is ultimately
incorrect! in testing existence
the state of variables are
modified. exists should be a safe
operation and it is therefore
reasonable to expect that it
won't make any modifications

@p5pRT
Copy link
Author

p5pRT commented Jan 5, 2012

From rcolvin@people.net.au

On Thu Jan 05 14​:20​:12 2012,
ikegami@​adaelis.com wrote​:

On Thu, Jan 5, 2012 at 9​:43 AM,
David Mertens
<dcmertens.perl@​gmail.com>wrote​:

If it is such a major
complaint, how might it go about
getting
changed?
I'm new, so forgive me if
this is a faux pas, but it would
appear
that the
obvious solution would be to
pull the autovivification module
into
core.
After all, the module
addresses the OP's concern
exactly, it does
not break
normal autovivification, and
it has a 100% pass rate.

So, what does it take to get
something like this into core?

The current (well reasoned)
desire is to *remove* modules
from the
perl
distribution, or at least avoid
adding any new modules.

You're saying this module works
perfectly well without being
bundled
into
the perl distribution, so
there's no need to include it.

- Eric

true, but pre-supposes that this
is not actually a bug, rather its
a particular operating mode which
is undesirable of has undesired
side effects.

as I stated earlier, I still
beleive this is a bug and so
disabling autovivification
whether by import or in the core
or other means is merely a work
around and not a fix.

I would love to be persuaded
otherwise, but I can see no
benefit to this effect in
autovivification, however I can
see plenty of negatives, and
consider it a logical error in
the expectations of how exists or
defined would operate.

finally whilst this module dies
have, to some degree the desired
effect, it is not always
practical or possible to
introduce external modules,
leaving the only sollution in
long and unnecessary work grounds

if the consensus is that it's not
a bug then so be it, however it
seems I'm not alone in being
tripped up by this side effect.

@p5pRT
Copy link
Author

p5pRT commented Jan 6, 2012

From @pjcj

On Thu, Jan 05, 2012 at 02​:58​:30PM -0800, Robert Colvin via RT wrote​:

On Thu Jan 05 08​:18​:43 2012,
zefram@​fysh.org wrote​:

Robert Colvin via RT wrote​:

But in my opinion if the
default behaviour is to create
the variable
reference when I test for its
existence, that is a bug.

It's not a bug. The behaviour
is perfectly consistent across
operators.
"exists" does not create the
hash element that you ask it
about.
The autovivification applies to
the *hash* in which you looked.

-zefram

indeed it may be consistent,
though it is ultimately
incorrect! in testing existence
the state of variables are
modified. exists should be a safe
operation and it is therefore
reasonable to expect that it
won't make any modifications

From perldoc -f exists​:

  This surprising autovivification in what does not at first--or even
  second--glance appear to be an lvalue context may be fixed in a future
  release.

--
Paul Johnson - paul@​pjcj.net
http​://www.pjcj.net

@p5pRT
Copy link
Author

p5pRT commented Jan 6, 2012

From @demerphq

On 5 January 2012 23​:19, Eric Brine <ikegami@​adaelis.com> wrote​:

On Thu, Jan 5, 2012 at 9​:43 AM, David Mertens <dcmertens.perl@​gmail.com>
wrote​:

If it is such a major complaint, how might it go about getting changed?
I'm new, so forgive me if this is a faux pas, but it would appear that the
obvious solution would be to pull the autovivification module into core.
After all, the module addresses the OP's concern exactly, it does not break
normal autovivification, and it has a 100% pass rate.

So, what does it take to get something like this into core?

The current (well reasoned) desire is to *remove* modules from the perl
distribution, or at least avoid adding any new modules.

If the (unthinking) position of "if we can remove it from the core
then it should be removed" is current policy I would appreciate a
pointer to where it says so.

The reason to do something should never be because we *can*, it should
be because it is *right*.

You're saying this module works perfectly well without being bundled into
the perl distribution, so there's no need to include it.

I consider this module to be in the same category as Scalar​::Util and
as such I personally feel it should be in the core.

cheers,
Yves

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

@p5pRT
Copy link
Author

p5pRT commented Jan 6, 2012

From @cpansprout

On Fri Jan 06 08​:53​:00 2012, demerphq wrote​:

I consider this module to be in the same category as Scalar​::Util and
as such I personally feel it should be in the core.

I think it would be better to make it part of the core itself, resulting
in a far simpler implementation. It could be enable with ‘use v5.xx’,
as someone suggested.

Then, we should probably consider whether it does everything correctly.
(I’m not saying it doesn’t; it just needs to be considered.)

What is the *concept* behind not having exists $foo{bar}{baz} autovivify
$foo{bar}? After all, it’s not exists() that is doing the autovivification.

We need to come up with a concept that works (e.g., autovivification is
a type of lvalue context, so only an outer lvalue context, propagated
down to the rv2hv in question, will cause it) before we do much else.

Otherwise we run the risk of having a model that is not self-consistent,
with buggy edge cases.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jan 7, 2012

From @druud62

On 2012-01-05 23​:58, Robert Colvin via RT wrote​:

in testing existence
the state of variables are
modified. exists should be a safe
operation and it is therefore
reasonable to expect that it
won't make any modifications

Reminds me​:

This also changes the state of $a​:

  my $a = "2";
  ...;
  print "yes" if $a > 0;

If that $a is on a shared memory page, and that numeric test happens in
a child process, it will probably cause the memory page to be really
copied. Which can eat RAM fast.

--
Ruud

@p5pRT
Copy link
Author

p5pRT commented Jan 7, 2012

From @demerphq

On 6 January 2012 20​:31, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Fri Jan 06 08​:53​:00 2012, demerphq wrote​:

I consider this module to be in the same category as Scalar​::Util and
as such I personally feel it should be in the core.

I think it would be better to make it part of the core itself, resulting
in a far simpler implementation.  It could be enable with ‘use v5.xx’,
as someone suggested.

I am fine with that. In fact I generally prefer not to have to use a
module to get access to important language features.

Then, we should probably consider whether it does everything correctly.
 (I’m not saying it doesn’t; it just needs to be considered.)

What is the *concept* behind not having exists $foo{bar}{baz} autovivify
$foo{bar}?  After all, it’s not exists() that is doing the autovivification.

We need to come up with a concept that works (e.g., autovivification is
a type of lvalue context, so only an outer lvalue context, propagated
down to the rv2hv in question, will cause it) before we do much else.

Otherwise we run the risk of having a model that is not self-consistent,
with buggy edge cases.

Agreed.

Yves

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

@p5pRT
Copy link
Author

p5pRT commented Jan 9, 2012

From @ap

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2012-01-06 20​:35]​:

We need to come up with a concept that works (e.g., autovivification
is a type of lvalue context, so only an outer lvalue context,
propagated down to the rv2hv in question, will cause it) before we do
much else.

That sounds good to me. Off the bat I can’t think of a case where I want
autovivification for lower levels when I’m not mutating the last level,
so I can conceive of this as the default and mandatory behaviour.

Maybe Abigail can think of such a case, though.

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Jan 10, 2012

From kstarsinic@gmail.com

I'm looping in Phil Moore, as I recall that autovivification is an
issue he has (or at least once had) rather vehement views on.

Phil, my apologies in advance if you no longer care.

- Kurt

On Sun, Jan 8, 2012 at 7​:39 PM, Aristotle Pagaltzis <pagaltzis@​gmx.de> wrote​:

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2012-01-06 20​:35]​:

We need to come up with a concept that works (e.g., autovivification
is a type of lvalue context, so only an outer lvalue context,
propagated down to the rv2hv in question, will cause it) before we do
much else.

That sounds good to me. Off the bat I can’t think of a case where I want
autovivification for lower levels when I’m not mutating the last level,
so I can conceive of this as the default and mandatory behaviour.

Maybe Abigail can think of such a case, though.

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Jan 10, 2012

From @wphillipmoore

This is pretty amusing.... First of all, I am flattered that my 15
year old flame war with Chip over the introduction of autovivification
into perl5.004 (!!) is remembered by anyone. No apologies necessary.
Quite the contrary, I'm touched that you remembered.

I've been out of the perl5-porters loop for too long, and my knowledge
of perl internals too weak, to really contribute in a meaningful
fashion, though.

The issues I had at the time were primarily due to the fact that while
introducing autovivification was a Really Cool Thing, in terms of
moving the language forward, it was horribly incompatible with
existing perl code. That was really my issue, since this one change
meant that you had to PORT code from pre-5.004 to 5.004 (I might have
the release where this changed wrong -- my memory of flame wars from
the 90's is a little weak :-). If you had code that did this​:

if ( $a->{b}->{c}->{d} ) {
  do something important...
}

and the mere existence of the the intermediate references was
important, your code broke, and broke badly. Merely inspecting
something deep in a large data structure would have the side effect of
autovivifying all the intermediate data structures. For example, if
later in the code, you did this​:

if ( exists $a->{b}->{c} ) {
  burn the data center down
}

Then, BEFORE the change, that deep key didn't exist. AFTER the
change, it did. And that meant we had to rewrite the code as
follows, to effectively port it​:

if ( exists $a->{b} and exists $a->{b}->{c} )

Although, I don't recall if "and" had been added by that time, either.
  While I lack context on this particular issue, I merely ask that
however you solve it, please keep backwards compatibility in mind.

Phil (who is now going to spend the rest of the evening fondly
remembering his days contributing to perl5-porters.....)

On Tue, Jan 10, 2012 at 4​:44 PM, Kurt Starsinic <kstarsinic@​gmail.com> wrote​:

I'm looping in Phil Moore, as I recall that autovivification is an
issue he has (or at least once had) rather vehement views on.

Phil, my apologies in advance if you no longer care.

- Kurt

On Sun, Jan 8, 2012 at 7​:39 PM, Aristotle Pagaltzis <pagaltzis@​gmx.de> wrote​:

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2012-01-06 20​:35]​:

We need to come up with a concept that works (e.g., autovivification
is a type of lvalue context, so only an outer lvalue context,
propagated down to the rv2hv in question, will cause it) before we do
much else.

That sounds good to me. Off the bat I can’t think of a case where I want
autovivification for lower levels when I’m not mutating the last level,
so I can conceive of this as the default and mandatory behaviour.

Maybe Abigail can think of such a case, though.

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Jan 11, 2012

From @nwc10

On Tue, Jan 10, 2012 at 05​:02​:49PM -0500, Phillip Moore wrote​:

This is pretty amusing.... First of all, I am flattered that my 15
year old flame war with Chip over the introduction of autovivification
into perl5.004 (!!) is remembered by anyone. No apologies necessary.
Quite the contrary, I'm touched that you remembered.

I've been out of the perl5-porters loop for too long, and my knowledge
of perl internals too weak, to really contribute in a meaningful
fashion, though.

The issues I had at the time were primarily due to the fact that while
introducing autovivification was a Really Cool Thing, in terms of
moving the language forward, it was horribly incompatible with
existing perl code. That was really my issue, since this one change
meant that you had to PORT code from pre-5.004 to 5.004 (I might have
the release where this changed wrong -- my memory of flame wars from
the 90's is a little weak :-). If you had code that did this​:

if ( $a->{b}->{c}->{d} ) {
do something important...
}

and the mere existence of the the intermediate references was
important, your code broke, and broke badly. Merely inspecting
something deep in a large data structure would have the side effect of
autovivifying all the intermediate data structures. For example, if
later in the code, you did this​:

if ( exists $a->{b}->{c} ) {
burn the data center down
}

Then, BEFORE the change, that deep key didn't exist. AFTER the
change, it did. And that meant we had to rewrite the code as
follows, to effectively port it​:

I'm not sure which change you mean, but I don't think that it can exactly
the one that you describe above, as that code has the same behaviour
under 5.000 as it does now​:

$ ~/Sandpit/5000/bin/perl -le 'if ( $a->{b}->{c}->{d} ) { print }; if ( exists $a-&gt;{b}-&gt;{c} ) { die $] }'
5.000 at -e line 1.

$ perl -le 'if ( $a->{b}->{c}->{d} ) { print }; if ( exists $a-&gt;{b}-&gt;{c} ) { die $] }'
5.012003 at -e line 1.

The only references I can spot to /autoviv/ in the changelog is about
not making subroutine arguments create entries in hashes and arrays.

I think that a relevant thread starts here​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1997-07/msg01063.html

and Larry's response is interesting​:

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/1997-07/msg01091.html

  Alan writes​:
  : What is the reasoning behind this behaviour?
 
  Don't ask me. The original intent was that dereferences should know
  whether they were being called in an rvalue or lvalue context and do
  the appropriate thing, where the appropriate thing for rvalues is the
  propagation of undefinedness all the way out, without autovivication.
  I guess that got busted somewhere along the way. But a lot of people
  have had their fingers in that particular pie, so I couldn't venture to
  guess who to shoot. Any volunteers? :-)
 
  Larry

Nicholas Clark

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

No branches or pull requests

2 participants