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

RFE: allow length(undef)=>0 (w/no warnings) #11257

Closed
p5pRT opened this issue Apr 17, 2011 · 8 comments
Closed

RFE: allow length(undef)=>0 (w/no warnings) #11257

p5pRT opened this issue Apr 17, 2011 · 8 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 17, 2011

Migrated from rt.perl.org#88740 (status was 'resolved')

Searchable as RT88740$

@p5pRT
Copy link
Author

p5pRT commented Apr 17, 2011

From perl-diddler@tlinx.org

This is a bug report for perl from perl-diddler@​tlinx.org,
generated with the help of perlbug 1.36 running under perl 5.10.0.

(Since I have yet to install 5.12, please excuse any ignorance of
details about this feature change, I'm going from documentation
changes and 'whatsnew' docs regarding diffs between 5.10 & 5.12)

In 5.12, I believe, the behavior of length was changed from giving a
warning and a result of '0' for "length undef" to now give a result of
'0'.

When this was announced, I thought, "oh, that makes sense, how can you
take the length of a non object".

But in writing programs that use length, I have a different view -- in
that the length of something can be a positive integer, OR , it can be 0.
But just because the object is undefined, doesn't mean the length is, as
in 'real life', you have no objects with undefined length.

Example​: Suppose I ask what is the length of the color orange. It makes
no sense, as the color orange isn't a physical object that would have a
length. So it has no length. But what is something that has no length
but something that has 0 length?

The length function in this case is 'arbitrary', and I can see a
usefulness of allowing 'undef' but I also have many cases where returning
a value of 0 is also useful. With the old paradigm, I could intercept the
warning​:

  $SIG{__WARN__} =
  sub {/^Use of uninitialized value in length at/ && return};

  and get 'clean' looking code to (for example) sum up the lengths
of several 'test result strings', where skipped-tests have no output
string and are "undef".

NOTE​: this is a clear example where 0 is the "correct" answer. I.e. if
asking "how much space will it take to display the results of a test that
was not run, or reworded, what is the length of a result string for a test
that was not run?"

  I would ASSERT, that most people would answer "0" -- not "undef" and
that "undef" would be considered 'counter-intuitive'.

Alternatively instead of using a SIG handler, one substitute​:

  "( defined $str && length $str ) || 0"
 
for each place where you add the length of a test-results string.

Now, in 5.12, there's no more warning to intercept -- it just returns
'undef', requring something along the lines of​:

  "$str && length $str || 0"

instead of the simple

  "length $str".
 
