Re: Perl 28 broke L: How to fix?
by haukex (Archbishop) on Oct 28, 2019 at 09:11 UTC
|
It seems your usage of L depends on a "feature" that was deprecated over 20 years ago: It's setting up an AUTOLOAD function in the UNIVERSAL package, so that function calls such as Data::Dump::pp are sent to AUTOLOAD.
The module's tests only test a method call, and its synopsis only shows a method call. In fact, the breakage of the module was reported in #131571, and in the module's repository as #2. If I interpret the fix correctly, I think the module was never intended to work for regular function calls.
At the moment, I don't have any good ideas for a replacement. It's still possible to call Data::Dump->pp(), but that will pass the package as the first argument:
$ perl -wMstrict -ML -e 'Data::Dump->pp("x")'
("Data::Dump", "x")
Note that using -M actually doesn't necessarily make the one-liners longer:
$ perl -wMstrict -ML -e 'Data::Dump::pp("x")'
$ perl -wMstrict -MData::Dump=pp -e 'pp("x")'
| [reply] [d/l] [select] |
|
|
Note that using -M actually doesn't necessarily make the one-liners longer
Not for this example but the real win is not having to worry about -M at all once you have -ML.
breakage of the module was reported in #131571
Thanks for the history lesson. So Perl's appearance of backward compatability was an illusion due to not fatalizing deprecated bugs for 20 years? Bugs were mistaken for features: "So, this is something we're likely to see many times in this annual development cycle: code that breaks because we're fatalizing a behavior we've tolerated for twenty years (+ 1 month)."
I see a lot of messages from recent versions of Perl about code that is "no longer allowed" and "forbidden" and even "illegal"! The code police have made easy things impossible. If you guys can't figure this out my chances are slim:
haukex: At the moment, I don't have any good ideas for a replacement.
Corion: I'm not sure how to best implement the functionality of L.
| [reply] |
|
|
I see a lot of messages from recent versions of Perl about code that is "no longer allowed" and "forbidden" and even "illegal"! The code police have made easy things impossible.
I dunno about that, deprecations are usually made with a good amount of consideration, watching all of CPAN for breakage (as in this case) as a canary for how Perl is used by devs in production, and there is usually a workaround or fix possible for code that is affected by this. Personally, I don't remember really being affected by any surprising deprecations. So I'd be curious what problems specifically you've run into.
As I said, in this case, I doubt that this module was ever supposed to work with plain function calls, and only methods. If you look at the really early and unreleased version of the module, that's all it supported. And the tests specifically test for the failure of a function call.
If you guys can't figure this out my chances are slim
There are probably some hacks that would make it possible, but I think chances are that they'd be pretty ugly hacks. Note that using UNIVERSAL::AUTOLOAD is not so great to begin with - anything that installs things into UNIVERSAL risks having other modules break in mysterious ways.
| [reply] [d/l] [select] |
Re: Perl 28 broke L: How to fix?
by davido (Cardinal) on Oct 28, 2019 at 03:36 UTC
|
It's interesting that it doesn't exhibit failing tests on newer versions of Perl. I can confirm that it doesn't behave correctly on 5.30, if correct is to work both for OO modules AND for function modules. Here's the tester's matrix, showing that it is still passing: http://matrix.cpantesters.org/?dist=L+v1.0.1. So clearly the tests are inadequate. You might submit a patch that includes a test. If you feel up to fixing the problem itself, include that in the patch too. Otherwise, just the test so that the author can incorporate it, and have something to work with in fixing it. The module was most recently uploaded in December 2018, so it's possible the author is still open to maintaining it.
Fortunately it's really just saving a few keystrokes; one-liners will survive without it. Also worth noting, perhaps: Object/Class-method calls do work. It's functions (non-methods) that trip up the error.
| [reply] |
|
|
Fortunately it's really just saving a few keystrokes; one-liners will survive without it. Also worth noting, perhaps: Object/Class-method calls do work. It's functions (non-methods) that trip up the error.
I find it very valuable and wish to retain the ability to use modules on the command line without having to refer to them twice and tinker with -M! As for the second point, you would think so, but check this out:
perl -ML -e 'print Data::Dumper->Dump([HTTP::Tiny->new->get(q(https://
+www.perlmonks.org))->{headers}])'
5.26
$VAR1 = {
'server' => 'Apache/2.4.41',
'etag' => '"f059-595f109c01e50"',
'date' => 'Mon, 28 Oct 2019 04:38:47 GMT',
'last-modified' => 'Mon, 28 Oct 2019 04:36:06 GMT',
'content-length' => '61529',
'accept-ranges' => 'bytes',
'content-type' => 'text/html'
};
5.28
$VAR1 = {
'content-type' => 'text/plain',
'content-length' => 110
};
<Twilight Zone Music> | [reply] [d/l] |
|
|
17:17 >perl -ML -e "print Data::Dumper->Dump([HTTP::Tiny->new->get(q(h
+ttps://www.perlmonks.org))->{headers}]);"
$VAR1 = {
'content-type' => 'text/html',
'server' => 'Apache/2.4.41',
'etag' => '"e57e-595f34244bafb"',
'content-length' => '58750',
'last-modified' => 'Mon, 28 Oct 2019 07:15:04 GMT',
'accept-ranges' => 'bytes',
'date' => 'Mon, 28 Oct 2019 07:18:01 GMT'
};
17:18 >mversion -f L Data::Dumper HTTP::Tiny
L v1.0.1
Data::Dumper 2.173
HTTP::Tiny 0.070
17:18 >perl -v
This is perl 5, version 28, subversion 0 (v5.28.0) built for MSWin32-x
+64-multi-thread
Strawberry Perl v5.28.0 under Windows 8.1, 64-bit. Same (correct) result using Perl v5.30.0.
Cheers,
| [reply] [d/l] |
Re: Perl 28 broke L: How to fix?
by Corion (Patriarch) on Oct 28, 2019 at 09:17 UTC
|
You're calling dd as a function, but still expect AUTOLOAD to kick in. This doesn't work anymore, since Perl 5.28.
I'm not sure how to best implement the functionality of L. For real method calls, (ab)using UNIVERSAL::AUTOLOAD will continue to work I think, but for functions called by absolute name, I'm not aware of any approach where you can find the package name soon enough and then inject AUTOLOAD there.
Maybe you can work with a tie'd main:: or maybe you can add an INIT block to inject your AUTOLOAD into all packages that exist at that time.
| [reply] [d/l] [select] |
|
|
The simple fix for old code is: In any module that used to depend on inheriting AUTOLOAD for non-methods from a base class named BaseClass, execute *AUTOLOAD = \&BaseClass::AUTOLOAD during startup.
http://www.rocketaware.com/perl/perldelta/Deprecated_Inherited_C_AUTOLOAD.htm
| [reply] |
|
|
| [reply] |
Re: Perl 28 broke L: How to fix?
by tobyink (Canon) on Oct 29, 2019 at 00:16 UTC
|
Not perfect, but it will fix the majority of cases, including your example...
# add this to L.pm
use Filter::Simple;
FILTER {
while (/((?:[\w]+::)+)[\w]+\(/g) {
substr(my $module = $1, -2) = '';
eval { Module::Load::load($module) };
}
};
| [reply] [d/l] |
|
|
I added warn after every significant step in L.pm and read the docs for Filter::Simple to understand what your patch is doing. Nice work and thank you! I also learned that the eval doesn't seem necessary. I thought it was killing the warning about autoloading non-methods but I get no warnings for using functions!
perl -ML -e 'Data::Dump::dd(File::Spec::Functions::splitpath($^X))'
| [reply] [d/l] |
|
|
The eval is because the regexp might match a package name but you don't have a module with that name available to be loaded. For example, if "lib/Foo.pm" defines a function called "Foo::Bar::baz", then you run this:
perl -Ilib -MFoo -ML -e'Foo::Bar::baz(42)'
… without the eval it will die because "lib/Foo/Bar.pm" doesn't exist, even though "lib/Foo/Bar.pm" is unnecessary because "Foo::Bar::baz" is defined elsewhere in a module that successfully loaded.
| [reply] [d/l] [select] |
|
|
|
|
Re: Perl 28 broke L: How to fix?
by 1nickt (Canon) on Oct 28, 2019 at 13:34 UTC
|
$ perlbrew use perl-5.28.1
$ perl -ML -E 'say Data::Dumper->Dump([HTTP::Tiny->new->get("https://w
+ww.perlmonks.org")->{headers}])'
$VAR1 = {
'etag' => '"e96f-595f85f776cd3"',
'content-length' => '59759',
'last-modified' => 'Mon, 28 Oct 2019 13:21:09 GMT',
'content-type' => 'text/html',
'date' => 'Mon, 28 Oct 2019 13:22:14 GMT',
'server' => 'Apache/2.4.41',
'accept-ranges' => 'bytes'
};
$ perlbrew use perl-5.30.0
$ perl -ML -E 'say Data::Dumper->Dump([HTTP::Tiny->new->get("https://w
+ww.perlmonks.org")->{headers}])'
$VAR1 = {
'last-modified' => 'Mon, 28 Oct 2019 13:21:09 GMT',
'content-type' => 'text/html',
'content-length' => '59759',
'etag' => '"e96f-595f85f776cd3"',
'date' => 'Mon, 28 Oct 2019 13:22:23 GMT',
'accept-ranges' => 'bytes',
'server' => 'Apache/2.4.41'
};
Hope this helps!
The way forward always starts with a minimal test.
| [reply] [d/l] [select] |
Re: Perl 28 broke L: How to fix?
by Anonymous Monk on Oct 28, 2019 at 10:49 UTC
|
| [reply] |
|
|
Or add a l($) to -Mojo -e " l Data::Dump; dd g(q(example.com))->headers->to_hash "
perl -Mojo -E 'say r g("example.com")->headers->to_hash'
| [reply] [d/l] |
Re: Perl 28 broke L: How to fix?
by Anonymous Monk on Oct 28, 2019 at 02:59 UTC
|
file a bug report with author, wait :) | [reply] |
|
|
file a bug report with author
I considered that and checked the CPAN Testers Matrix but don't see any failures for L! I figured maybe L was doing something unintentional by loading non-methods that a perlbug allowed to happen all this time? L docs are sparse. Why else would Perl remove a way to do it? Since L is maintained it doesn't seem to be considered a bug.
Anyway I just saw davido's reply too and must say L is black magic to me. I don't even know what it's doing, nor if this is a bug in L, let alone how to fix it or anything. I just love L and want to keep up with new Perl versions and hope someone will post a patch so my local L will autoload non-methods again, without any warnings! 🙏 Thanx 😇
| [reply] |