[EXPERIMENT] use feature 'class'
use feature 'class' was first released in perl v5.38.0 as an experimental feature. This issue tracks its progress toward the end of its experimental phase.
Not sure if it's the right place to make suggestions.
Class feature has its own class keyword which declares a class and also a package. I'd like to use it in a bit more perlish way than what is usually given in examples: class at the top of the file and no block for the class.
class MyClass;
use v5.40;
method something () { ... }
The obvious problem is that I cannot have class at the top of the file because the feature was not yet enabled. As I understand, I will never be able to have that. Even if let's say class becomes stable and part of 5.50 bundle, I will still need to have the order reversed:
use v5.50;
class MyClass;
method something() { ... }
I think it's less readable and breaks the existing coventions which everyone follow, to have a package name as the first line in a .pm file. Of course, I can repeat myself with the package keyword:
package MyClass;
use feature 'class';
class MyClass;
I don't like this either, because it suggests that my package may contain something more than just a class.
So my suggestion is to consider auto-enabling the class feature if the very first line of a .pm file looks like a class declaration. I don't think it has much potental for breaking backward compatibility with existing code. It may look like an indirect call MyClass->class, but since it's just for the first line, I don't think any code ever does this. It will let us write classes in more perlish style, I think the package + class with block style looks more like PHP which has namespace + class with block as well.
I don't like this either, because it suggests that my package may contain something more than just a class.
Why does it suggest that? Regular old packages are exactly one class.
It may look like an indirect call MyClass->class
It looks like a regular call to sub class in the namespace from which MyClass.pm was do/use/require'ed. Without a package keyword the stuff in the file gets dumped into the package that do'ed the file. This has been useful to me exactly once, when turning an exceptionally large script into a collection of "klinda logically grouped bits" that get used back into main::.
This behaviour is why perlcritic has a "You must have a package declaration on the first line of your .pm" rule in the first place. Things get very spooky if you forget to put a package at the top - seemingly random stuff ends up in unexpected packages in stack traces if you sneak them ahead of the package line.
A more specific enclass MyClass keyword that enables class in the included file might address your specific complaint but it's pretty late in the features life cycle to go adding something that...
A more specific
enclass MyClasskeyword that enablesclassin the included file might address your specific complaint but it's pretty late in the features life cycle to go adding something that...
This leaks the responsibility to get it right into every caller. That seems like it would be awful to use. Worse you get new failure modes where the caller and the intention of the loaded code don’t match.
As I understand, I will never be able to have that. Even if let's say
classbecomes stable and part of 5.50 bundle, I will still need to have the order reversed:
I can see why one would dislike it but I don’t think there is a good other option…
But if I may, I’d like to wonder if it’s less readable or just less readable to someone used to a different order… because personally I switched long ago to putting (originally) use strict; use warnings; (in a single line) at the top of the file (and later use 5.012; use warnings;, and so on)… and my experience is that if I ever had to get used to it, it happened pretty quickly. So it’s not universally less readable; the question is whether it’s universally a matter of getting used to it.
I've taken a fairly standard style now of use VERSION being the very first (active) line of the file, followed by any other use feature or similar I wanted to be in scope, and then the package or class declaration as required, followed by all the other sorts of imports. It seems to work well in practice.
For example: https://metacpan.org/dist/App-eachperl/source/lib/App/eachperl.pm#L6
Writing use VERSION as the first line of a Perl file should be understood as declaring which version of the Perl language the rest of the file is written in. (Even if that's technically not exactly what it does.)
I remember previous PSC members (especially @rjbs) speaking of this as "Line 1 Semantics" (versus "Line 0 Semantics" being the good old Perl v5.8 semantics.)
I for one really want to encourage use VERSION on the first line of every Perl file. This should basically become the new "use strict and warnings" mantra.
I submitted Perl-Critic/Perl-Critic#1070 exactly for this reason.
@ap Yes, enclass would be troublesome, especially if software outside your control depends on your module/class...
The thing is the only place "before" the first line of the .pm is some place the caller... unless you want a -w-style global flag about it in the #! of your calling script