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

No autovivification, for loop aliasing, #15583

Closed
p5pRT opened this issue Sep 2, 2016 · 9 comments
Closed

No autovivification, for loop aliasing, #15583

p5pRT opened this issue Sep 2, 2016 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 2, 2016

Migrated from rt.perl.org#129177 (status was 'rejected')

Searchable as RT129177$

@p5pRT
Copy link
Author

p5pRT commented Sep 2, 2016

From @leszekdubiel

Created by @leszekdubiel

This is after the discussion here​: http​://www.perlmonks.org/?node_id=1171041

Data structure​:

my $n = {
  a => [1, 2 ],
  b => [3, 4],
};

This throws exception​:

@​{$$n{'x'}};

And this doesn't​:

for my $e (@​{$$n{'x'}}) {
}

Maybe it is somehow connected with autovivification.

Here is program​:

#!/usr/bin/perl -CSDA

use utf8;
use strict;
use warnings;
no warnings qw{uninitialized numeric};
no autovivification; # qw{fetch exists delete store};
use Data​::Dumper;

print "\n\ninitialize data structures, no autovivification\n";
my $n = {
  a => [1, 2 ],
  b => [3, 4],
};
$$n{'x'}{'y'}{'z'} and die;
$$n{'x'}{'y'}[0] and die;
$$n{'x'}{'y'} and die;
$$n{'x'} and die;
print "so far, so good, no 'x' autovivified​:\n";
print Dumper $n;

# "Can't use an undefined value as an ARRAY reference"​:
# @​{$$n{'x'}} and die;

print "\n\nnow the same but in loop​:\n";
for my $e (@​{$$n{'x'}}) {
}
print "why 'x' autovivified?\n";
print Dumper $n;

print "\n\nnow the same but in loop​:\n";
for my $e (@​{[ $$n{'y'} ]}) {
}
print "why 'y' NOT autovivified?\n";
print Dumper $n;

Perl Info

Flags:
     category=core
     severity=low

Site configuration information for perl 5.20.2:

Configured by Debian Project at Sun Jul 24 19:46:25 UTC 2016.

