Open tobyink opened 3 years ago
From $_ = 'spro^^%^6ut#@&$%*c>#!^!#&!pan.org'; y/a-z.@//cd; print on 2017-10-30 01:31:26 :
On Sun Oct 29 21:18:50 2017, SPROUT wrote:
PL_curstname is a char* holding the package name,
Correction: PL_curstname is an SV*, but this does not affect Moops.
Migrated from rt.cpan.org #123445 (status was 'open')
Requestors:
From $_ = 'spro^^%^6ut#@&$%*c>#!^!#&!pan.org'; y/a-z.@//cd; print on 2017-10-30 01:18:50 :
If I run this script:
!perl
package What::Ever;
use Moops; class Foo {
};
eval { Foo->meta }; warn $@ if $@; eval { What::Ever::Foo->meta }; warn $@ if $@; END
I get this error message:
Can't locate object method "meta" via package "Foo" (perhaps you forgot to load "Foo"?) at - line 9.
If I comment out the package declaration, I get this error message:
Can't locate object method "meta" via package "What::Ever::Foo" (perhaps you forgot to load "What::Ever::Foo"?) at - line 7.
Judging by the code, I think this is by design. But here is the catch: When a module (or any file) is loaded via âuseâ or ârequireâ, the package in which the module is initially compiled is that of the caller (the code containing the ârequireâ statement). That means that this module:
$ cat Pfoom.pm use Moops; class Pfoom { } END
may define a top-level Pfoom class (if âuse Pfoomâ is in main), or it may define a subpackage, such as Gromple::Pfoom (if âuse Pfoomâ is in the Gromple package).
Now, there is a glitch in existing Perl versions up to 5.27.4, in that, while PL_curstash points to the package of the code currently being compiled and PL_curstname is a char* holding the package name, sometimes they can get out of synch, because PL_curstname is set only with âpackageâ declarations, and not at the beginning of a string eval or file.
In bleadperl (5.27.5) I fixed it, because it was causing the wrong package to show up in error messages (see https://perl5.git.perl.org/perl.git/commitdiff/04680144c43).
Now Parse::Keyword::compiling_package, which Moops happens to use, gets the name from PL_curstname, the variable that is sometimes off.
This means that
will create a Pfoom class as long as there is no currently compiling scope, but
will create a package named Whatever::Pfoom, assuming that the scope in which âuseâ occurs has a âpackage Whateverâ declaration in it.
As of 5.27.6, the former behaves consistently the same way as the latter, which happens to break Pod::Elemental::Transformer::Splint (https://rt.perl.org/Ticket/Display.html?id=132373).
I can see two possible ways for you to fix this unpredictability in the way Moops handles unqualified package names:
1) Drop support for nested package names; just do things the Perl 5 way.
2) Look at the file name of the code that is currently being compiled. (I donât know offhand how to do that from pure-Perl, but I can look into it if you want to follow this route.)