Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.94k stars 554 forks source link

Num ~~ numish does not behave as expected #10023

Closed p5pRT closed 8 years ago

p5pRT commented 14 years ago

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

Searchable as RT71452$

p5pRT commented 14 years ago

From belg4mit@pthbb.org

Created by belg4mit@pthbb.org

Perlsyn states​:

  Num numish[4] numeric equality $a == $b

Thus the smartmatch.t tests​:

  ! 2 "2bananas"   ! 2_3 "2_3"

Should not expect failure since 2 == "2bananas" and 2 == "2_3" yet for some reason (2 ~~ "2bananas") != 1

If "2bananas" is numish enough for every other operator in perl\, but not smart match\, that seems rather unsmart.

Perl Info ``` Flags: category=core severity=medium This perlbug was built using Perl v5.8.8 in the Red Hat build system. It is being executed now by Perl v5.8.8 - Thu Apr 2 19:39:17 EDT 2009. Site configuration information for perl v5.8.8: Configured by Red Hat, Inc. at Thu Apr 2 19:39:17 EDT 2009. Summary of my perl5 (revision 5 version 8 subversion 8) configuration: Platform: osname=linux, osvers=2.6.18-53.el5, archname=x86_64-linux-thread-multi uname='linux builder10.centos.org 2.6.18-53.el5 #1 smp mon nov 12 02:14:55 est 2007 x86_64 x86_64 x86_64 gnulinux ' config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Dversion=5.8.8 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dprivlib=/usr/lib/perl5/5.8.8 -Dsitelib=/usr/lib/perl5/site_perl/5.8.8 -Dvendorlib=/usr/lib/perl5/vendor_perl/5.8.8 -Darchlib=/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi -Dsitearch=/usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi -Darchname=x86_64-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_pro to -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.7 5.8.6 5.8.5 -Dscriptdir=/usr/bin' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef 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='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm', optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic', cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -I/usr/include/gdbm' ccversion='', gccversion='4.1.2 20080704 (Red Hat 4.1.2-44)', 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='gcc', ldflags ='' libpth=/usr/local/lib64 /lib64 /usr/lib64 libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=, so=so, useshrplib=true, libperl=libperl.so gnulibc_version='2.5' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' Locally applied patches: @INC for perl v5.8.8: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 . Environment for perl v5.8.8: HOME=/home/belg4mit LANG=en_US LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin PERL_BADLANG (unset) SHELL=/bin/tcsh ```
p5pRT commented 14 years ago

From belg4mit@pthbb.org

Additional evidence of inconsistency\, the following test​:

  [qw(1foo 2bar)] 2

i.e; (qw(1foo 2bar)] ~~ 2) == 1 but (2 ~~ "2bananas") != 1 ?!

-- Free map of local environmental resources​: http​://CambridgeMA.GreenMap.org -- MOTD on Prickle-Prickle\, the 62nd of The Aftermath\, in the YOLD 3175​: Alternative smock. --JP

p5pRT commented 14 years ago

From @ikegami

On Sat\, Dec 19\, 2009 at 9​:37 PM\, Jerrad Pierce \belg4mit@​pthbb\.org wrote​:

Additional evidence of inconsistency\, the following test​:

   \[qw\(1foo 2bar\)\]         2

i.e; (qw(1foo 2bar)] ~~ 2) == 1 but (2 ~~ "2bananas") != 1 ?!

No it doesn't.

perl -lE"say( ( [qw(1foo 2bar)] ~~ 2 ) ?1​:0 ) 0

Are you sure you're using 5.10.1?

p5pRT commented 14 years ago

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

p5pRT commented 14 years ago

From @ikegami

On Sat\, Dec 19\, 2009 at 6​:19 PM\, belg4mit@​pthbb.org (via RT) \< perlbug-followup@​perl.org> wrote​:

If "2bananas" is numish enough for every other operator in perl\,

Really? Every operator I tried told me it wasn't numeric.

perl -wE"my $x = 3 * '2bananas'" Argument "2bananas" isn't numeric in multiplication (*) at -e line 1.

