Skip to content

Infinite loop 'while( each { 1=>'a' } )' #14706

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

Closed
p5pRT opened this issue May 16, 2015 · 14 comments
Closed

Infinite loop 'while( each { 1=>'a' } )' #14706

p5pRT opened this issue May 16, 2015 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented May 16, 2015

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

Searchable as RT125205$

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

From @KES777

This is a bug report for perl from kes-kes@​yandex.ru,
generated with the help of perlbug 1.39 running under perl 5.18.2.

#!/usr/bin/perl

use Modern​::Perl;

my $val = { 1 => 'a' };

#test 1 OK
while( my( $key, $value ) = each %{ $val } ) {
  say "$key $value";
}

#test 2 OK (Why this work if "Type of argument to each on reference must be unblessed hashref or arrayref at ./test.pl line 18."
while( my( $key, $value ) = each %$val ) {
  say "$key $value";
}

#test 3 FAIL not Expected
#while( my( $key, $value ) = each ( 1 => 'a' ) ) {
# say "$key $value";
#}

#test4 OK as Expected (see perldoc each)
my %hash = %{ { 1 => 'a' } }; #same hash as in prev example​: %hash = ( 1 => 'a' )
while( my( $key, $value ) = each %hash ) {
  say "$key $value";
}

#test 5 FAIL not expected (infinite loop)
while( my( $key, $value ) = each %{ { 1 => 'a' } } ) {
  say "$key $value";
}

#test 6 FAIL not Expected (infinite loop)
while( my( $key, $value ) = each { 1 => 'a' } ) {
  say "$key $value";
}

__END__

May you tell me please where I can view status of this BUG report?


Flags​:
  category=core
  severity=critical


Site configuration information for perl 5.18.2​:

Configured by Debian Project at Thu Mar 27 18​:28​:21 UTC 2014.

