Skip to content

Latest commit

 

History

History
194 lines (150 loc) · 7.09 KB

faq.md

File metadata and controls

194 lines (150 loc) · 7.09 KB

Prev: P5P MVP
Next: README


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:

  • class will 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 is blesseded and all you have are subs?
  • class is single-inheritance and bless is multiple inheritance. Having to switch the MRO back and forth as you walk the inheritance hierarchy is begging for bugs.
  • Ultimately, class might need a different base class, such as UNIVERSAL::Class. If we inherit from a blessed 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.


Prev: P5P MVP
Next: README