Starting at the end (cos the the challenge was interesting:).

Sub::Exporter on the other hand is awesome. ... but it can do all sorts of fun tricks. You couldn't do this with Exporter:

Who needs Exporter :)

package LOLCat; use pudu 'has' => { -as => 'i_can_haz' }; i_can_haz 'cheeseburger' => ( is => 'rw', trigger => sub { print "NOM NOM" } ); 1;
#! perl -slw use strict; use LOLCat; LOLCat->new->cheeseburger('KTHNXBYE'); __END__ c:\test>t-pudu.pl NOM NOM

And what is actually required inside pudu.pm to make that happen?

package pudu; use strict; use warnings; use constant Exportables => { has => { -as => 'has' }, new => { -as => 'new' } }; my @attrs = (); sub _exportTo { no strict qw[ refs ]; *{ $_[0] . '::' . $_[ 1 ] } = $_[ 2 ]; } sub new { my $class = shift; die "Uneven attribute list (Missing value?(use 'undef')" if @_ & 1 +; my %args = @_; return bless \@attrs, $class; } sub has { my $package = caller; my $name = shift; my %attr = @_; $attrs[ @attrs ] = \%attr; my $slot = eval qq[ sub(){ ${ \$#attrs } } ]; _exportTo( $package, $name, sub :lvalue { $_[ 0 ][ &$slot ]{ trigger }->( $_[ 0 ], $_[ 1 ] ) if $_[ 0 ][ &$slot ]{ trigger }; $_[ 0 ][ &$slot ] } ); } sub import { my $class = shift; die "Uneven parameter list (Symbol without alias?)" if @_ & 1; my %args = ( %{ +Exportables }, @_ ); my %exports; @exports{ keys %{ +Exportables } } = delete @args{ keys %{ +Export +ables } }; warn "Unknown export(s) @{[ keys %args ]} ignored" if %args; my $package = caller; while( my( $export, $alias ) = each %exports ) { _exportTo( $package, $alias->{ -as }, \&$export ); } } 1;

It's minimal, just enough to meet the requirements of the challenge, but I hope it is enough to show that much of what Moose does, could be met without large dependency chains, and rather more efficiently. (Especially once you drop the need for bondage and discipline!)

I guess that sums up my feelings about a lot of this kind of module. (Sub::Exporter et al.) At their core, they provide a single, useful mechanism. But then, almost inevitably, they feel the need to add to that basic mechanism a bunch of "fun tricks", which whilst fun, often aren't required by most of their users. And the provision of those additional features, as much for the sake of having something to put in the POD as anything else, leads to complexity and bloat. Not just because of the presence of the additional code to provide those extra, little-used features. But also in additional code in the core, oft-used features in order to support the little used ones. With the result that code that only needs the core, useful mechanisms is often paying a penalty for the support of features that they don't use.

For the authors of these modules, they only test & benchmark their code from one level above, and the penalty seems minor. But once you get to the level of a complex framework like Moose, that utilises several of this type of module, and uses two, three & four levels deep chains of them, each adding its own layer of "fun tricks" and their associated (unnecessary) overhead, the individually small deltas start to add up.

Now imagine me writing my graphics application using Moose. I have a hierarchy of classes: Solids inherit from WireFrames inherit from Lines inherit from Point3D; and the core of my application is doing hidden Line and hidden Face removals on complex Solids before rendering to a View2D--the very stuff where Class/Object mechanisms like Moose are at their most useful and productive. And at each layer of my application I'm picking up the products of the deltas below Moose and compounding them over the layers of my application above Moose.

The result is that small, negative performance delta don't just add up, but multiply up, and my app is running 2 or 3 or 4 times more slowly because of the presence of features in the lowest levels that I, nor most other Moose users will ever use.

If you are really up for a challenge?

tos recently posted a behemoth of a piece of really quite awful code. (No disrespect meant tos. Its given me hours of fun exploring it). It sets out to be OO, but throws everything into one huge file because he's taken a bunch of short cuts (global vars mainly) to work around things he didn't understand how to do using Perl's DIY OO mechanisms. I had a couple of attempts at splitting it up into modules and making it work, but never really had the motivation to see it through.

It runs a 3D Rubix Cube (3x3, 4x4 or 5x5) simulation using Tk as the display tool, making extensive use of OO (mostly) to perform the math. It runs, in its presented, messy, badly structured form, with a surprising turn of speed. You can spin and rotate the cube in 3 dimensions using the mouse, and (when it doesn't crash) the graphics keep up with you.

The challenge is for us to agree the Moose-style class definitions for the 8 classes required by the Rubix Cube application:

package matob; package point3d; package line3d; package vec3d; package rect3d; package cube3d; package slice; package qb;

and then you port it to Moose and I'll extend pudu just enough to meet that specification. We could then compare, from all aspects, the results.

I realise that this is more than just a couple of hours work and that you're a busy guy, busy doing $work and maintaining Moose. But the results would make for a very good demonstration of the power of Moose (he said trying to tempt :).


(*)I mentioned "bondage & discipline" above. I realise that this is what a lot of your customers are asking for, and you are supplying that need. I did start to question that need here, but decided that it was irrelevant to the subject and besides, I feel a meditation on the subject coming on, so I've deferred that for another thread. And for the record. The more I learn about what Moose does (and the way it does it for the most part), the more impressed and enthralled I am by it. I'm even more impressed by what you and your team have pulled together so quickly.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

In reply to Re^12: Data Structures by BrowserUk
in thread Data Structures by YYCseismic

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.