perl -wE"my $x = 3 + '2bananas'" Argument "2bananas" isn't numeric in addition (+) at -e line 1.

perl -wE"my $x = 3 | '2bananas'" Argument "2bananas" isn't numeric in bitwise or (|) at -e line 1.

So argument is because the value becomes two when treated as a number\, it's numish? Given that every value can be converted to a number\, that would mean that all values are numish.

perl -wE"say 3 + '2bananas'" Argument "2bananas" isn't numeric in addition (+) at -e line 1. 5 # Treated as 2

perl -wE"say 3 + 'bananas'" Argument "bananas" isn't numeric in addition (+) at -e line 1. 3 # Treated as 0

perl -wE"say 3 + ['abc']" 2329375 # Treated as 2329372

Perl uses the same test it uses everywhere\, looks_like_number​:

perl -MScalar​::Util=looks_like_number -E"say looks_like_number('2bananas')||0" 0

p5pRT commented 14 years ago

From belg4mit@pthbb.org

Are you sure you're using 5.10.1? No\, 5.10.0

Okay\, so that inconsistency is gone\, but ~~ behavior still clashes with documentation Re​: numify -- Free map of local environmental resources​: http​://CambridgeMA.GreenMap.org -- MOTD on Prickle-Prickle\, the 62nd of The Aftermath\, in the YOLD 3175​: Alternative smock. --JP

p5pRT commented 14 years ago

From @ap

* belg4mit@​pthbb.org (via RT) \perlbug\-followup@&#8203;perl\.org [2009-12-20 04​:05]​:

Perlsyn states​:

Num numish[4] numeric equality $a == $b

Thus the smartmatch.t tests​:

! 2 "2bananas" ! 2_3 "2_3"

Should not expect failure since 2 == "2bananas" and 2 == "2_3" yet for some reason (2 ~~ "2bananas") != 1

If "2bananas" is numish enough for every other operator in perl\, but not smart match\, that seems rather unsmart.

This is not a bug. The documentation says “numish”\, not “can be converted to a number”.

Every scalar can be converted to a number so that would be a meaningless thing to say anyway.

And if the operator worked that way\, then `0 ~~ 'pink monkeys'` would also have to succeed. That would be far less smart.

You can get what you want by using `2 ~~ (0 + '2bananas')` instead.

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

p5pRT commented 14 years ago

From jpierce@cpan.org

Sorry\, I never received this message\, but just found it when revisiting the conversation in RT.

On Sat Dec 19 23​:23​:44 2009\, ikegami@​adaelis.com wrote​:

On Sat\, Dec 19\, 2009 at 6​:19 PM\, belg4mit@​pthbb.org (via RT) \< perlbug-followup@​perl.org> wrote​:

If "2bananas" is numish enough for every other operator in perl\,

Really? Every operator I tried told me it wasn't numeric. It *warned* that it wasn't\, but it still did the operation. I'd perfectly happy if C\<2 ~~ "2bananas"> emitted a non-numeric warning\, but still returned true.

Else\, the documentation needs to be updated.

I still think the current behavior is less smart than it could be\, but it could go either way and breaking from established is not to be entered into lightly.

p5pRT commented 14 years ago

From jpierce@cpan.org

Interjecting this previously sent message in case it gets lost in the ether\, as perl.org's mail server/RT seems to be having some issues... Eric's previous message Re​: warnings\, as well as Aristotle's never got to me\, and my reply to an off-list response at Sun\, 20 Dec 2009 04​:49​:57 -0500 about the consistency remaining in 5.10.1 below\, hasn't been logged...

On Sun\, 20 Dec 2009 14​:41​:12 -0500 Eric Brine wrote​:

Numish\, not numifable. Everything is numifiable That is a distinction which is not made in the documentation\, and that I contend is counter-intuitive since it violates the "Matching code" of C\<$a == $b> with the foot note​:

  4 - either a real number\, or a string that looks like a number

That's not the same thing as​:

  A string containing only a number that would be returned from the   string if eval'd* e.g; "2.0" and not strings that are treated as   numbers by other perl operators e.g; "2bananas"