What to do? (and please don't just say, it's done, so give up and go
away -- 5.12 introduced an incompatibility in this 1 feature. If it
was possible to enable all features in 5.12 but have a shorthand
for disabling that, it might be suitable...but I don't believe
that's the case.

So, actually, that's what I'm proposing as a fix, 'sorta' -- introduced
as a pragma, though I'm not sure of the best name. Spelling it out looks
too long​:

  use undef_has_length0;
or
  use length_as_int, or length_is_int, len_gte0 (greater than or equal)
  etc...

The shorter the name, the less obvious it is what it does.

Unfortunately, on a personal level, my initial acceptance of this
change wasn't well considered. I'm wondering if I'm the only one
who doesn't view this change as something that should have been
made optional via a pragma, and not included by default.

Perhaps this issue might be raised amongst a wider group a people
with the intent of reversing the change as a 'default', and requiring
a separate pragma to enable 'length' returing a non-integer value?

Linda Walsh
(diddling w/perl for over 20 years now...)


Flags​:
  category=core
  severity=medium


This perlbug was built using Perl 5.10.0 - Fri Jul 30 00​:12​:10 UTC 2010
It is being executed now by Perl 5.10.0 - Thu Sep 16 16​:14​:28 UTC 2010.

Site configuration information for perl 5.10.0​:

Configured by abuild at Thu Sep 16 16​:14​:28 UTC 2010.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration​:
  Platform​:
  osname=linux, osvers=2.6.31, archname=x86_64-linux-thread-multi
  uname='linux build35 2.6.31 #1 smp 2010-01-06 16​:07​:25 +0100 x86_64 x86_64 x86_64 gnulinux '
  config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Duseshrplib=true -DEBUGGING=both -Doptimize=-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -Wall -pipe -Accflags=-DPERL_USE_SAFE_PUTENV'
  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 -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -Wall -pipe -g',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe'
  ccversion='', gccversion='4.4.1 [gcc-4_4-branch revision 150839]', 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 =' -L/usr/local/lib64'
  libpth=/lib64 /usr/lib64 /usr/local/lib64
  libs=-lm -ldl -lcrypt -lpthread
  perllibs=-lm -ldl -lcrypt -lpthread
  libc=/lib64/libc-2.10.1.so, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.10.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.10.0/x86_64-linux-thread-multi/CORE'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib64'

Locally applied patches​:
 


@​INC for perl 5.10.0​:
  /usr/local/lib/perl/5.8
  /usr/lib/perl5/5.10.0/x86_64-linux-thread-multi
  /usr/lib/perl5/5.10.0
  /usr/lib/perl5/site_perl/5.10.0/x86_64-linux-thread-multi
  /usr/lib/perl5/site_perl/5.10.0
  /usr/lib/perl5/vendor_perl/5.10.0/x86_64-linux-thread-multi
  /usr/lib/perl5/vendor_perl/5.10.0
  /usr/lib/perl5/vendor_perl
  .


Environment for perl 5.10.0​:
  HOME=/home/law
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LC_CTYPE=en_US.UTF-8
  LD_LIBRARY_PATH=/usr/lib64/mpi/gcc/openmpi/lib64
  LOGDIR (unset)
  PATH=.​:/sbin​:/usr/local/sbin​:/usr/lib64/mpi/gcc/openmpi/bin​:/home/law/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/X11R6/bin​:/usr/games​:/opt/kde3/bin​:/usr/lib/mit/bin​:/usr/lib/mit/sbin​:/usr/lib/qt3/bin​:/usr/sbin
  PERL5LIB=/usr/local/lib/perl/5.8
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2011

From @ap

* Linda Walsh <perlbug-followup@​perl.org> [2011-04-18 02​:15]​:

Now, in 5.12, there's no more warning to intercept -- it just
returns 'undef', requring something along the lines of​:

"$str && length $str || 0"

instead of the simple

"length $str"\.

length $str // 0

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2011

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

@p5pRT
Copy link
Author

p5pRT commented Jul 4, 2012

From @doy

undef in numeric context evaluates to 0, so your example of summing up a
bunch of lengths will still work identically (although the warning that
is generated is now "Use of uninitialized value in addition (+)" instead
of "Use of uninitialized value in length". Also, if you want to suppress
the warning, previously you had to do "(defined($str) && length($str))
|| 0", where now you can do just "length($str) || 0", since passing
undef to length no longer warns. I'm inclined to close this ticket,
unless anyone can see anything here that should be done.

-doy

@p5pRT
Copy link
Author

p5pRT commented Jul 4, 2012

From perl-diddler@tlinx.org

I don't care that much -- convenience wise, I'd would have preferred
the length of an undef return the 0 without the warning -- since with many
programs, a warning is treated the same as an error...

I.e. I'd rather a function like length always return a number -- like doing
a safe conversion from 'any' (defined or not) => number (in numeric
context)...

But I could probably argue the opposite point of view just as
logically...so...eh!
I don't care that much...
;-)

Jesse Luehrs via RT wrote​:

undef in numeric context evaluates to 0, so your example of summing up a
bunch of lengths will still work identically (although the warning that
is generated is now "Use of uninitialized value in addition (+)" instead
of "Use of uninitialized value in length". Also, if you want to suppress
the warning, previously you had to do "(defined($str) && length($str))
|| 0", where now you can do just "length($str) || 0", since passing
undef to length no longer warns. I'm inclined to close this ticket,
unless anyone can see anything here that should be done.

-doy

@p5pRT
Copy link
Author

p5pRT commented Jul 4, 2012

From @doy

In that case, closing.

-doy

@p5pRT
Copy link
Author

p5pRT commented Jul 4, 2012

From [Unknown Contact. See original ticket]

In that case, closing.

-doy

@p5pRT p5pRT closed this as completed Jul 4, 2012
@p5pRT
Copy link
Author

p5pRT commented Jul 4, 2012

@doy - Status changed from 'open' to 'resolved'

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