I know this is not the canonical bug tracker, but I don’t want to create a sourceforge account.
In perl 5.16-to-be, explicit return in an lvalue sub has been fixed, such that it no longer
copies the value to be returned.
For some reason, this function in Basic/Core/Core.pm (PDL-2.4.10; but this applies to _003
as well) is affected by this:
sub PDL::flat { # fall through if < 2D
return $_[0]->getndims != 1 ? $_[0]->clump(-1) : $_[0];
}
When getndims returns 1, the value returned by PDL::flat is the $_[0] scalar itself, not a copy
of that scalar.
For some reason, that causes this code in PDL::EditDistance’s t/01_distance.t test script to
behave differently:
sub makepdls {
($s1,$s2) = ('GUMBO','GAMBOL');
our $a = pdl(byte,[map { ord($_) } split(//,$s1)]);
our $b = pdl(byte,[map { ord($_) } split(//,$s2)]);
our $a1 = $a->flat->reshape($a->nelem+1)->rotate(1);
our $b1 = $b->flat->reshape($b->nelem+1)->rotate(1);
}
Not being a PDL user, I can’t really explain why; but I get error output like this later on as a
result:
Error in _edit_distance_full:Wrong dims
at Basic/Core/Core.pm.PL (i.e. PDL::Core.pm) line 396.
PDL::Core::barf('Error in _edit_distance_full:Wrong dims\x{a}') called at t/01_distance.t
line 36
main::test_distance_full() called at t/01_distance.t line 51
(To reproduce this, install perl 5.15.9 and type ‘test MOOCOW/PDL-EditDistance-
0.05001.tar.gz’ at the CPAN prompt.)
Through code inspection, I’ve managed to come up with the attached patch, which makes
PDL::flat behave the same way in 5.16 as it does in 5.14 and earlier. It uses a temporary
scalar that forces the value to be copied. (I don’t know whether other functions need similar
treatment.)
I’m not able to produce a small test case, as I would have to learn PDL first. :-)
Also, note that applying the lvalue attribute to an already-defined Perl sub has never actually
worked properly. Hence, in 5.16-to-be, there is this warning in attributes.pm’s docs:
Show quoted text
> This module allows one to set this attribute on a subroutine that is
> already defined. For Perl subroutines (XSUBs are fine), it may or may not
> do what you want, depending on the code inside the subroutine, with details
> subject to change in future Perl versions. You may run into problems with
> lvalue context not being propagated properly into the subroutine, or maybe
> even assertion failures. For this reason, a warning is emitted if warnings
> are enabled. In other words, you should only do this if you really know
> what you are doing. You have been warned.
(PDL already suppresses the warning that gets emitted.)
In this particular case, it ends up producing different results depending on how the code is
written. If you remove the explicit ‘return’, that works too, as leavesub and leavesublv are
two distinct ops. return is a single op type, that checks the flag on the current CV to
determine what type of return to do. That is all an implementation detail, subject to change.
The way I wrote the patch (using a temporary variable instead of relying on the way leavesub
is implemented) should be future-proof.
For reference, this ticket is derived from <https://rt.cpan.org/Ticket/Display.html?
id=76461>, but it also touches on issue discussed in
<https://rt.perl.org/rt3/Ticket/Display.html?id=107366>.
I made the severity ‘Critical’, because perl 5.16 is supposed to be released shortly.
Subject: | open_Wqa1Llaj.txt |
diff -rup PDL-2.4.10-uQtW7V-orig/Basic/Core/Core.pm PDL-2.4.10-uQtW7V/Basic/Core/Core.pm
--- PDL-2.4.10-uQtW7V-orig/Basic/Core/Core.pm 2012-04-15 12:06:00.000000000 -0700
+++ PDL-2.4.10-uQtW7V/Basic/Core/Core.pm 2012-04-15 12:06:37.000000000 -0700
@@ -2678,7 +2678,7 @@ Falls through if argument already E<lt>=
*flat = \&PDL::flat;
sub PDL::flat { # fall through if < 2D
- return $_[0]->getndims != 1 ? $_[0]->clump(-1) : $_[0];
+ return my $dummy = $_[0]->getndims != 1 ? $_[0]->clump(-1) : $_[0];
}
=head2 convert