Summary of my perl5 (revision 5 version 20 subversion 2) configuration:
    
   Platform:
     osname=linux, osvers=3.16.0-4-amd64, archname=i586-linux-gnu-thread-multi-64int
     uname='linux x86-csail-01 3.16.0-4-amd64 #1 smp debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) i686 gnulinux '
     config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Dldflags= -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=i586-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.20 -Darchlib=/usr/lib/i386-linux-gnu/perl/5.20 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/i386-linux-gnu/perl5/5.20 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.20.2 -Dsitearch=/usr/local/lib/i386-linux-gnu/perl/5.20.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dusesitecustomize -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.20.2 -des'
     hint=recommended, useposix=true, d_sigaction=define
     useithreads=define, usemultiplicity=define
     use64bitint=define, use64bitall=undef, uselongdouble=undef
     usemymalloc=n, bincompat5005=undef
   Compiler:
     cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
     optimize='-O2 -g',
     cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include'
     ccversion='', gccversion='4.9.2', gccosandvers=''
     intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
     d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
     ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
     alignbytes=4, prototype=define
   Linker and Libraries:
     ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
     libpth=/usr/local/lib /usr/lib/gcc/i586-linux-gnu/4.9/include-fixed /usr/include/i386-linux-gnu /usr/lib /lib/i386-linux-gnu /lib/../lib /usr/lib/i386-linux-gnu /usr/lib/../lib /lib
     libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
     perllibs=-ldl -lm -lpthread -lc -lcrypt
     libc=libc-2.19.so, so=so, useshrplib=true, libperl=libperl.so.5.20
     gnulibc_version='2.19'
   Dynamic Linking:
     dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
     cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches:
     DEBPKG:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN.
     DEBPKG:debian/db_file_ver - http://bugs.debian.org/340047 Remove overly restrictive DB_File version check.
     DEBPKG:debian/doc_info - Replace generic man(1) instructions with Debian-specific information.
     DEBPKG:debian/enc2xs_inc - http://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @INC directories.
     DEBPKG:debian/errno_ver - http://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes.
     DEBPKG:debian/libperl_embed_doc - http://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking
     DEBPKG:fixes/respect_umask - Respect umask during installation
     DEBPKG:debian/writable_site_dirs - Set umask approproately for site install directories
     DEBPKG:debian/extutils_set_libperl_path - EU:MM: set location of libperl.a under /usr/lib
     DEBPKG:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor
     DEBPKG:debian/prefix_changes - Fiddle with *PREFIX and variables written to the makefile
     DEBPKG:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets.
     DEBPKG:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor.
     DEBPKG:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy.
     DEBPKG:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable.
     DEBPKG:debian/mod_paths - Tweak @INC ordering for Debian
     DEBPKG:debian/module_build_man_extensions - http://bugs.debian.org/479460 Adjust Module::Build manual page extensions for the Debian Perl policy
     DEBPKG:debian/prune_libs - http://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need.
     DEBPKG:fixes/net_smtp_docs - [rt.cpan.org #36038] http://bugs.debian.org/100195 Document the Net::SMTP 'Port' option
     DEBPKG:debian/perlivp - http://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local
     DEBPKG:debian/deprecate-with-apt - http://bugs.debian.org/747628 Point users to Debian packages of deprecated core modules
     DEBPKG:debian/squelch-locale-warnings - http://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts
     DEBPKG:debian/skip-upstream-git-tests - Skip tests specific to the upstream Git repository
     DEBPKG:debian/patchlevel - http://bugs.debian.org/567489 List packaged patches for 5.20.2-3+deb8u6 in patchlevel.h
     DEBPKG:debian/skip-kfreebsd-crash - http://bugs.debian.org/628493 [perl #96272] Skip a crashing test case in t/op/threads.t on GNU/kFreeBSD
     DEBPKG:fixes/document_makemaker_ccflags - http://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags}
     DEBPKG:debian/find_html2text - http://bugs.debian.org/640479 Configure CPAN::Distribution with correct name of html2text
     DEBPKG:debian/perl5db-x-terminal-emulator.patch - http://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl
     DEBPKG:debian/cpan-missing-site-dirs - http://bugs.debian.org/688842 Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable
     DEBPKG:fixes/memoize_storable_nstore - [rt.cpan.org #77790] http://bugs.debian.org/587650 Memoize::Storable: respect 'nstore' option not respected
     DEBPKG:debian/regen-skip - Skip a regeneration check in unrelated git repositories
     DEBPKG:fixes/regcomp-mips-optim - [perl #122817] http://bugs.debian.org/754054 Downgrade the optimization of regcomp.c on mips and mipsel due to a gcc-4.9 bug
     DEBPKG:debian/makemaker-pasthru - http://bugs.debian.org/758471 Pass LD settings through to subdirectories
     DEBPKG:fixes/perldoc-less-R - [rt.cpan.org #98636] http://bugs.debian.org/758689 Tell the 'less' pager to allow terminal escape sequences
     DEBPKG:fixes/pod_man_reproducible_date - http://bugs.debian.org/759405 Support POD_MAN_DATE in Pod::Man for the left-hand footer
     DEBPKG:fixes/io_uncompress_gunzip_inmemory - http://bugs.debian.org/747363 [rt.cpan.org #95494] Fix gunzip to in-memory file handle
     DEBPKG:fixes/socket_test_recv_fix - http://bugs.debian.org/758718 [perl #122657] Compare recv return value to peername in socket test
     DEBPKG:fixes/hurd_socket_recv_todo - http://bugs.debian.org/758718 [perl #122657] TODO checking the result of recv() on hurd
     DEBPKG:fixes/regexp-performance - [0fa70a0] http://bugs.debian.org/777556 [perl #123743] simpify and speed up /.*.../ handling
     DEBPKG:fixes/failed_require_diagnostics - http://bugs.debian.org/781120 [perl #123270] Report inaccesible file on failed require
     DEBPKG:fixes/array-cloning - http://bugs.debian.org/779357 [perl #124127] [902d169] fix cloning arrays with unused elements
     DEBPKG:fixes/perldb-threads - http://bugs.debian.org/779357 [perl #124127] [41ef2c6] lib/perl5db.pl: Restore noop lock prototype
     DEBPKG:fixes/CVE-2015-8607_file_spec_taint_fix - ensure File::Spec::canonpath() preserves taint
     DEBPKG:fixes/encode-unicode-bom - http://bugs.debian.org/798727 [rt.cpan.org #107043] Address https://rt.cpan.org/Public/Bug/Display.html?id=107043
     DEBPKG:debian/encode-unicode-bom-doc - http://bugs.debian.org/798727 Document Debian backport of Encode::Unicode fix
     DEBPKG:debian/kfreebsd-softupdates - http://bugs.debian.org/796798 Work around Debian Bug#796798
     DEBPKG:fixes/CVE-2016-2381_duplicate_env - remove duplicate environment variables from environ
     DEBPKG:debian/debugperl-compat-fix - [perl #127212] http://bugs.debian.org/810326 Disable PERL_TRACK_MEMPOOL for debugging builds
     DEBPKG:fixes/CVE-2015-8853_regexp_hang - http://bugs.debian.org/821848 [perl #123562] PATCH [perl #123562] Regexp-matching "hangs"
     DEBPKG:fixes/utf8_regexp_crash - http://bugs.debian.org/820328 [perl #124109] save_re_context(): do "local $n" with no PL_curpm
     DEBPKG:fixes/regcomp_whitespace_fix - http://bugs.debian.org/820328 [perl #124109] Perl_save_re_context(): re-indent after last commit
     DEBPKG:fixes/5.20.3/eval_label_crash - http://bugs.debian.org/822336 [perl #123652] eval {label:} crash
     DEBPKG:fixes/5.20.3/preserve_record_separator - http://bugs.debian.org/822336 [perl #123218] "preserve" $/ if set to a bad value
     DEBPKG:fixes/5.20.3/test_count_base_rs - http://bugs.debian.org/822336 Fix test count in t/base/rs.t
     DEBPKG:fixes/5.20.3/remove_get_magic - http://bugs.debian.org/822336 [perl #123739] Remove get-magic from $/
     DEBPKG:fixes/5.20.3/speed_up_scalar_g - http://bugs.debian.org/822336 [perl #123202] speed up scalar //g against tainted strings
     DEBPKG:fixes/5.20.3/accidental_all_features - http://bugs.debian.org/822336 Stop $^H |= 0x1c020000 from enabling all features
     DEBPKG:fixes/5.20.3/multidimensional_arrays_utf8 - http://bugs.debian.org/822336 [perl #124113] Make check for multi-dimensional arrays be UTF8-aware
     DEBPKG:fixes/5.20.3/unquoted_utf8_heredoc_terminators - http://bugs.debian.org/822336 Allow unquoted UTF-8 HERE-document terminators
     DEBPKG:fixes/5.20.3/parentheses_ambiguous_warning_utf8_functions - http://bugs.debian.org/822336 Fix "...without parentheses is ambuguous" warning for UTF-8 function names
     DEBPKG:fixes/5.20.3/leak_namepv_copy - http://bugs.debian.org/822336 [perl #123786] don't leak the temp utf8 copy of namepv
     DEBPKG:fixes/5.20.3/h2ph_hex_constants - http://bugs.debian.org/822336 h2ph: correct handling of hex constants for the preamble
     DEBPKG:fixes/5.20.3/leftbracket_XTERMORDORDOR - http://bugs.debian.org/822336 [perl #123711] Fix crash with 0-5x-l{0}
     DEBPKG:fixes/5.20.3/fatalize_warnings_unwinding - http://bugs.debian.org/822336 [perl #123398] don't fatalize warnings during unwinding (#123398)
     DEBPKG:fixes/5.20.3/setpgrp - http://bugs.debian.org/822336 =?UTF-8?q?Don=E2=80=99t=20treat=20setpgrp($nonzero)=20as=20setpgr?= =?UTF-8?q?p(1)?=
     DEBPKG:fixes/5.20.3/death_unwinding_crash - http://bugs.debian.org/822336 [perl #124156] RT #124156: death during unwinding causes crash
     DEBPKG:fixes/5.20.3/stashpvn_crash - http://bugs.debian.org/822336 [perl #125541] Fix crash with %::=(); J->${\"::"}
     DEBPKG:fixes/5.20.3/possessive_quantifier - http://bugs.debian.org/822336 [perl #125825] PATCH: [perl 125825] {n}+ possessive quantifier broken
     DEBPKG:fixes/5.20.3/quoted_code_crash - http://bugs.debian.org/822336 [perl #123712] Fix /$a[/ parsing
     DEBPKG:fixes/5.20.3/checking_sub_inwhat - http://bugs.debian.org/822336 [perl #123712] Don't check sub_inwhat
     DEBPKG:fixes/5.20.3/yylex_loop - http://bugs.debian.org/822336 Fix hang with "@{"
     DEBPKG:fixes/5.20.3/docs/op - http://bugs.debian.org/822336 Fix apidocs for OP_TYPE_IS(_OR_WAS) - arguments separated by |, not ,.
     DEBPKG:fixes/5.20.3/docs/encoding - http://bugs.debian.org/822336 perlpodspec: Corrections/adds to detecting =encoding
     DEBPKG:fixes/5.20.3/docs/SvPV_set - http://bugs.debian.org/822336 improve SvPV_set's docs, it really shouldn't be public API
     DEBPKG:fixes/5.20.3/docs/autodie - http://bugs.debian.org/822336 Fix warning message regarding "use autodie" and "use open".
     DEBPKG:fixes/5.20.3/docs/autodie_2_26 - http://bugs.debian.org/822336 perlunicook: Note that autodie >= 2.26 should be okay with "use open".
     DEBPKG:fixes/5.20.3/docs/setenv - http://bugs.debian.org/822336 Fix setenv() replacement documentation in perlclib
     DEBPKG:fixes/5.20.3/docs/clib_caution - http://bugs.debian.org/822336 perlhacktips: Add caution about clib ptr returns to static memory
     DEBPKG:fixes/5.20.3/docs/perlunicook_typos - http://bugs.debian.org/822336 Fix minor code typos in perlunicook
     DEBPKG:fixes/5.20.3/docs/ook_example - http://bugs.debian.org/822336 [perl #122322] Update OOK example in perlguts
     DEBPKG:fixes/5.20.3/docs/study_noop - http://bugs.debian.org/822336 perlfunc: mention that study() is currently a noop
     DEBPKG:fixes/CVE-2016-1238/remove-dot-when-loading - [perl #127834] (perl #127834) remove . from the end of @INC if complex modules are loaded
     DEBPKG:fixes/CVE-2016-1238/remove-dot-in-padwalker - [perl #127834] perl5db.pl: ensure PadWalker is loaded from standard paths
     DEBPKG:fixes/CVE-2016-1238/remove-dot-in-dist - [perl #127834] dist/: remove . from @INC when loading optional modules
     DEBPKG:fixes/CVE-2016-1238/remove-dot-in-cpan - [perl #127834] cpan/: remove . from @INC when loading optional modules
     DEBPKG:fixes/CVE-2016-1238/customized-encode - Update customized.dat for cpan/Encode/Encode.pm
     DEBPKG:debian/CVE-2016-1238/test-suite-without-dot - [perl #127810] Patch unit tests to explicitly insert "." into @INC when needed.
     DEBPKG:debian/CVE-2016-1238/eumm-without-dot - [perl #127810] Add PERL_USE_UNSAFE_INC support to EU::MM for fortify_inc support.
     DEBPKG:debian/CVE-2016-1238/cpan-without-dot - [perl #127810] Set PERL_USE_UNSAFE_INC for cpan usage
     DEBPKG:debian/CVE-2016-1238/mb-without-dot - Make Module::Build set PERL_USE_UNSAFE_INC
     DEBPKG:debian/CVE-2016-1238/sitecustomize-in-etc - Look for sitecustomize.pl in /etc/perl rather than sitelib on Debian systems
     DEBPKG:fixes/xsloader-eval - [rt.cpan.org #115808] http://bugs.debian.org/829578 =?UTF-8?q?Don=E2=80=99t=20let=20XSLoader=20load=20relative=20path?= =?UTF-8?q?s?=


@INC for perl 5.20.2:
     /etc/perl
     /usr/local/lib/i386-linux-gnu/perl/5.20.2
     /usr/local/share/perl/5.20.2
     /usr/lib/i386-linux-gnu/perl5/5.20
     /usr/share/perl5
     /usr/lib/i386-linux-gnu/perl/5.20
     /usr/share/perl/5.20
     /usr/local/lib/site_perl


Environment for perl 5.20.2:
     HOME=/root
     LANG=pl_PL.UTF-8
     LANGUAGE (unset)
     LC_ADDRESS=pl_PL.UTF-8
     LC_IDENTIFICATION=pl_PL.UTF-8
     LC_MEASUREMENT=pl_PL.UTF-8
     LC_MONETARY=pl_PL.UTF-8
     LC_NAME=pl_PL.UTF-8
     LC_NUMERIC=pl_PL.UTF-8
     LC_PAPER=pl_PL.UTF-8
     LC_TELEPHONE=pl_PL.UTF-8
     LC_TIME=pl_PL.UTF-8
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11
     PERL_BADLANG (unset)
     SHELL=/bin/bash





@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2016

From @jkeenan

On Fri Sep 02 13​:54​:24 2016, leszek@​dubiel.pl wrote​:

This is a bug report for perl from leszek@​dubiel.pl,
generated with the help of perlbug 1.40 running under perl 5.20.2.

-----------------------------------------------------------------
[Please describe your issue here]

This is after the discussion here​:
http​://www.perlmonks.org/?node_id=1171041

Data structure​:

my $n = {
a => [1, 2 ],
b => [3, 4],
};

This throws exception​:

@​{$$n{'x'}};

And this doesn't​:

for my $e (@​{$$n{'x'}}) {
}

Maybe it is somehow connected with autovivification.

Perhaps it does -- but since you are referencing the 'autovivification' module from CPAN (http​://search.cpan.org/~vpit/autovivification-0.16/lib/autovivification.pm#BUGS), you first have to rule out the possibility that this is a bug in that library. Reports sent to rt.perl.org should be concerned only with the Perl 5 core distribution. The 'autovivification' library is not part of the core distribution.

Please report this problem first to the CPAN maintainer of 'autovivification' via sending mail to​:

bug-autovivification [at] rt.cpan.org

If the discussion there discloses a bug in the Perl 5 core distribution, then we can open a new ticket here or re-open this one.

Here is program​:

#!/usr/bin/perl -CSDA

use utf8;
use strict;
use warnings;
no warnings qw{uninitialized numeric};
no autovivification; # qw{fetch exists delete store};
use Data​::Dumper;

Note for when you report this problem at rt.cpan.org​: Much of what you have above is superfluous for the purpose of filing a bug report. You can and should eliminate the '-CSDA'; the 'use utf8'; and the 'no warnings qw{uninitialized numeric}'. Strip down the code sample to the minimum code that reproduces the problematic behavior.

print "\n\ninitialize data structures, no autovivification\n";
my $n = {
a => [1, 2 ],
b => [3, 4],
};
$$n{'x'}{'y'}{'z'} and die;
$$n{'x'}{'y'}[0] and die;
$$n{'x'}{'y'} and die;
$$n{'x'} and die;
print "so far, so good, no 'x' autovivified​:\n";
print Dumper $n;

# "Can't use an undefined value as an ARRAY reference"​:
# @​{$$n{'x'}} and die;

print "\n\nnow the same but in loop​:\n";
for my $e (@​{$$n{'x'}}) {
}
print "why 'x' autovivified?\n";
print Dumper $n;

print "\n\nnow the same but in loop​:\n";
for my $e (@​{[ $$n{'y'} ]}) {
}
print "why 'y' NOT autovivified?\n";
print Dumper $n;

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2016

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

@p5pRT p5pRT closed this as completed Sep 3, 2016
@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2016

@jkeenan - Status changed from 'open' to 'rejected'

@p5pRT
Copy link
Author

p5pRT commented Sep 3, 2016

From @leszekdubiel

Hello!

Here's striped down version.
What sould I do next? Thank you.

#!/usr/bin/perl

use strict;
use warnings;

my $n = {};

# this is ok...
for (@​{$$n{'x'}}) {
  print 1;
}

# the same throws exception​:
# Can't use an undefined value as an ARRAY reference
@​{$$n{'y'}} and print 2;

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2016

From @jkeenan

On Sat Sep 03 15​:00​:21 2016, leszek@​dubiel.pl wrote​:

Hello!

Here's stripped down version.
What should I do next? Thank you.

Yes, for the purpose of discussing autovivification in general (as distinct from the 'autovivification' pragma on CPAN), this is a better code sample.

The documentation of autovivification in the core distribution is clearly less than satisfactory. By consulting four different doc files (as well as the CPAN autovivification documentation), have pieced together the following explanation which should be treated as a *provisional, layperson's* explanation of the phenomenon. The documentation is somewhat adequate in explaining why array and hash elements autovivify when they do, but -- as you have probably found out already -- quite inadequate in explaining why autovivification does *not* happen where you might expect it to.

So here goes.

Perl autovivifies intermediate elements in data structures when it senses that you need to use the lowest elements in such structures as *storage locations*. In Perl, a storage location is referred to as an *lvalue* (where the 'l' refers to the customary 'left-hand side' or an assignment). The context in which you are assigning a value to a storage location -- or when Perl senses that you are about to assign a value to a storage location -- is referred to as *lvalue context*. When you need to assign a value to an array or hash element that doesn't already exist, Perl will create that elements -- and any elements needed to reach that element -- for you. More formally, when you are in lvalue context, perl will autovivify data structures as needed.

#!/usr/bin/perl

use strict;
use warnings;

my $n = {};

# this is ok...
for (@​{$$n{'x'}}) {
print 1;
}

In the above you are (IMO) in lvalue context. You are saying, "For each element of the array which is the value of a hash element whose key is 'x' -- and where said hash is dereferenced from $n -- I am going to do something which may (or may not) include storing an element in that array. I need that array to exist even if it does not yet have any elements."

Let me slightly rewrite what we've got so far in a more contemporary notation​:

#####
use Data​::Dumper;$Data​::Dumper​::Indent=0;
my $n = {};
for (@​{$n->{'x'}}) {
  print 1;
}
print Dumper ($n), "\n";
#####

Output​:

#####
$VAR1 = {'x' => []};
#####

# the same throws exception​:
# Can't use an undefined value as an ARRAY reference
@​{$$n{'y'}} and print 2;

Here, I would argue, you are *not* in lvalue context. You're not indicating any current or future need to store values in the array which is the value of a hash keyed on 'y'. In fact, if we were to set aside the runtime exception and simply look at the code, we'd probably say, "We're in scalar context; we're asking whether we have a Perl-true (non-zero) number of elements in that array and, if so, we are printing a numeral." Since we're not in lvalue context, there's no call for autovivification of the array, which (I think) renders the array reference undefined.

Here, too, we can update the syntax without changing the problem​:

#####
@​{$n->{'y'}} and print 2;
#####

That triggers the exception you have encountered. But this exception is to be expected.

What should I do next?

We don't really know the real-world context if which you encountering this problem. However, if at this point, what you want to do is to create an array -- initially empty but intended for later storage of values -- and you want that array to be the value of a hash keyed on 'y' in a hash referenced from $n, then you could say​:

#####
$n->{'y'} = [];
print Dumper ($n), "\n";
#####

Together with the 'x' code above, this would now output​:

#####
$VAR1 = {'x' => [],'y' => []};
#####

HTH

References in core distribution​:

cpan/perlfaq/lib/perlfaq4.pod
cpan/perlfaq/lib/perlglossary.pod (definitions for 'autovivification' and 'lvalue')
pod/perlref.pod
pod/perlreftut.pod

P5P​: We need to work a discussion like the above into our documentation of autovivification. Patches welcome!

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2016

From @jkeenan

On Sat Sep 03 17​:26​:00 2016, jkeenan wrote​:

On Sat Sep 03 15​:00​:21 2016, leszek@​dubiel.pl wrote​:

Let me slightly rewrite what we've got so far in a more contemporary
notation​:

#####
use Data​::Dumper;$Data​::Dumper​::Indent=0;
my $n = {};
for (@​{$n->{'x'}}) {
print 1;
}
print Dumper ($n), "\n";
#####

Output​:

#####
$VAR1 = {'x' => []};
#####

# the same throws exception​:
# Can't use an undefined value as an ARRAY reference
@​{$$n{'y'}} and print 2;

Follow-up​: Vincent Pit pointed on irc.perl.org #p5p that this exception is a consequence of your (correct) use of 'use strict;'.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2016

From @cpansprout

The possibility of making foreach refrain from autovivification when possible has been raised before (i.e., it would be considered a bug fix), but it has been put off indefinitely because it would cause a significant slowdown.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Sep 26, 2016

From @ap

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2016-09-04 04​:12]​:

it has been put off indefinitely because it would cause a significant
slowdown.

It’s not just speed. The semantics are serious headache too. Referential
identity is impossible without actually allocating the key, and without
it, you get it into all sorts of fun games regarding the order in which
things happen.

The bug that *could* be fixed is autovivification in *rvalue* context.

But not lvalue context; that would be way too much of a braintwister.

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

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

1 participant