so it would be useless. No\, it would just be different.

C\<2 ~~ "2bananas"> would be true but C\<2 ~~ "0 but true"> would still be false

* Addendum​: A rough pass at clearly documenting the behavior\, but we clearly wouldn't want "return 2" or "5 -3" to smart match to 2.

p5pRT commented 14 years ago

From jpierce@cpan.org

A few other notes for completeness...

Quoth Aristotle​:

And if the operator worked that way\, then `0 ~~ 'pink monkeys'` would also have to succeed. That would be far less smart. An interesting point.

Quoth I​:

I still think the current behavior is less smart than it could be\, but it could go either way and breaking from established is not to be entered into lightly. Although apparently ~~ has changed from 5.10.0 to 5.10.1 \<http​://search.cpan.org/~dapm/perl-5.10.1/pod/perl5101delta.pod#Smart_match_changes> and 5.10.1 does not pass its predecessor's tests​:

not ok 1 - \&foo ~~ \&foo​: #documented change? not ok 2 - \&foo ~~ \&foo​: #documented change? not ok 5 - \&foo ~~ \&bar​: 2 #documented change not ok 8 - sub{shift} ~~ 1​: #documented change not ok 12 - sub{scalar @​_} ~~ 1​: #documented change not ok 14 - \&bar ~~ []​: #documented change not ok 16 - \&bar ~~ {}​: #documented change not ok 63 - +{foo => 1\, bar => 2} ~~ "foo"​: #commutativity failure not ok 74 - [qr/o/\, qr/a/] ~~ ["foo"\, "bar"]​: #commutativity failure not ok 87 - [qw(1foo 2bar)] ~~ 2​: not ok 88 - 2 ~~ [qw(1foo 2bar)]​: not ok 100 - "2bananas" ~~ 2​: 1 #commutativity failure! not ok 103 - qr/x/ ~~ "x"​: #commutativity failure not ok 108 - qr/3/ ~~ 12345​: #commutativity failure not ok 109 - @​nums ~~ 7​: #commutativity failure not ok 119 - %hash ~~ "foo"​: #commutativity failure

p5pRT commented 14 years ago

From belg4mit@pthbb.org

On Sun\, 20 Dec 2009 14​:41​:12 -0500 Eric Brine wrote​:

Numish\, not numifable. Everything is numifiable That is a distinction which is not made in the documentation\, and that I contend is counter-intuitive since it violates the "Matching code" of C\<$a == $b> with the foot note​:

  4 - either a real number\, or a string that looks like a number

That's not the same thing as​:

  A string containing only a number that would be returned from the string   if eval'd e.g; "2.0" and not strings that are treated as numbers by other   perl operators e.g; "2bananas"

so it would be useless. No\, it would just be different.

C\<2 ~~ "2bananas"> would be true but C\<2 ~~ "0 but true"> would still be false -- Free map of local environmental resources​: http​://CambridgeMA.GreenMap.org -- MOTD on Prickle-Prickle\, the 62nd of The Aftermath\, in the YOLD 3175​: Alternative smock. --JP

p5pRT commented 14 years ago

From @ikegami

On Sun\, Dec 20\, 2009 at 3​:01 PM\, Jerrad Pierce \belg4mit@&#8203;pthbb\.org wrote​:

On Sun\, 20 Dec 2009 14​:41​:12 -0500 Eric Brine wrote​:

Numish\, not numifable. Everything is numifiable That is a distinction which is not made in the documentation\, and that I contend is counter-intuitive since it violates the "Matching code" of C\<$a == $b> with the foot note​:

4 - either a real number\, or a string that looks like a number

I seem to have forgotten the lesson on number 2bananas.

so it would be useless. No\, it would just be different.

I stand corrected. It wouldn't be useless. It would make

NUMBER NUMISH

into the undesirable

NUMBER ANY

C\<2 ~~ "2bananas"> would be true but C\<2 ~~ "0 but true"> would still be

false

