Intro

I've been looking at the docs for the new 'class' OO in upcoming Perl versions.

While i agree that Perl would benefit from a modern OO system, i think this new system shouldn't give up any of the flexibilities ye olde 'bless' provides.

Before i go into details, i must admit that i'm not a huge fan of the "attributes" stuff that most OO system use. Or at least not to the extend they are used anyway. I've seen code that uses like 4-5 attributes for a single class and just as much for a variable. I call this C++ line noise. Yes, it makes the code more concise(1), but when you have to spend a minute per line of code just to understand just the implication of these flags, they are not what i call helpful. Going forward, the new 'class' system will have to be very carefully design to avoid making a mess with attribute feature creep.

I also understand that 'class' is still in the early stages, so i can only look on what has been designed so far. My main questionmarks are:

Let's look at those in detail:

Abort object creation?

One of the nice things about 'bless' is that constructors are just functions with return values. This allows the constructor a lot of flexibility. One of those is to not construct an object under some circumstances. Something like this:

package Foo::Bar::UrlHandler; sub new($proto, %config) { my $class = ref($proto) || $proto; if(!defined($config{url})) { # No URL given, don't know what to do next return; } my $self = bless \%config, $class; return $self; }

The caller can easily check if things worked out:

my $handler = Foo::Bar::UrlHandler->new(url => 'http://perlmonks.org') or do_some_error_handling();

From what i understand, a 'class' is pretty much required to be created, no matter if that makes sense with the given parameters. This will probably make error handling/detection in the caller more complicated. And no, eval() is seldomly the solution to such problems but many times the cause of them.

Constructor not proper functions?

From the design, it seems you don't write the constructor as a proper function, you can only 'ADJUST()' what it does. This has a few implications that make it much less flexible than bless():

No "named" constructor

Modules like DBI (among others) make use of the fact that bless() can run in arbitrarily names constructors. For DBI, this is connect(). In my opinion, this makes it much clearer to the user of this module that constructing an new instance is not only an in-memory operation, it also connects to the server.

No option for multiple constructors

In my projects, i have a few modules that provide multiple constructor. For example, there might be a classic new(list-of-parameters), but also a newFromConfig(filename) that takes a filename to a configuration file. This makes especially sense when using sub signatures. Another example would be, say, a file parser that has a newFromFile() and newFromUrl() method.

Yes, you can achieve this by subclassing with the new 'class' OO, but that can make the code harder to maintain, especially if only the initialization differs.

No simple "factories"

I sometimes use the concept of "factories", e.g. modules that decide on given parameters which object to return. In keeping with the example of the UrlHandler above, something like this isn't too uncommon:

package Foo::Bar::UrlHandler; sub new($proto, %config) { my $class = ref($proto) || $proto; if(!defined($config{url})) { # No URL given, don't know what to do next return; } if($config{url} =~ /^http\:/) { return Foo::Bar::UrlHandler::HTTP->new(); } elsif($config{url} =~ /^file\:/) { return Foo::Bar::UrlHandler::FILE->new(); } # Invalid URL? return; }

Deciding when to call parent constructor?

Sometimes it's useful to decide WHEN and IF(2) to call the parent constructor. I don't see how that is properly handled by the 'class' OO.

sub new($proto, %config) { my $class = ref($proto) || $proto; # Override the default template $config{htmltemplate} = 'righttoleft.tt'; # Call parent constructor to load and parse template my $self = $class->SUPER::new(%config); # Re-bless bless $self, $class; # Re-bless with our class $self->do_our_own_stuff(); return $self; }

Conclusion

The new 'class' OO is a long overdue project and i thank the developers for their hard work. But at this early stage, it seems to be only a copy of other programming languages, without the flexibility Perl can (and currently does) provide when it comes to object orientation.

I'm using Perl (and ignore the Moo* stuff(3)) because i can shape the language to fit the problem. If we go the way in which we have to shape the problem to fit the language, we all might as well switch to there-is-only-one-way-to-do-it languages like C++, Java or TypesScript.

Yes, 'class' has the potential to make object oriented code easier to read and write, and i'm certainly all for that. We just need to make sure that it turns out TIMTOWTDI enough not to feature the same headaches as Java or C++. I can only talk about this from one own, small personal viewpoint, but because of (not "despite of"!) the flexibility of the old bless() OO and the typelessnes of Perl variables, in the last two decades i was able to single-handedly write a big web framework and implement multiple commercial systems in Perl.

Footnotes:
(1) just as $_ does. Which makes following code flow (and debugging it) a huge pain. Use $_ is banned in my projects.

(2) Sometime you override, sometime you enhance, sometimes the parameters to new() tell you what to do

(3) Combining the rigidity of C++ with the speed of Windows Vista somehow never appealed to me.

PerlMonks XP is useless? Not anymore: XPD - Do more with your PerlMonks XP

In reply to Thoughts on new 'class' OO in upcoming perl by cavac

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.