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

substitution operator with undef #13723

Open
p5pRT opened this issue Apr 9, 2014 · 5 comments
Open

substitution operator with undef #13723

p5pRT opened this issue Apr 9, 2014 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 9, 2014

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

Searchable as RT121610$

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2014

From [email protected]

There was an idea that any operation on strings should stringify output
http​://www.nntp.perl.org/group/perl.perl5.porters/2014/04/msg214205.html

Below test shows that there are inconsistencies with that rule.

use strict;
use warnings;

my $a = undef;
$a =~ s/x/z/;
print "a undefined\n" if ! defined $a;

my $b = undef;
$b =~ s//z/;
print "b defined\n" if defined $b;
__END__
perl-5.19.10

Use of uninitialized value $a in substitution (s///) at undef_str.pl line 5.
a undefined
Use of uninitialized value $b in substitution (s///) at undef_str.pl line 9.
Use of uninitialized value $b in substitution (s///) at undef_str.pl line 9.
b defined

Note that does not stringify undef first time (but prints a warning),
and it prints two warnings (instead of one) second time.

perl-5.19.10

Summary of my perl5 (revision 5 version 19 subversion 10) configuration​:

  Platform​:
  osname=linux, osvers=3.8.0-37-generic, archname=x86_64-linux
  uname='linux green-u 3.8.0-37-generic #53~precise1-ubuntu smp wed
feb 19 21​:37​:54 utc 2014 x86_64 x86_64 x86_64 gnulinux '
  config_args='-de -Dprefix=/home/perlbrew/perls/perl-5.19.10
-Dusedevel -Aeval​:scriptdir=/home/perlbrew/perls/perl-5.19.10/bin'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.6.3', 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
/usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
/usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu
/lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
  libs=-lnsl -lgdbm -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.15'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'

Characteristics of this binary (from libperl)​:
  Compile-time options​: HAS_TIMES PERLIO_LAYERS PERL_DONT_CREATE_GVSV
  PERL_HASH_FUNC_ONE_AT_A_TIME_HARD PERL_MALLOC_WRAP
  PERL_NEW_COPY_ON_WRITE PERL_PRESERVE_IVUV
  PERL_USE_DEVEL USE_64_BIT_ALL USE_64_BIT_INT
  USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_PERLIO
  USE_PERL_ATOF
  Built under linux
  Compiled at Mar 21 2014 09​:53​:32
  %ENV​:
  PERL5LIB=""
  PERLBREW_BASHRC_VERSION="0.67"
  PERLBREW_HOME="/home/vse/.perlbrew"
  PERLBREW_MANPATH="/home/perlbrew/perls/perl-5.19.10/man"
  PERLBREW_PATH="/home/perlbrew/bin​:/home/perlbrew/perls/perl-5.19.10/bin"
  PERLBREW_PERL="perl-5.19.10"
  PERLBREW_ROOT="/home/perlbrew"
  PERLBREW_VERSION="0.67"
  @​INC​:
  /home/perlbrew/perls/perl-5.19.10/lib/site_perl/5.19.10/x86_64-linux
  /home/perlbrew/perls/perl-5.19.10/lib/site_perl/5.19.10
  /home/perlbrew/perls/perl-5.19.10/lib/5.19.10/x86_64-linux
  /home/perlbrew/perls/perl-5.19.10/lib/5.19.10
  .

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2014

From @shlomif

Hi Victor,

On Wed Apr 09 02​:13​:52 2014, efimov@​reg.ru wrote​:

There was an idea that any operation on strings should stringify
output
http​://www.nntp.perl.org/group/perl.perl5.porters/2014/04/msg214205.html

Below test shows that there are inconsistencies with that rule.

use strict;
use warnings;

my $a = undef;
$a =~ s/x/z/;
print "a undefined\n" if ! defined $a;

my $b = undef;
$b =~ s//z/;
print "b defined\n" if defined $b;

I was a bit unhappy with your program (due to the overriding of $a and $b as lexicals) so I refactored it into this​:

[CODE]

#!/usr/bin/perl

use strict;
use warnings;

sub my_print
{
  my ($name, $val) = @​_;

  if (defined $val)
  {
  print "$name is defined and is <<$val>>\n";
  }
  else
  {
  print "$name is undefined.";
  }
}
my $x = undef;
$x =~ s/x/z/;

my_print('x', $x);

my $y = undef;
$y =~ s//z/;
my_print('y', $y);

[/CODE]

I am getting​:

[OUT]
shlomif@​telaviv1​:~$ /home/shlomif/apps/perl/bleadperl/bin/perl5.19.11 Test.pl
Use of uninitialized value $x in substitution (s///) at Test.pl line 20.
Use of uninitialized value $y in substitution (s///) at Test.pl line 25.
Use of uninitialized value $y in substitution (s///) at Test.pl line 25.
x is undefined.y is defined and is <<z>>

[/OUT]
What I think is happening is that in the second case one matches the empty string and so the undef is treated as an empty string, where the empty string is matched and gets translated to a z. In the first case, the $x is implicitly an empty string so no match is made and it isn't getting modified.

I don't think that's a bug.

Hope it is clearer now.

Regards,

-- Shlomi Fish

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2014

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

@p5pRT
Copy link
Author

p5pRT commented Apr 11, 2014

From [email protected]

2014-04-10 20​:39 GMT+04​:00 Shlomi Fish via RT <perlbug-followup@​perl.org>​:

Hi Victor,

I was a bit unhappy with your program (due to the overriding of $a and $b as lexicals) so I refactored it into this​:
ok

I am getting​:

[OUT]
shlomif@​telaviv1​:~$ /home/shlomif/apps/perl/bleadperl/bin/perl5.19.11 Test.pl
Use of uninitialized value $x in substitution (s///) at Test.pl line 20.
Use of uninitialized value $y in substitution (s///) at Test.pl line 25.
Use of uninitialized value $y in substitution (s///) at Test.pl line 25.
x is undefined.y is defined and is <<z>>

[/OUT]
What I think is happening is that in the second case one matches the empty string and so the undef is treated as an empty string, where the empty string is matched and gets translated to a z. In the first case, the $x is implicitly an empty string so no match is made and it isn't getting modified.

Right.

I don't think that's a bug.

My point was (see original report)​:

1) string operation should stringify undef (i.e. $x) - probably even
if it does not modify it?
2) there are two (same) warnings for $y. should be just one.

Hope it is clearer now.

Regards,

-- Shlomi Fish

@p5pRT
Copy link
Author

p5pRT commented May 18, 2014

From @jkeenan

On Fri Apr 11 07​:35​:27 2014, efimov@​reg.ru wrote​:

2014-04-10 20​:39 GMT+04​:00 Shlomi Fish via RT <perlbug-
followup@​perl.org>​:

Hi Victor,

I was a bit unhappy with your program (due to the overriding of $a
and $b as lexicals) so I refactored it into this​:
ok

I am getting​:

[OUT]
shlomif@​telaviv1​:~$ /home/shlomif/apps/perl/bleadperl/bin/perl5.19.11
Test.pl
Use of uninitialized value $x in substitution (s///) at Test.pl line
20.
Use of uninitialized value $y in substitution (s///) at Test.pl line
25.
Use of uninitialized value $y in substitution (s///) at Test.pl line
25.
x is undefined.y is defined and is <<z>>

[/OUT]
What I think is happening is that in the second case one matches the
empty string and so the undef is treated as an empty string, where
the empty string is matched and gets translated to a z. In the first
case, the $x is implicitly an empty string so no match is made and it
isn't getting modified.

Right.

I don't think that's a bug.

So that makes this RT a request to modify Perl's current behavior.

My point was (see original report)​:

1) string operation should stringify undef (i.e. $x) - probably even
if it does not modify it?
2) there are two (same) warnings for $y. should be just one.

I don't see a compelling case for change in either of those two points, and this is the kind of change that would likely cause problems for existing production code.

Thank you very much.
Jim Keenan

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

No branches or pull requests

2 participants