I don't know how you can consider "2bananas" equivalent to 2 and "apple" equivalent to zero.

- ELB

p5pRT commented 14 years ago

From jpierce@cpan.org

As i see it there are two matters at hand​:

1) Is whether ~~ should handle numish differently/better\, and if so how. I contend that it should/could. 2) If not 1\, that perlsyn should more clearly describe it's current behavior as something other than simply ==\, and I gave a (verbose) example.

I don't know how you can consider "2bananas" equivalent to 2 By the dox it should be\, since the pod says it's defined as == But like everything else it should heed C\<warnings 'numeric'> if changed to truly employ an == test so that C\<"2bananas" ~~ 2> is true.

and "apple" equivalent to zero. That was Aristotle's argument\, and I acknowledged it was valid that C\<qw/apple 4/ ~~ 0> should be false. However\, if non-numifiable strings were undef rather than zero (to ~~ when comparing to a number) then the previous statement would still be false\, but C\<qw/0apples 4/ ~~ 0> would be true. That shouldn't change anything else since ~~ reportedly uses defined on C\<"zebra" ~~ undef>.

p5pRT commented 8 years ago

From @dcollinsn

While reviewing this older ticket\, I'm having some trouble deciding what other behavior is desired. Perlop defines "nummy" as "Either an actual number\, or a string that looks like one."\, changing that to perform numeric comparison on number ~~ string\, even for strings that are clearly not numbers\, seems problematic.

The code matches the documentation\, so I'm marking this as wishlist. However\, I also propose to mark this rejected.

-- Respectfully\, Dan Collins

p5pRT commented 8 years ago

From jpierce@cpan.org

On Fri Jul 22 09​:13​:01 2016\, dcollinsn@​gmail.com wrote​:

While reviewing this older ticket\, I'm having some trouble deciding what other behavior is desired. Perlop defines "nummy" as "Either an actual number\, or a string that looks like one."\, changing that to perform numeric comparison on number ~~ string\, even for strings that are clearly not numbers\, seems problematic.

The code matches the documentation\, so I'm marking this as wishlist. However\, I also propose to mark this rejected.

The behavior desired is for the operator to be implemented as described. When submitted\, the operator was not matching strings that look like one i.e; == and ~~ should give the same result for strings beginning with numbers. Perhaps things have changed in the interim\, but in the latest perl I'm using (5.22)\, this does not appear to be the case.

p5pRT commented 8 years ago

From @dcollinsn

On Fri Jul 22 10​:01​:33 2016\, jpierce wrote​:

The behavior desired is for the operator to be implemented as described. When submitted\, the operator was not matching strings that look like one i.e; == and ~~ should give the same result for strings beginning with numbers. Perhaps things have changed in the interim\, but in the latest perl I'm using (5.22)\, this does not appear to be the case.

This ticket arises from the distinction between "string that looks like a number" (which is used by smartmatch) and "string that can be coerced to a number" (which is the set of all perl strings). Per the perldoc perlop section on smartmatch\, Num ~~ nummy is defined as numeric equality\, where "nummy" is defined as "either an actual number\, or a string that looks like one".

This is consistent with the only other use of "looks like" a number in perlop​:

  Unary "-" performs arithmetic negation if the operand is numeric\, including any string that looks like a number...If\, however\, the string begins with a non-alphabetic character (excluding "+" or "-" )\, Perl will attempt to convert the string to a numeric\, and the arithmetic negation is performed. If the string cannot be cleanly converted to a numeric\, Perl will give the warning Argument "the string" isn't numeric in negation (-) at ....

  perl -wle 'print -"2banana"'   Argument "2banana" isn't numeric in negation (-) at -e line 1.   -2

In other words\, 2 doesn't "look like" a number\, so it gets the warning\, but perl is still able to convert the string to a numeric. On the other hand\, the smartmatch operator makes no promise about handling strings that don't look like a number but that can be converted to one - they would be covered under the "Any ~~ Any" case\, which is defined as string equality.

-- Respectfully\, Dan Collins

p5pRT commented 8 years ago

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