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

sqrt without EXPR and Math::Complex always 0 #9620

Closed
p5pRT opened this issue Jan 15, 2009 · 23 comments
Closed

sqrt without EXPR and Math::Complex always 0 #9620

p5pRT opened this issue Jan 15, 2009 · 23 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 15, 2009

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

Searchable as RT62412$

@p5pRT
Copy link
Author

p5pRT commented Jan 15, 2009

From frank.wiegand@gmail.com

This is a bug report for perl from frank.wiegand@​gmail.com,
generated with the help of perlbug 1.36 running under perl 5.10.0.


perldoc -f sqrt says​:

| Return the square root of EXPR. If EXPR is omitted, returns square
| root of C<$_>. Only works on non-negative operands, unless you've
| loaded the standard Math​::Complex module.

Let's try​:

% perl -MMath​::Complex -E '$_=+1; say sqrt'
0
% perl -MMath​::Complex -E '$_=-1; say sqrt'
0

The EXPR form works fine​:

% perl -MMath​::Complex -E 'say sqrt +1'
1
% perl -MMath​::Complex -E 'say sqrt -1'
i

Without -MMath​::Complex everything works fine, according to the docs.

Thanks, Frank



Flags​:
  category=core
  severity=low


Site configuration information for perl 5.10.0​:

Configured by Debian Project at Thu Jan 1 15​:40​:00 UTC 2009.

Summary of my perl5 (revision 5 version 10 subversion 0) configuration​:
  Platform​:
  osname=linux, osvers=2.6.26-1-vserver-amd64,
archname=x86_64-linux-gnu-thread-multi
  uname='linux excelsior 2.6.26-1-vserver-amd64 #1 smp sat nov 8
20​:24​:14 utc 2008 x86_64 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr
-Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10
-Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5
-Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl/5.10.0
-Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1
-Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl
-Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio
-Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib
-Dlibperl=libperl.so.5.10.0 -Dd_dosuid -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
-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 -fno-strict-aliasing
-pipe -I/usr/local/include'
  ccversion='', gccversion='4.3.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 =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=/lib/libc-2.7.so, so=so, useshrplib=true,
libperl=libperl.so.5.10.0
  gnulibc_version='2.7'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -g -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl 5.10.0​:
  /etc/perl
  /usr/local/lib/perl/5.10.0
  /usr/local/share/perl/5.10.0
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.10
  /usr/share/perl/5.10
  /usr/local/lib/site_perl
  .


Environment for perl 5.10.0​:
  HOME=/home/fw
  LANG=de_DE.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)

PATH=/sbin​:/home/fw/bin​:/home/fw/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/games
  PERL_AUTOINSTALL=--defaultdeps
  PERL_BADLANG (unset)
  PERL_EXTUTILS_AUTOINSTALL=--defaultdeps
  PERL_MM_USE_DEFAULT=1
  SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

Hi Frank,

thanks for the bug report,

Frank Wiegand wrote​:

# New Ticket Created by Frank Wiegand
# Please include the string​: [perl #62412]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=62412 >

perldoc -f sqrt says​:

| Return the square root of EXPR. If EXPR is omitted, returns square
| root of C<$_>. Only works on non-negative operands, unless you've
| loaded the standard Math​::Complex module.

Let's try​:

% perl -MMath​::Complex -E '$_=+1; say sqrt'
0
% perl -MMath​::Complex -E '$_=-1; say sqrt'
0

The EXPR form works fine​:

% perl -MMath​::Complex -E 'say sqrt +1'
1
% perl -MMath​::Complex -E 'say sqrt -1'
i

Without -MMath​::Complex everything works fine, according to the docs.

This is because Math​::Complex defines a new sqrt() function that can
deal with complex values and overrides the core sqrt. The attached patch
fixes the issue and adds a test for it.

I did *not* check all other Math​::Complex functions for the same defect.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

