Author: Curtis "Ovid" Poe <curtis.poe@gmail.com>
Sponsor:
ID: 0018
Status: Implemented
This PPC proposes a feature which, when used, eliminates the need to end a Perl module with the conventional "1" or other true value.
Eliminate the need for a true value at the end of a Perl file.
There's no need to have a true value be hard-coded in our files that we
use. Further, newer programmers can get confused because sometimes code
doesn't end with a true value but nonetheless compiles just fine because
something in the code returned a true value and the code compiles as a
side-effect.
First, a new feature is added:
use feature 'module_true';Then, whenever a module is loaded with require (or an equivalent, like
use), the "croak if false" test is skipped if the module_true feature was
in effect at the last statement executed in the required module.
There are no compatibility concerns I'm aware of because we're only suggesting changing behaviour in the presence of a newly-added feature that is not present in any existing code.
None expected.
Imagine this module:
package Demo1;
use feature 'module_true';
sub import {
warn "You imported a module!\n";
}When loaded by require or use anywhere in perl, this would import
successfully, despite the lack of a true value at the end.
This module shows an (almost certainly never useful) way to croak anyway:
package Demo2;
use feature 'module_true';
return 1 if $main::test_1;
return 0 if $main::test_2;
{
no feature 'module_true';
return 0 if $main::test_3;
}In this example, the only case in which requiring Demo2 would fail is if
$main::test_3 was true. The previous return 0 if $main::test_2 would still
be within the scope of the module_true feature, so the return value would be
ignored. When 0 is returned outside the effect of module_true, though, the
old behavior of testing the return value is back in effect.
There is a prototype implementation at true.
Due to this being a named feature, this can eventually be the default behavior
when use v5.XX; is used.
It's been discussed that we should return the package name instead. This supports:
my $obj = (require Some::Object::Class)->new;However, per haarg:
Changing the return value of require seems like a separate issue from what this PPC wants to address.
If you wanted require to always return the same value, and for that value to come from the file, you need a new location to store these values. This would probably mean a new superglobal to go along with %INC. And it would usually be useless because most modules return 1. I don't think this is a very good idea.
If you wanted require to always return the package name, it's a separate issue from this PPC because that means ignoring the return value from the file. It also presents a problem because require doesn't actually take package names. It takes file path fragments. Foo::Bar is translated to "Foo/Bar.pm" at parse time. This would then need to be converted back to a package name, or do something else. I don't think this is a good idea either.
Instead, it's probably best addressed with a builtin::load or similar routine that accepts a package as a string. This has been discussed in the past, and solves other problems. Module::Runtime has a use_module function that behaves like this, returning the package name.
Thus, we prefer simply returning true (or 1).
Copyright (C) 2022, Curtis "Ovid" Poe
This document and code and documentation within it may be used, redistributed and/or modified under the same terms as Perl itself.