Section 15: FAQ
August 11, 2023 ยท View on GitHub
Section 15: FAQ
This file is automatically generated. If you wish to submit a PR, do not
edit this file directly. Please edit
templates/rfc/faq.md instead. Use bin/generate_rfc.pl to regenerate the RFCs.
15.1 Overview
You have questions? We have answers. Note that this is a work-in-progress. More may be added later.
15.1.1 Why can't I inherit from blessed objects?
Post-MVP this decision might be revisited, but for the MVP, we needed to constrain the problem space. Just some of the issues being faced:
classwill understand the difference between methods and subroutines and when the MVP is more fleshed out, will not allow you to call subroutines as methods. What do you do when the parent class isblesseded and all you have are subs?classis single-inheritance andblessis multiple inheritance. Having to switch the MRO back and forth as you walk the inheritance hierarchy is begging for bugs.- Ultimately,
classmight need a different base class, such asUNIVERSAL::Class. If we inherit from ablessed object, which base class wins? - Many awesome tools have been written for Moose and they assume Class::MOP works. We cannot make that assumption, so we don't.
Post-MVP, we might revision this decision, but for the MVP, there's a huge
amount of work to do and trying to make sure we didn't screw up anywhere is
much harder if we try to slurp in the entire blessed ecosystem. Bear with
us.
Otherwise, you can try the Object::Pad module. That's been the test bed for Corinna and it does allow inheriting from legacy objects. Caveat Emptor.
15.1.2 But I need to inherit from a blessed object!
No, you can't. Sorry. You can try Object::Pad, not use class, or
investigate composition over inheritance:
class My::Class {
use Some::Bless::Class;
field $arg_for_blessed :param(arg);
field $delegate = Some::Bless::Class->new($arg_for_blessed);
method to_delegate (@args) {
return $delegate->some_method(@args);
}
}
None of those answers are satisfactory, but this is an MVP.
15.1.3 Why can't I use subroutines for methods?
If you write this:
class My::Class {
field $name;
sub get_name ($self) { $name }
}
That's a syntax error because we can't access the instance variable $name
from a subroutine. They don't know what instance variables are. Or consider
these;
class Example1 {
sub sum ($self) { ... }
}
class Example2 {
use List::Util 'sum';
}
In both cases, we have a sum subroutine, but for the first, it's clearly
intended to be a method and not a helper function. From the outside, we have
no way of knowing that. class makes a clear distinction between methods and
subroutines and when the MVP is complete, $class->can('sum') should return
false if sum is a subroutine and not a method.
15.1.4 Will class break existing code?
No. Well, if you tried to slap it into an existing procedural code and you had subroutines with conflicting names to the keywords, maybe. Or you could use a lexical block and it should be perfectly safe:
# lots of code here
{
use feature 'class';
class Foo ...
}
# more code here, but it doesn't see `class` behavior
Otherwise, class objects can call methods on bless objects and vice-versa
without problem.
15.1.5 How can I refactor existing objects with class?
Er, you probably shouldn't. Rewriting is okay, but refactoring is a different story.
If you wanted to experiment, keep this in mind: a class cannot inherit from
blessed objects, but as of this writing, a blessed object can inherit
from a class object. So go to the root of your object hierarchy and look at
converting that to a class and see what happens.
For any decent-sized system, you're going to have too many edge cases for this
to be easy (or sane). For example, class constructors require an even-sized
list of key/value pairs. Many other constructors don't. You may need to
rethink your constructor strategy.
At the end of the day, trying to gradually mix-and-match an OOP hierarchy from
bless to class is like trying to use motorcycle parts to fix a car. Maybe
you'll get lucky and it works, but probably not for larger codebases (at least,
not without a lot of heavy lifting).
The above is for refactoring. However, you could rewrite existing objects via
the new class syntax. If your tests are sane, that may not be too hard.
However, if people are using your code, they may not be in a position to
upgrade to v5.38.0. You could investigate
Feature::Compat::Class, but
read the docs carefully. There are potential compatibility issues.
15.1.6 Are there any interesting projects being written with class?
Yes! Check out Chris "peregrin" Prather's Roguelike
tutorial. It's pretty amazing and
shows that class is more powerful than your author suspected (I thought we'd
need more features to get this far. I was wrong).
Stevan "Damn it" Little is writing Stella,
an actor model written with class. So far, he's been very pleased with how
easy class is to work with.
15.1.7 Are a class and a package the same thing?
Not quite. A class keyword declares a class and a namespace. A package
keyword just declares the namespace. They both have the same scoping rules.
What this means, however, is that you can use class similarly to how you
would use a package.
For example, if you have a file named lib/My/Awesome/Class.pm, you won't need
a package statement inside if you use class instead:
use experimental 'class';
class My::Awesome::Class;
# more code here ...
15.1.8 You keep writing classes with a postfix block. Is that required?
No, it's not. Like the package keyword, the postfix block is optional. I
prefer it for the extremely clear scoping. You don't need to use it if you
don't want to.
15.1.9 Is there a tutorial?
There's a tutorial at perlclasstut.pod.
Note that this tutorial is for the full MVP. If you're reading this before the full MVP is released, some of the features in that tutorial won't yet be working. I don't know what version of Perl you have installed, so you'll need to consult your documentation.
If you prefer, here's a gist of the tutorial, formatted via markdown. It's not guaranteed to be kept up-to-date.
15.1.10 How do I know which class features my Perl supports?
The experimental class feature was first added in Perl v5.38.0. You'll want
to check perldoc perlclass for your version of Perl. You can also read it
online, but be sure to select the correct
version of Perl from the menu at the top.