0001-Quick-fix-for-Math-Complex-sqrt-not-falling-back.patch
From 0e83e9816665b6a5a66f31456bd554f8e0417544 Mon Sep 17 00:00:00 2001
From: Steffen Mueller <smueller@cpan.org>
Date: Fri, 16 Jan 2009 09:16:57 +0100
Subject: [PATCH] Quick fix for Math::Complex::sqrt() not falling back to $_ (RT #62412)

---
 lib/Math/Complex.pm |    2 +-
 lib/Math/Complex.t  |   10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/lib/Math/Complex.pm b/lib/Math/Complex.pm
index 7d05a44..6c5b3b4 100644
--- a/lib/Math/Complex.pm
+++ b/lib/Math/Complex.pm
@@ -672,7 +672,7 @@ sub arg {
 # Therefore if you want the two solutions use the root().
 #
 sub sqrt {
-	my ($z) = @_;
+	my ($z) = @_ ? @_ : $_;
 	my ($re, $im) = ref $z ? @{$z->_cartesian} : ($z, 0);
 	return $re < 0 ? cplx(0, CORE::sqrt(-$re)) : CORE::sqrt($re)
 	    if $im == 0;
diff --git a/lib/Math/Complex.t b/lib/Math/Complex.t
index ee02341..99514fc 100755
--- a/lib/Math/Complex.t
+++ b/lib/Math/Complex.t
@@ -106,6 +106,16 @@ push(@script, <<'EOT');
                         (Im($z) + 1          ) < $eps;
 EOT
     push(@script, qq(print "ok $test\\n"}\n));
+
+    $test++;
+    push @script, <<'TEST_FOR_DEFAULT_ARG';
+{
+    local $_ = cplx(  4,  0);
+    my $res = sqrt();
+    print "# $test $_=cplx(4, 0); sqrt() == 2\n";
+    print 'not ' if abs($res - 2) > $eps;
+TEST_FOR_DEFAULT_ARG
+    push(@script, qq(print "ok $test\\n"}\n));
 }
 
 test_mutators();
-- 
1.5.4.3

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

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

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

Hi Andrew, hi Jarkko,

the Porting/Maintainers.pl document in core now has a field that
indicates whether a given module considers CPAN or perl core 'upstream'.
It's not yet set for Math​::Complex. Please do set it so we know whether
to send patches to you or apply to core and let you pull them.

The attached patch fixes a minor issue in Math​::Complex and adds a test.
It's a patch against the core Math​::Complex.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

Hi Frank,

thanks for the bug report,

Frank Wiegand wrote​:

# New Ticket Created by Frank Wiegand
# Please include the string​: [perl #62412]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=62412 >

perldoc -f sqrt says​:

| Return the square root of EXPR. If EXPR is omitted, returns square
| root of C<$_>. Only works on non-negative operands, unless you've
| loaded the standard Math​::Complex module.

Let's try​:

% perl -MMath​::Complex -E '$_=+1; say sqrt'
0
% perl -MMath​::Complex -E '$_=-1; say sqrt'
0

The EXPR form works fine​:

% perl -MMath​::Complex -E 'say sqrt +1'
1
% perl -MMath​::Complex -E 'say sqrt -1'
i

Without -MMath​::Complex everything works fine, according to the docs.

This is because Math​::Complex defines a new sqrt() function that can
deal with complex values and overrides the core sqrt. The attached patch
fixes the issue and adds a test for it.

I did *not* check all other Math​::Complex functions for the same defect.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

0001-Quick-fix-for-Math-Complex-sqrt-not-falling-back.patch
From 0e83e9816665b6a5a66f31456bd554f8e0417544 Mon Sep 17 00:00:00 2001
From: Steffen Mueller <smueller@cpan.org>
Date: Fri, 16 Jan 2009 09:16:57 +0100
Subject: [PATCH] Quick fix for Math::Complex::sqrt() not falling back to $_ (RT #62412)

---
 lib/Math/Complex.pm |    2 +-
 lib/Math/Complex.t  |   10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/lib/Math/Complex.pm b/lib/Math/Complex.pm
index 7d05a44..6c5b3b4 100644
--- a/lib/Math/Complex.pm
+++ b/lib/Math/Complex.pm
@@ -672,7 +672,7 @@ sub arg {
 # Therefore if you want the two solutions use the root().
 #
 sub sqrt {
-	my ($z) = @_;
+	my ($z) = @_ ? @_ : $_;
 	my ($re, $im) = ref $z ? @{$z->_cartesian} : ($z, 0);
 	return $re < 0 ? cplx(0, CORE::sqrt(-$re)) : CORE::sqrt($re)
 	    if $im == 0;
diff --git a/lib/Math/Complex.t b/lib/Math/Complex.t
index ee02341..99514fc 100755
--- a/lib/Math/Complex.t
+++ b/lib/Math/Complex.t
@@ -106,6 +106,16 @@ push(@script, <<'EOT');
                         (Im($z) + 1          ) < $eps;
 EOT
     push(@script, qq(print "ok $test\\n"}\n));
+
+    $test++;
+    push @script, <<'TEST_FOR_DEFAULT_ARG';
+{
+    local $_ = cplx(  4,  0);
+    my $res = sqrt();
+    print "# $test $_=cplx(4, 0); sqrt() == 2\n";
+    print 'not ' if abs($res - 2) > $eps;
+TEST_FOR_DEFAULT_ARG
+    push(@script, qq(print "ok $test\\n"}\n));
 }
 
 test_mutators();
-- 
1.5.4.3

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From @Abigail

On Fri, Jan 16, 2009 at 09​:41​:12AM +0100, Steffen Mueller wrote​:

Hi Andrew, hi Jarkko,

the Porting/Maintainers.pl document in core now has a field that
indicates whether a given module considers CPAN or perl core 'upstream'.
It's not yet set for Math​::Complex. Please do set it so we know whether
to send patches to you or apply to core and let you pull them.

The attached patch fixes a minor issue in Math​::Complex and adds a test.
It's a patch against the core Math​::Complex.

Best regards,
Steffen

From​: Steffen Mueller <wyp3rlx02@​sneakemail.com>
To​: perl5-porters@​perl.org
Date​: Fri, 16 Jan 2009 09​:21​:29 +0100
Subject​: Re​: [perl #62412] sqrt without EXPR and Math​::Complex always 0

Hi Frank,

thanks for the bug report,

Frank Wiegand wrote​:

# New Ticket Created by Frank Wiegand
# Please include the string​: [perl #62412]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=62412 >

perldoc -f sqrt says​:

| Return the square root of EXPR. If EXPR is omitted, returns square
| root of C<$_>. Only works on non-negative operands, unless you've
| loaded the standard Math​::Complex module.

Let's try​:

% perl -MMath​::Complex -E '$_=+1; say sqrt'
0
% perl -MMath​::Complex -E '$_=-1; say sqrt'
0

The EXPR form works fine​:

% perl -MMath​::Complex -E 'say sqrt +1'
1
% perl -MMath​::Complex -E 'say sqrt -1'
i

Without -MMath​::Complex everything works fine, according to the docs.

This is because Math​::Complex defines a new sqrt() function that can
deal with complex values and overrides the core sqrt. The attached patch
fixes the issue and adds a test for it.

I did *not* check all other Math​::Complex functions for the same defect.

sub sqrt {
- my ($z) = @​_;
+ my ($z) = @​_ ? @​_ : $_;

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

  sub sqrt (_) {
  my ($z) = @​_;
  ...

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From wyp3rlx02@sneakemail.com

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...

doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

In any case, please disregard my patch.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From @Abigail

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...

doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From @jhi

Abigail wrote​:

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...
doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.

Which means without BEGIN + eval games that can't be in M​::C.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From @nwc10

On Fri, Jan 16, 2009 at 07​:58​:00AM -0500, Jarkko Hietaniemi wrote​:

Abigail wrote​:

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...
doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.

Which means without BEGIN + eval games that can't be in M​::C.

I don't think that an eval is needed - simply assign one of the alternatives
to *Math​::Complex​::sqrt

Or alternatively, a Corelist_pm.PL that has the two alternatives, and
Makefile.PL extracts.

(Hmm. Without XS, I can't see any way to change the prototype of a function
at run time.)

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jan 16, 2009

From @rgs

2009/1/16 Nicholas Clark <nick@​ccl4.org>​:

On Fri, Jan 16, 2009 at 07​:58​:00AM -0500, Jarkko Hietaniemi wrote​:

Abigail wrote​:

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...
doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.

Which means without BEGIN + eval games that can't be in M​::C.

I don't think that an eval is needed - simply assign one of the alternatives
to *Math​::Complex​::sqrt

Or alternatively, a Corelist_pm.PL that has the two alternatives, and
Makefile.PL extracts.

(Hmm. Without XS, I can't see any way to change the prototype of a function
at run time.)

Scalar​::Util​::set_prototype() ?

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2009

From @jhi

Steffen Mueller wrote​:

Hi Andrew, hi Jarkko,

the Porting/Maintainers.pl document in core now has a field that
indicates whether a given module considers CPAN or perl core 'upstream'.
It's not yet set for Math​::Complex. Please do set it so we know whether
to send patches to you or apply to core and let you pull them.

I would prefer the patches being sent to us (jhi or zefram).

The attached patch fixes a minor issue in Math​::Complex and adds a test.
It's a patch against the core Math​::Complex.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2009

From wyp3rlx02@sneakemail.com

Hi,

Jarkko Hietaniemi jhi-at-iki.fi |newsgroups6| wrote​:

Steffen Mueller wrote​:

the Porting/Maintainers.pl document in core now has a field that
indicates whether a given module considers CPAN or perl core 'upstream'.
It's not yet set for Math​::Complex. Please do set it so we know whether
to send patches to you or apply to core and let you pull them.

I would prefer the patches being sent to us (jhi or zefram).

Thanks for the info, I updated Porting/Maintainers.pl accordingly.

Best regards,
Steffen

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2009

From @jhi

Rafael Garcia-Suarez wrote​:

2009/1/16 Nicholas Clark <nick@​ccl4.org>​:

On Fri, Jan 16, 2009 at 07​:58​:00AM -0500, Jarkko Hietaniemi wrote​:

Abigail wrote​:

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...
doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.
Which means without BEGIN + eval games that can't be in M​::C.
I don't think that an eval is needed - simply assign one of the alternatives
to *Math​::Complex​::sqrt

Or alternatively, a Corelist_pm.PL that has the two alternatives, and
Makefile.PL extracts.

(Hmm. Without XS, I can't see any way to change the prototype of a function
at run time.)

Scalar​::Util​::set_prototype() ?

Okay, call me dim, but how do I write an interface that (either accepts
an explicit argument, or uses the $_ and) works with the new lexical $_,
and that works both nicely in pre-5.10 and 5.10? In pre-5.10 I cannot
say sub ... (_) without hiding it in an eval.

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2009

From @Abigail

On Sun, Jan 18, 2009 at 02​:05​:12PM -0500, Jarkko Hietaniemi wrote​:

Rafael Garcia-Suarez wrote​:

2009/1/16 Nicholas Clark <nick@​ccl4.org>​:

On Fri, Jan 16, 2009 at 07​:58​:00AM -0500, Jarkko Hietaniemi wrote​:

Abigail wrote​:

On Fri, Jan 16, 2009 at 11​:33​:08AM +0100, Steffen Mueller wrote​:

Hi,

Abigail abigail-at-abigail.be |newsgroups6| wrote​:

That will not pick up any lexical $_. It would if you'd used a '_' prototype​:

sub sqrt (_) {
my ($z) = @​_;
...
doh, of course. Thanks for catching that. If I recall correctly, the _
prototype can't be backported to 5.8 and earlier, right?

Indeed. Both the '_' prototype and lexical $_ are new in 5.10.
Which means without BEGIN + eval games that can't be in M​::C.
I don't think that an eval is needed - simply assign one of the alternatives
to *Math​::Complex​::sqrt

Or alternatively, a Corelist_pm.PL that has the two alternatives, and
Makefile.PL extracts.

(Hmm. Without XS, I can't see any way to change the prototype of a function
at run time.)

Scalar​::Util​::set_prototype() ?

Okay, call me dim, but how do I write an interface that (either accepts
an explicit argument, or uses the $_ and) works with the new lexical $_,
and that works both nicely in pre-5.10 and 5.10? In pre-5.10 I cannot
say sub ... (_) without hiding it in an eval.

This works for me​:

  #!/usr/bin/perl

  use strict;
  use warnings;
  no warnings 'syntax';

  use Scalar​::Util 'set_prototype';

  $_ = "python";

  sub hello {
  my $arg = @​_ ? $_ [0] : $_;
  print "Hello, $arg\n";
  }

  BEGIN {
  set_prototype \&hello, '_' if $] >= 5.010;
  }

  {
  # my $_ = "perl"; # Uncomment in 5.10.0;
  # local $_ = "perl"; # Uncomment in 5.8.9;
  hello;
  }

  __END__

With the appropriate line uncommented, it prints "Hello, world" for me
in both 5.8.9 and 5.10.0. No eval.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2009

From @jhi

use warnings;
no warnings 'syntax';

use Scalar&#8203;::Util 'set\_prototype';

$\_ = "python";

sub hello \{
    my $arg = @&#8203;\_ ? $\_ \[0\] : $\_;
    print "Hello\, $arg\\n";
\}

BEGIN \{
    set\_prototype \\&hello\, '\_' if $\] >= 5\.010;
\}

\{
  \# my $\_    = "perl";  \# Uncomment in 5\.10\.0;
  \# local $\_ = "perl";  \# Uncomment in 5\.8\.9;
    hello;
\}

\_\_END\_\_

With the appropriate line uncommented, it prints "Hello, world" for me
in both 5.8.9 and 5.10.0. No eval.

No eval, true. But "no warnings 'syntax'", if that's left in I get these​:

Prototype mismatch​: sub Math​::Complex​::abs (_) vs none ...

Yuck.

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2009

From @Abigail

On Sun, Jan 18, 2009 at 09​:04​:16PM -0500, Jarkko Hietaniemi wrote​:

use warnings;
no warnings 'syntax';

use Scalar&#8203;::Util 'set\_prototype';

$\_ = "python";

sub hello \{
    my $arg = @&#8203;\_ ? $\_ \[0\] : $\_;
    print "Hello\, $arg\\n";
\}

BEGIN \{
    set\_prototype \\&hello\, '\_' if $\] >= 5\.010;
\}

\{
  \# my $\_    = "perl";  \# Uncomment in 5\.10\.0;
  \# local $\_ = "perl";  \# Uncomment in 5\.8\.9;
    hello;
\}

\_\_END\_\_

With the appropriate line uncommented, it prints "Hello, world" for me
in both 5.8.9 and 5.10.0. No eval.

No eval, true. But "no warnings 'syntax'", if that's left in I get these​:

Prototype mismatch​: sub Math​::Complex​::abs (_) vs none ...

Ah, I didn't realize that. (I always have 'syntax' warnings disabled).

But when I enable syntax warnings, I only get the warning if I do​:

  sub hello;
  BEGIN {
  set_prototype \&hello, '_' if $] >= 5.010;
  }
  sub hello {
  ...
  }

If I set the prototype after the sub has been defined, all seems to be well.

Abigail

@p5pRT
Copy link
Author

p5pRT commented Nov 17, 2010

From @nwc10

On Mon, Jan 19, 2009 at 03​:22​:01AM +0100, Abigail wrote​:

On Sun, Jan 18, 2009 at 09​:04​:16PM -0500, Jarkko Hietaniemi wrote​:

No eval, true. But "no warnings 'syntax'", if that's left in I get these​:

Prototype mismatch​: sub Math​::Complex​::abs (_) vs none ...

That's a valid warning.

Ah, I didn't realize that. (I always have 'syntax' warnings disabled).

But when I enable syntax warnings, I only get the warning if I do​:

sub hello;
BEGIN \{
    set\_prototype \\&hello\, '\_' if $\] >= 5\.010;
\}
sub hello \{
    \.\.\.
\}

If I set the prototype after the sub has been defined, all seems to be well.

Indeed.

The facetious version​:

I have a patch. It removes code (that's always good)
The tests all pass (that's good too)​:

Inline Patch
diff --git a/cpan/Math-Complex/lib/Math/Complex.pm b/cpan/Math-Complex/lib/Math/
index 8475a2b..afec359 100644
--- a/cpan/Math-Complex/lib/Math/Complex.pm
+++ b/cpan/Math-Complex/lib/Math/Complex.pm
@@ -73,20 +73,6 @@ use Scalar::Util qw(set_prototype);
 use warnings;
 no warnings 'syntax';  # To avoid the (_) warnings.

-BEGIN {
-    # For certain functions that we override, in 5.10 or better
-    # we can set a smarter prototype that will handle the lexical $_
-    # (also a 5.10+ feature).
-    if ($] >= 5.010000) {
-        set_prototype \&abs, '_';
-        set_prototype \&cos, '_';
-        set_prototype \&exp, '_';
-        set_prototype \&log, '_';
-        set_prototype \&sin, '_';
-        set_prototype \&sqrt, '_';
-    }
-}
-
 my $i;
 my %LOGN;



The less-than-facetious version:

1​: All those calls to set_prototype aren't achieving anything
2​: That test can't be testing what it was meant to be testing.

It's necessary to set the prototype *after* the subroutine is defined

Otherwise, it turns out that what happens is​:

1​: sub is stubbed and has prototype added by the call (in that BEGIN block)
3​: parser creates a new subroutine body
3​: newATTRSUB assigns that body to the stub, and uses *its* prototype,
  discarding the stub's prototype.

And as the body has no prototype, that (lack of) prototype wins.

Compare​:

$ ./perl -Ilib -MScalar​::Util=set_prototype -lwe 'BEGIN {set_prototype \&foo, "_"}; print prototype \&foo; sub foo {}'
Prototype mismatch​: sub main​::foo (_) vs none at -e line 1.
Use of uninitialized value in print at -e line 1.

$ ./perl -Ilib -MScalar​::Util=set_prototype -lwe 'sub foo {} BEGIN {set_prototype \&foo, "_"}; print prototype \&foo'
_

I don't have a patch to offer. Moving the BEGIN block later doesn't cause
tests to fail, but that's not filling me with confidence, given that the
tests aren't testing everything that they are meant to be.

(And I'm more interested in why something else I'm trying doesn't quite work,
and curiously this Math​::Complex test was the only "test" in core for the
current behaviour of prototypes getting scrubbed)

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Nov 17, 2010

From @nwc10

On Wed, Nov 17, 2010 at 10​:19​:21PM +0000, Nicholas Clark wrote​:

I don't have a patch to offer. Moving the BEGIN block later doesn't cause
tests to fail, but that's not filling me with confidence, given that the
tests aren't testing everything that they are meant to be.

Specifically, by "later" I had it at the end, so that the code of the
module itself is complied without prototypes changing the behaviour.
Otherwise, the following patch is "useful"​:

Inline Patch
diff --git a/cpan/Math-Complex/lib/Math/Complex.pm b/cpan/Math-Complex/lib/Math/
index 8475a2b..201b4fd 100644
--- a/cpan/Math-Complex/lib/Math/Complex.pm
+++ b/cpan/Math-Complex/lib/Math/Complex.pm
@@ -806,7 +806,7 @@ sub Im {
 # Return or set rho(w).
 #
 sub rho {
-    Math::Complex::abs(@_);
+    &Math::Complex::abs(@_);
 }

 #
@@ -874,7 +874,7 @@ sub log {
 #
 # Alias for log().
 #
-sub ln { Math::Complex::log(@_) }
+sub ln { &Math::Complex::log(@_) }

 #
 # log10


else the _ prototype forces @_ to a scalar, which isn't the old, desired, or bug\-free behaviour\.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jul 18, 2016

From @dcollinsn

This was fixed in 5.10.1.

--
Respectfully,
Dan Collins

@p5pRT p5pRT closed this as completed Jul 18, 2016
@p5pRT
Copy link
Author

p5pRT commented Jul 18, 2016

@dcollinsn - 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