Summary of my perl5 (revision 5 version 18 subversion 2) configuration​:
 
  Platform​:
  osname=linux, osvers=3.2.0-58-generic, archname=x86_64-linux-gnu-thread-multi
  uname='linux brownie 3.2.0-58-generic #88-ubuntu smp tue dec 3 17​:37​:58 utc 2013 x86_64 x86_64 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.18 -Darchlib=/usr/lib/perl/5.18 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.18.2 -Dsitearch=/usr/local/lib/perl/5.18.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -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.18.2 -des'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -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 -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='4.8.2', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=, so=so, useshrplib=true, libperl=libperl.so.5.18.2
  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 to /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/cpanplus_definstalldirs - http​://bugs.debian.org/533707 Configure CPANPLUS to use the site directories by default.
  DEBPKG​:debian/cpanplus_config_path - Save local versions of CPANPLUS​::Config​::System into /etc/perl.
  DEBPKG​:debian/deprecate-with-apt - http​://bugs.debian.org/702096 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.18.2-2ubuntu1 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/hurd_test_skip_stack - http​://bugs.debian.org/650175 Disable failing GNU/Hurd tests dist/threads/t/stack.t
  DEBPKG​:fixes/manpage_name_Test-Harness - http​://bugs.debian.org/650451 [rt.cpan.org #73399] cpan/Test-Harness​: add NAME headings in modules with POD
  DEBPKG​:debian/makemaker-pasthru - http​://bugs.debian.org/660195 [rt.cpan.org #28632] Make EU​::MM pass LD through to recursive Makefile.PL invocations
  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​:fixes/net_ftp_failed_command - [rt.cpan.org #37700] http​://bugs.debian.org/491062 Net​::FTP​: cope gracefully with a failed command
  DEBPKG​:fixes/perlbug-patchlist - [3541c11] http​://bugs.debian.org/710842 [perl #118433] Make perlbug look up the list of local patches at run time
  DEBPKG​:fixes/module_metadata_security_doc - [68cdd4b] CVE-2013-1437 documentation fix
  DEBPKG​:fixes/module_metadata_taint_fix - [bff978f] http​://bugs.debian.org/722210 [rt.cpan.org #88576] untaint version, if needed, in Module​::Metadata
  DEBPKG​:fixes/IPC-SysV-spelling - http​://bugs.debian.org/730558 [rt.cpan.org #86736] Fix spelling of IPC_CREAT in IPC-SysV documentation
  DEBPKG​:fixes/fix-undef-source -


@​INC for perl 5.18.2​:
  /home/kes/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
  /home/kes/perl5/lib/perl5
  /etc/perl
  /usr/local/lib/perl/5.18.2
  /usr/local/share/perl/5.18.2
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.18
  /usr/share/perl/5.18
  /usr/local/lib/site_perl
  .


Environment for perl 5.18.2​:
  HOME=/home/kes
  LANG=ru_UA.UTF-8
  LANGUAGE=en
  LC_MESSAGES=en_US.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/kes/bin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games​:/usr/local/games
  PERL5LIB=/home/kes/perl5/lib/perl5
  PERL_BADLANG (unset)
  PERL_MB_OPT=--install_base "/home/kes/perl5"
  PERL_MM_OPT=INSTALL_BASE=/home/kes/perl5
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

From @KES777

Subject​: Infinite loop 'while( each { 1=>'a' } )
Message-Id​: <5.18.2_3607_1431762613@​keswork>
Reply-To​: kes-kes@​yandex.ru
To​: perlbug@​perl.org
From​: kes-kes@​yandex.ru

This is a bug report for perl from kes-kes@​yandex.ru,
generated with the help of perlbug 1.39 running under perl 5.18.2.

#!/usr/bin/perl

use Modern​::Perl;

my $val = { 1 => 'a' };

#test 1 OK
while( my( $key, $value ) = each %{ $val } ) {
  say "$key $value";
}

#test 2 OK (Why this work if "Type of argument to each on reference must be unblessed hashref or arrayref at ./test.pl line 18."
while( my( $key, $value ) = each %$val ) {
  say "$key $value";
}

#test 3 FAIL not Expected
#while( my( $key, $value ) = each ( 1 => 'a' ) ) {
# say "$key $value";
#}

#test4 OK as Expected (see perldoc each)
my %hash = %{ { 1 => 'a' } }; #same hash as in prev example​: %hash = ( 1 => 'a' )
while( my( $key, $value ) = each %hash ) {
  say "$key $value";
}

#test 5 FAIL not expected (infinite loop)
while( my( $key, $value ) = each %{ { 1 => 'a' } } ) {
  say "$key $value";
}

#test 6 FAIL not Expected (infinite loop)
while( my( $key, $value ) = each { 1 => 'a' } ) {
  say "$key $value";
}

__END__

May you tell me please where I can view status of this BUG report?
---
Flags​:
  category=core
  severity=critical
---
Site configuration information for perl 5.18.2​:

Configured by Debian Project at Thu Mar 27 18​:28​:21 UTC 2014.

Summary of my perl5 (revision 5 version 18 subversion 2) configuration​:
 
  Platform​:
  osname=linux, osvers=3.2.0-58-generic, archname=x86_64-linux-gnu-thread-multi
  uname='linux brownie 3.2.0-58-generic #88-ubuntu smp tue dec 3 17​:37​:58 utc 2013 x86_64 x86_64 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.18 -Darchlib=/usr/lib/perl/5.18 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.18.2 -Dsitearch=/usr/local/lib/perl/5.18.2 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -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.18.2 -des'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fstack-protector -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 -fstack-protector -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='4.8.2', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=, so=so, useshrplib=true, libperl=libperl.so.5.18.2
  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 to /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/cpanplus_definstalldirs - http​://bugs.debian.org/533707 Configure CPANPLUS to use the site directories by default.
  DEBPKG​:debian/cpanplus_config_path - Save local versions of CPANPLUS​::Config​::System into /etc/perl.
  DEBPKG​:debian/deprecate-with-apt - http​://bugs.debian.org/702096 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.18.2-2ubuntu1 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/hurd_test_skip_stack - http​://bugs.debian.org/650175 Disable failing GNU/Hurd tests dist/threads/t/stack.t
  DEBPKG​:fixes/manpage_name_Test-Harness - http​://bugs.debian.org/650451 [rt.cpan.org #73399] cpan/Test-Harness​: add NAME headings in modules with POD
  DEBPKG​:debian/makemaker-pasthru - http​://bugs.debian.org/660195 [rt.cpan.org #28632] Make EU​::MM pass LD through to recursive Makefile.PL invocations
  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​:fixes/net_ftp_failed_command - [rt.cpan.org #37700] http​://bugs.debian.org/491062 Net​::FTP​: cope gracefully with a failed command
  DEBPKG​:fixes/perlbug-patchlist - [3541c11] http​://bugs.debian.org/710842 [perl #118433] Make perlbug look up the list of local patches at run time
  DEBPKG​:fixes/module_metadata_security_doc - [68cdd4b] CVE-2013-1437 documentation fix
  DEBPKG​:fixes/module_metadata_taint_fix - [bff978f] http​://bugs.debian.org/722210 [rt.cpan.org #88576] untaint version, if needed, in Module​::Metadata
  DEBPKG​:fixes/IPC-SysV-spelling - http​://bugs.debian.org/730558 [rt.cpan.org #86736] Fix spelling of IPC_CREAT in IPC-SysV documentation
  DEBPKG​:fixes/fix-undef-source -

---
@​INC for perl 5.18.2​:
  /home/kes/perl5/lib/perl5/x86_64-linux-gnu-thread-multi
  /home/kes/perl5/lib/perl5
  /etc/perl
  /usr/local/lib/perl/5.18.2
  /usr/local/share/perl/5.18.2
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.18
  /usr/share/perl/5.18
  /usr/local/lib/site_perl
  .

---
Environment for perl 5.18.2​:
  HOME=/home/kes
  LANG=ru_UA.UTF-8
  LANGUAGE=en
  LC_MESSAGES=en_US.UTF-8
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/kes/bin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games​:/usr/local/games
  PERL5LIB=/home/kes/perl5/lib/perl5
  PERL_BADLANG (unset)
  PERL_MB_OPT=--install_base "/home/kes/perl5"
  PERL_MM_OPT=INSTALL_BASE=/home/kes/perl5
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

From @KES777

test.pl

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

From @jkeenan

On Sat May 16 00​:56​:18 2015, kes-kes@​yandex.ua wrote​:

This is a bug report for perl from kes-kes@​yandex.ru,
generated with the help of perlbug 1.39 running under perl 5.18.2.

#!/usr/bin/perl

use Modern​::Perl;

To report a possible error in Perl itself, you should submit the bug report in a manner in which other possible causes of the error are excluded. Modern​::Perl is a library which, if I recall correctly, tries to provide a lot of functionality which has become popular among Perl programmers in the last decade, but it is nonetheless a library which might handle situations differently from Perl itself.

So, for the balance of my response, I'm going to proceed as if you had *not* said 'use Modern​::Perl'. But I will assume at least Perl 5.18.2 -- the version from which you are filing this bug report -- and I will assume 'use strict;' and 'use warnings;'.

my $val = { 1 => 'a' };

#test 1 OK
while( my( $key, $value ) = each %{ $val } ) {
say "$key $value";
}

#test 2 OK (Why this work if "Type of argument to each on reference
must be unblessed hashref or arrayref at ./test.pl line 18."
while( my( $key, $value ) = each %$val ) {
say "$key $value";
}

#test 3 FAIL not Expected
#while( my( $key, $value ) = each ( 1 => 'a' ) ) {
# say "$key $value";
#}

This first gets a warning and then a failure message​:
#####
each on reference is experimental at 125205.pl line 18.

Type of argument to each on reference must be unblessed hashref or arrayref at 125205.pl line 18.
#####

See​: 'perldoc -f each'. The way you are using 'each' above is neither on a hash nor on an array but on its third, experimental version​: "a scalar EXPR, which must hold reference to an unblessed hash or array." Your expression does not hold a reference; hence the error.

#test4 OK as Expected (see perldoc each)
my %hash = %{ { 1 => 'a' } }; #same hash as in prev example​: %hash =
( 1 => 'a' )
while( my( $key, $value ) = each %hash ) {
say "$key $value";
}

#test 5 FAIL not expected (infinite loop)
while( my( $key, $value ) = each %{ { 1 => 'a' } } ) {
say "$key $value";
}

#test 6 FAIL not Expected (infinite loop)
while( my( $key, $value ) = each { 1 => 'a' } ) {
say "$key $value";
}

Since I have to go AFK now, I'll leave analysis of these two cases to others.

Thank you very much.

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

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

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

@p5pRT
Copy link
Author

p5pRT commented May 16, 2015

From [email protected]

kes-kes@​yandex.ua wrote​:

#test 2 OK (Why this work if "Type of argument to each on reference
must be unblessed hashref or arrayref at ./test.pl line 18."
while( my( $key, $value ) = each %$val ) {

It works because this isn't "each on reference". It's the old-style
each on a hash.

#test 5 FAIL not expected (infinite loop)
while( my( $key, $value ) = each %{ { 1 => 'a' } } ) {

This creates a fresh hash each time round the loop, via the {} constructor
expression. Iterating on a fresh hash first returns the first element.
Because you throw the hash away before the next iteration, you never
see that you've reached the end of that hash.

#test 6 FAIL not Expected (infinite loop)
while( my( $key, $value ) = each { 1 => 'a' } ) {

Same again, this time using each on the reference.

-zefram

@p5pRT
Copy link
Author

p5pRT commented May 17, 2015

From @demerphq

On 16 May 2015 at 09​:56, KES <perlbug-followup@​perl.org> wrote​:

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

This is a bug report for perl from kes-kes@​yandex.ru,
generated with the help of perlbug 1.39 running under perl 5.18.2.

#!/usr/bin/perl

use Modern​::Perl;

my $val = { 1 => 'a' };

#test 1 OK
while( my( $key, $value ) = each %{ $val } ) {
say "$key $value";
}

#test 2 OK (Why this work if "Type of argument to each on reference must be unblessed hashref or arrayref at ./test.pl line 18."
while( my( $key, $value ) = each %$val ) {
say "$key $value";
}

#test 3 FAIL not Expected
#while( my( $key, $value ) = each ( 1 => 'a' ) ) {
# say "$key $value";
#}

#test4 OK as Expected (see perldoc each)
my %hash = %{ { 1 => 'a' } }; #same hash as in prev example​: %hash = ( 1 => 'a' )
while( my( $key, $value ) = each %hash ) {
say "$key $value";
}

#test 5 FAIL not expected (infinite loop)
while( my( $key, $value ) = each %{ { 1 => 'a' } } ) {
say "$key $value";
}

#test 6 FAIL not Expected (infinite loop)
while( my( $key, $value ) = each { 1 => 'a' } ) {
say "$key $value";
}

__END__

May you tell me please where I can view status of this BUG report?

As far as I can tell, and I think Zefram agrees, this is not a bug.

Yves

@p5pRT
Copy link
Author

p5pRT commented May 17, 2015

From @kentfredric

May you tell me please where I can view status of this BUG report?

As far as I can tell, and I think Zefram agrees, this is not a bug.

At best, one could potentially submit documentation for perlfunc/each to
clarify this case being not-what-you-expected and why.

--
Kent

*KENTNL* - https://metacpan.org/author/KENTNL

@p5pRT
Copy link
Author

p5pRT commented May 17, 2015

From @jkeenan

Since this is not a bug in Perl, I am taking the ticket for the purpose of closing it within 7 days unless there is further discussion.

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

@p5pRT
Copy link
Author

p5pRT commented May 18, 2015

From @KES777

This creates a fresh hash each time round the loop, via the {} constructor
expression.

I do not agree with you.
http​://perldoc.perl.org/functions/keys.html

for( keys { 1 => 'a', 2 => 'b' } ) {
print "$_\n";
}

As you say this must also creates a fresh hash, but it does not.
( I do not belive that you create temp array for all keys in hash at once and than iterate over it, because it may memory wasting on big hashes) Reading doc carefully I see that you uses some iterator​: "Each hash or array has its own internal iterator, accessed by each, keys, and values". So in case of 'keys'/'values' you **create hash once** and than **iterate** over hash keys/values using its internal iterator.

Because you throw the hash away before the next iteration, you never
see that you've reached the end of that hash.

Becase 'each' access internal iterator of hash in same manner as 'keys'/'values' do. You can use this iterator.

1. What is the benifit of recalculating argument of 'each' for every 'while' iteration?

2. Does this broken in compare to 5.12? print shift split ' ', '1 2';

3. Can I force hash for ( 1 => 'a', 2 => 'b' ) without temporary variable? maybe like​:
while( my( $key, $value ) = each once ( 1 => 'a', 2 => 'b' ) ) {
...
}

or force to not calculate 'each's EXPR on 'while' iterations​:
while( my( $key, $value ) = each once { 1 => 'a', 2 => 'b' } ) {
...
}

@p5pRT
Copy link
Author

p5pRT commented May 18, 2015

From [email protected]

KES wrote​:

for( keys { 1 => 'a', 2 => 'b' } ) {

Different case. A while loop evaluates its conditional expression each
time round the loop. Your while/each loop therefore evaluates the each {}
expression each time round the loop, which creates a fresh hash each time.
But a foreach loop evaluates its list expression only once per execution
of the loop as a whole, to produce a list of elements to subsequently
iterate over. So this foreach/keys loop evaluates the keys {} expression
once, creating one hash. The keys operator immediately iterates over the
entire hash to produce the list of keys, and the hash is then discarded.
*Then* the foreach iteration begins, iterating over the temporarily-saved
list of keys and executing the body once for each of those keys.

As you say this must also creates a fresh hash, but it does not.

It creates a fresh hash once per execution of the whole foreach loop.
Totally different from the while loop.

( I do not belive that you create temp array for all keys in hash
at once and than iterate over it, because it may memory wasting on
big hashes)

That's what it does, wasteful or not. Except that technically we don't
call it an "array" because it's not reified as an array object; the
list of keys sits on an internal stack. It's an array in the C sense
but not in the Perl sense.

"Each hash or array has its own internal iterator, accessed by each,
keys, and values".

This refers to the well-known side effect that the keys and values
operators interfere with each, because they internally use the same
iterator. They reset the iterator, use it to iterate over the entire
hash at once, and leave the iterator reset again. This side effect is
sometimes used deliberately, just to restart iteration that's using each.

You can see this resetting effect by comparing these two loops​:

$ perl -lwe '%a=(a=>1,b=>2,c=>3); while ($_ = each %a) { print $_; }'
c
a
b
$ perl -lwe '%a=(a=>1,b=>2,c=>3); while ($_ = each %a) { print $_; keys %a; }' |head -4
c
c
c
c

This means that there is practical utility in that `wasteful' behaviour
of getting the entire key list up front​: it means that the hash iterator
can be safely used in other ways during the loop body. Not an issue in
your example where the hash is anonymous and not accessible outside the
loop control expression, but I have on occasion fixed bugs by changing
a while/each loop into foreach/keys.

              So in case of 'keys'/'values' you \*\*create hash once\*\*

and than **iterate** over hash keys/values using its internal iterator.

The keys operator does all the hash iteration in one go. With the choice
between foreach/keys and while/each, you have a choice between doing all
the hash iteration up front and doing it as part of your loop structure.
There's more than one way to do it.

1. What is the benifit of recalculating argument of 'each' for every 'while' iteration?

It is fundamental to the while operator that it evaluates the conditional
expression anew each time round the loop. That implies recalculating
all the subexpressions. Consistency in these semantics is important to
make the language usable. Any subexpression that you don't want to be
re-evaluated on each iteration needs to be lifted out of the loop, as in​:

  my $h = { 1 => "a", 2 => "b" };
  while(my($key, $value) = each %$h) {

2. Does this broken in compare to 5.12? print shift split ' ', '1 2';

shift is another of the operators to which the experimental implicit
dereferencing applies. That was introduced in Perl 5.14, which means
that the error message that you get (and the time when you get it)
has changed between 5.12 and 5.14. Neither Perl version is broken,
but that expression is broken on any version.

3. Can I force hash for ( 1 => 'a', 2 => 'b' ) without temporary variable? maybe like​:
while( my( $key, $value ) = each once ( 1 => 'a', 2 => 'b' ) ) {

That doesn't quite make sense, because you don't have a hash constructor
expression there. But your other version​:

or force to not calculate 'each's EXPR on 'while' iterations​:
while( my( $key, $value ) = each once { 1 => 'a', 2 => 'b' } ) {

is precisely possible, using a module from CPAN​:

  use Memoize​::Once qw(once);
  while( my( $key, $value ) = each once { 1 => 'a', 2 => 'b' } ) {

See also the quite similar Memoize​::Lift. However, these operators cause
the subexpression, in this case the hash constructor, to be executed
once *per program run*, which may not be what you want. It's quite
different from the once per loop execution that you get from foreach/keys.

-zefram

@p5pRT
Copy link
Author

p5pRT commented May 18, 2015

From @KES777

Ok, thank you for your explanation.
I agree that EXPR must be calculated for each iteration of while, but, I think, it will be more sence if arguments of each will be calculated once

18.05.2015, 19​:37, "Zefram via RT" <perlbug-followup@​perl.org>​:

KES wrote​:

for( keys { 1 => 'a', 2 => 'b' } ) {

Different case.  A while loop evaluates its conditional expression each
time round the loop.  Your while/each loop therefore evaluates the each {}
expression each time round the loop, which creates a fresh hash each time.
But a foreach loop evaluates its list expression only once per execution
of the loop as a whole, to produce a list of elements to subsequently
iterate over.  So this foreach/keys loop evaluates the keys {} expression
once, creating one hash.  The keys operator immediately iterates over the
entire hash to produce the list of keys, and the hash is then discarded.
*Then* the foreach iteration begins, iterating over the temporarily-saved
list of keys and executing the body once for each of those keys.

As you say this must also creates a fresh hash, but it does not.

It creates a fresh hash once per execution of the whole foreach loop.
Totally different from the while loop.

( I do not belive that you create temp array for all keys in hash
at once and than iterate over it, because it may memory wasting on
big hashes)

That's what it does, wasteful or not.  Except that technically we don't
call it an "array" because it's not reified as an array object; the
list of keys sits on an internal stack.  It's an array in the C sense
but not in the Perl sense.

"Each hash or array has its own internal iterator, accessed by each,
keys, and values".

This refers to the well-known side effect that the keys and values
operators interfere with each, because they internally use the same
iterator.  They reset the iterator, use it to iterate over the entire
hash at once, and leave the iterator reset again.  This side effect is
sometimes used deliberately, just to restart iteration that's using each.

You can see this resetting effect by comparing these two loops​:

$ perl -lwe '%a=(a=>1,b=>2,c=>3); while ($_ = each %a) { print $_; }'
c
a
b
$ perl -lwe '%a=(a=>1,b=>2,c=>3); while ($_ = each %a) { print $_; keys %a; }' |head -4
c
c
c
c

This means that there is practical utility in that `wasteful' behaviour
of getting the entire key list up front​: it means that the hash iterator
can be safely used in other ways during the loop body.  Not an issue in
your example where the hash is anonymous and not accessible outside the
loop control expression, but I have on occasion fixed bugs by changing
a while/each loop into foreach/keys.

                   So in case of 'keys'/'values' you **create hash once**
and than **iterate** over hash keys/values using its internal iterator.

The keys operator does all the hash iteration in one go.  With the choice
between foreach/keys and while/each, you have a choice between doing all
the hash iteration up front and doing it as part of your loop structure.
There's more than one way to do it.

1. What is the benifit of recalculating argument of 'each' for every 'while' iteration?

It is fundamental to the while operator that it evaluates the conditional
expression anew each time round the loop.  That implies recalculating
all the subexpressions.  Consistency in these semantics is important to
make the language usable.  Any subexpression that you don't want to be
re-evaluated on each iteration needs to be lifted out of the loop, as in​:

        my $h = { 1 => "a", 2 => "b" };
        while(my($key, $value) = each %$h) {

2. Does this broken in compare to 5.12? print shift split ' ', '1 2';

shift is another of the operators to which the experimental implicit
dereferencing applies.  That was introduced in Perl 5.14, which means
that the error message that you get (and the time when you get it)
has changed between 5.12 and 5.14.  Neither Perl version is broken,
but that expression is broken on any version.

3. Can I force hash for ( 1 => 'a', 2 => 'b' ) without temporary variable? maybe like​:
while( my( $key, $value ) =  each once ( 1 => 'a', 2 => 'b' ) ) {

That doesn't quite make sense, because you don't have a hash constructor
expression there.  But your other version​:

or force to not calculate 'each's  EXPR on 'while' iterations​:
while( my( $key, $value ) =  each once { 1 => 'a', 2 => 'b' } ) {

is precisely possible, using a module from CPAN​:

        use Memoize​::Once qw(once);
        while( my( $key, $value ) =  each once { 1 => 'a', 2 => 'b' } ) {

See also the quite similar Memoize​::Lift.  However, these operators cause
the subexpression, in this case the hash constructor, to be executed
once *per program run*, which may not be what you want.  It's quite
different from the once per loop execution that you get from foreach/keys.

-zefram

@p5pRT p5pRT closed this as completed May 18, 2015
@p5pRT
Copy link
Author

p5pRT commented May 18, 2015

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

@p5pRT
Copy link
Author

p5pRT commented May 18, 2015

From @ap

* KES <kes-kes@​yandex.ua> [2015-05-18 19​:20]​:

I agree that EXPR must be calculated for each iteration of while, but,
I think, it will be more sence if arguments of each will be calculated
once

No. That would require a combination of several special cases, and that
would be worse than your surprise in this case.

  “Any language that doesn't occasionally surprise the novice
  will pay for it by continually surprising the expert.” —Larry Wall

Now you know how it works. So just store it in a variable and move on.

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