Stevan's Journal Stevan's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:11:46+00:00 pudge Technology hourly 1 1970-01-01T00:00+00:00 Stevan's Journal Task::Moose released <p> I have just uploaded <a href="">Task::Moose</a> which provides a simple way to install Moose and (optionally) install many useful extensions as well. This is not only a handy way to install Moose, but it is a nice way to keep a running list of the latest extensions and add-ons. </p><p> I am also quite proud of the fact that Moose now has <a href=";perl=5.8.8&amp;os=any+OS">100% chance of installing smoothly on Perl 5.8.8</a> and <a href=";perl=5.10&amp;os=any+OS">we are in the high 90%s for Perl 5.10</a>. It is a common myth that Moose is full of magic and has lots of heavy dependencies, but the reality is we use suprisingly little magic and have 9 non-core dependencies (yes, there is some XS in there, but hey, you want it fast right?). </p><p> - Stevan </p> Stevan 2008-03-14T21:25:31+00:00 journal New Moose Features in 0.34 <p> The latest release of <a href="">Moose</a> (0.34) brings with it some very nice features as well as a major re-factoring of the role system (I am finally happy with the design now too) and a re-factoring of the parameterized types. While most of the information on the new features is in the <a href="">Changes</a> file, I figured that they are cool enough to be blog-worthy too, so here goes. </p><p> <b>New Maybe[`a] parameterized type</b> </p><p> The handling of parameterized types has been re-factored so that it is now possible to add new parameterized types without needing them to be based off the ArrayRef or HashRef type (no syntactic sugar yet though). As a demonstration of this, and because it's just a useful thing anyway I have added the Maybe[`a] type. This type basically means "maybe there will be a value, and if there is, it will be of type `a", users of Haskell will be familiar with this (as will O'Caml users, it is similar to the 'option' type). Here is an example of the usage: </p><blockquote><div><p> <tt>package Person;<br>use Moose;<br> <br>has 'first_name'&nbsp; &nbsp; &nbsp;=&gt; (is =&gt; 'rw', isa =&gt; 'Str');<br>has 'last_name'&nbsp; &nbsp; &nbsp; =&gt; (is =&gt; 'rw', isa =&gt; 'Str');<br>has 'middle_initial' =&gt; (is =&gt; 'rw', isa =&gt; 'Maybe[Str]');</tt></p></div> </blockquote><p> The 'middle_initial' attribute now allows either a string or an undefined value to be stored. </p><p> <b>Role method exclusion and aliasing</b> </p><p> Role composition follows a strictly defined set of rules, this is one of the benefits of roles over your basic mix-ins or multiple inheritance. But sometimes, you want to subvert those rules and have more control over the composition process. The <a href="">original Traits paper</a> (on which Roles are based) included both 'exclusion' and 'aliasing' operations as a way of modifying the composition process. I included these features when I originally wrote <a href="">Class::Trait</a>, but since @larry had not added them into Perl 6 I hadn't included support in <a href="">Moose</a>. Now after several months of using Roles I now see the original wisdom of the Traits paper authors and these features are now available in <a href="">Moose</a>. Here are some examples of usage: </p><p> Lets create an Equality role, which provides the mechanism for determining, well, equality.</p><blockquote><div><p> <tt>package Equality;<br>use Moose::Role;<br> <br>requires 'equal';<br>sub not_equal { not((shift)-&gt;equal(@_)) }</tt></p></div> </blockquote><p>Now lets define two more roles which do the Equality role, first a 'HasColor' role:</p><blockquote><div><p> <tt>package HasColor;<br>use Moose::Role;<br> <br>with 'Equality';<br> <br># create an attribute to hold RGB values<br>has 'rgb' =&gt; (is =&gt; 'rw', isa =&gt; 'ArrayRef[Int]');<br> <br>sub equal {<nobr> <wbr></nobr>... code to compare RBG values<nobr> <wbr></nobr>... }</tt></p></div> </blockquote><p>And now a 'HasCoordinate' role</p><blockquote><div><p> <tt>package HasCoordinate;<br>use Moose::Role;<br> <br>with 'Equality';<br> <br># create an attribute to hold x/y values<br>has 'coord' =&gt; (is =&gt; 'rw', isa =&gt; 'ArrayRef[Int]');<br> <br>sub equal {<nobr> <wbr></nobr>... code to compare x/y values<nobr> <wbr></nobr>... }</tt></p></div> </blockquote><p>Now if my 'Pixel' class wanted to use both the 'HasColor' and 'HasCoordinate' roles,<nobr> <wbr></nobr>...</p><blockquote><div><p> <tt>package Pixel;<br>use Moose;<br> <br>with 'HasColor', 'HasCoordinate';</tt></p></div> </blockquote><p>I would have a problem because their 'equal' methods would conflict. The conflict means that the 'Pixel' class must then implement an 'equal' method of it's own. I could implement it like so:</p><blockquote><div><p> <tt>sub equal {<br>&nbsp; &nbsp; my ($self, $other) = @_;<br>&nbsp; &nbsp; $self-&gt;HasColor::equal($other) &amp;&amp;<br>&nbsp; &nbsp; $self-&gt;HasCoordinate::equal($other);<br>}</tt></p></div> </blockquote><p>but the hardcoding of role names like this is a design smell IMO. We also have lost color and coordinate comparison abilities in our 'Pixel' class. Here is a different approach using exclusion and aliasing to provide (IMO) a much superior solution. </p><blockquote><div><p> <tt>package Pixel;<br>use Moose;<br> <br>with 'HasColor' =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; excludes =&gt; 'equal',<br>&nbsp; &nbsp; &nbsp; &nbsp; alias&nbsp; &nbsp; =&gt; { equal =&gt; 'color_equal' }<br>&nbsp; &nbsp; &nbsp;},<br>&nbsp; &nbsp; &nbsp;'HasCoordinate' =&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; excludes =&gt; 'equal',<br>&nbsp; &nbsp; &nbsp; &nbsp; alias&nbsp; &nbsp; =&gt; { equal =&gt; 'coord_equal' }<br>&nbsp; &nbsp; &nbsp;};<br> <br>sub equal {<br>&nbsp; &nbsp; my ($self, $other) = @_;<br>&nbsp; &nbsp; $self-&gt;color_equal($other) &amp;&amp; $self-&gt;coord_equal($other);<br>}</tt></p></div> </blockquote><p> The above code now removes the conflict between the 'equal' methods, but aliases them so that the features are not lost and finally implements equals in terms of them. </p><p> Of course this example is a little on the contrived side, but you get the point. Anyone who has messed around with roles enough will surely rejoice at this new feature addition. </p><p> <b>Attribute Metaclass traits</b> </p><p> We already have support for custom attribute metaclasses and this feature is used in a number of modules, <a href="">MooseX::Getopt</a>, <a href="">MooseX::Storage</a> and <a href="">MooseX::AttributeHelpers</a> to name a few. It allows you to extend the features of <a href="">Moose</a> attributes to provide additional functionality within the same <a href="">Moose</a> framework. The one problem with this feature has always been that it is very difficult to combine these extensions and use more than one at a time. Here is a (very contrived) example of how this feature will be useful. </p><blockquote><div><p> <tt>package My::App;<br>use Moose;<br>use MooseX::Storage;<br>use MooseX::Getopt;<br> <br>has 'some_thing' =&gt; (<br>&nbsp; &nbsp; traits =&gt; [qw/DoNotSerialize NoGetopt/],<br>&nbsp; &nbsp; is&nbsp; &nbsp; &nbsp;=&gt; 'rw',<br>&nbsp; &nbsp; isa&nbsp; &nbsp; =&gt; 'ArrayRef[Big::Heavy::Things]',<br>&nbsp; &nbsp; #<nobr> <wbr></nobr>...<br>);</tt></p></div> </blockquote><p> Currently <a href="">MooseX::Storage</a> provides a DoNotSerialize metaclass which lets the <a href="">MooseX::Storage</a> engine know to skip that attribute when serializing. This is fine, until you need to also use the <a href="">MooseX::Getopt</a> provided NoGetopt metaclass (which, yes you guessed it, tells <a href="">MooseX::Getopt</a> that this is not a command line parameter). I will soon be releasing versions of those two modules which will make the above example work, allowing you to easily combine both non-serialization with non-getopt-parsing. (Sorry, that was the best example I could come up with right now, we are working on a possible cookbook entry so if this interests you keep you eyes out). </p><p> <b>And lastly<nobr> <wbr></nobr>...</b> </p><p> And lastly, in addition to all this new functionality, I would like to announce the upcoming release of MooseX::Compile 0.01 (possibly by tomorrow morning). MooseX::Compile is a project here at $work which takes all the stored meta-information of a <a href="">Moose</a> class and compiles a<nobr> <wbr></nobr>.pmc file which defers loading the bulk of the <a href="">Moose</a> infrastructure and caches the already computed metaclasses. It is still in it's very early stages, and only supports a subset of <a href="">Moose</a>, but results are extremely promising. </p><p> - Stevan </p> Stevan 2008-01-22T04:03:56+00:00 journal All I want for Christmas is Perl 5.12 <p> Don't get me wrong, I love Perl 6, I spend most of my spare time maintaining a <a href="">port of its object system in Perl 5</a>. But lets be realistic, if Perl 6.0.0 comes out in Christmas 200x I will not be rushing to load it onto my production boxes and stake my livelihood on it. This is not beacuse I have no faith in the Perl 6 team, quite the contrary, just that it is an untested language (no, not unit tests, and audreyt deploying Pugs in prod doesn't count) and an untested platform (Parrot). Now Christmas 200(x + 1), thats a different story. </p><p> So, with that disclaimer out of the way, I have to say that I am really excited about the developments taking place on p5p regarding the Perl 5.12 features. Perl 5.10 is already got some really nice bits and 5.12 will surely introduce even more, bringing us even closer to the Perl 6 goodness. Yes, yes, even with its infamous jenga internals Perl 5 is still rock solid (it has never done me wrong), and with 16,000,000+ lines of nightmare legacy code (a.k.a. - CPAN) I know it's well tested. </p><p> - Stevan </p> Stevan 2008-01-16T15:49:55+00:00 journal Moose 2x Speed-Up <p> One of the biggest complaints/problems with Moose has always been it's compile time cost. Well with the newest release of Moose (0.33) and Class::MOP (0.49) we have made a major step towards reducing that. With judicious use of XS (konobi++ for that) and some caching in key parts of Class::MOP we have managed to <b>cut Moose load time almost in half</b>, here are the stats from my machine (MacBook Pro w/ 2.4 GHz Intel Core 2 Duo). </p><blockquote><div><p> <i> Moose 0.32 &amp; Class::MOP 0.48 =&gt; 0.46 real 0.43 user 0.02 sys <br> Moose 0.33 &amp; Class::MOP 0.49 =&gt; 0.27 real 0.22 user 0.02 sys </i></p></div> </blockquote><p> This change also brings allowed us to take advantage of some 5.10 specific improvements as well. In 5.8.* we use the PL_sub_generation interpreter global to determine when to invalidate our method cache, which was one of the big parts of the speed win. In 5.8.* this is incremented every time a package is changed, which means we were probably invalidating our cache even when we didn't need to. Now in 5.10 we are using the mro::get_pkg_gen function, which provides the same feature but increments on a per-package basis, which means less incorrect cache invalidation. </p><p> All in all, not bad for a few hours of work by the folks on #moose. </p><p> - Stevan </p><p> <small> <b>NOTE:</b> I got my stats wrong in the ChangeLogs, I called it a ~45% speed increase, but it is really 45% less slow. </small> </p> Stevan 2007-12-14T22:10:43+00:00 journal YAPC::EU Moose slides uploaded <p> I have just uploaded the <a href="">slides</a> from the Moose talk I gave yesterday at YAPC::EU. They are a revised version of a talk I gave at the Perl Seminiar NY earlier this year, I think this version flows a little better and I was pretty happy with how the talk went. I was hoping to include more information about roles into this talk, but there was not time. Maybe the next talk. </p><p> - Stevan</p> Stevan 2007-08-30T10:03:08+00:00 journal Class::MOP/Moose now works in 5.9.5 <p> Finally, thanks to mst (of <a href="">DBIx::Class</a> fame) we have a new version of <a href="">Class::MOP</a> which passes all tests cleanly in <a href="">perl 5.9.5</a> (all while retaining backwards compat too). This was after a few attempts at fixing and then a couple attempts at just silencing the offending test (it really was just an edge case which did not affect the actual operation of the module), we now actually have a <a href="">properly passing version</a>. <a href="">Horray for mst!</a> </p><p> This now paves the way for experimenting with the new features of 5.9.5 in Class::MOP and Moose themselves, specifically the mro pragma, the given/when construct and smart matching. I plan on using my YAPC::EU time away from $work to start an experimental branch. Should be fun! </p><p> - Stevan</p> Stevan 2007-07-17T13:40:20+00:00 journal Moose is turning 1yr old soon <p> About <a href="">a year ago</a> I released the first version of <a href=";query=Moose">Moose</a> to CPAN, and since then <a href="">we</a> have used it extensively in a number of projects. And now with 3 apps which have been in production for between 6 and 9 months without issue, and positive reports from several other developers who have had similar experiences, I am happy to announce that <a href=";query=Moose">Moose</a> is pretty much ready for general use (i.e. - not scary anymore). </p><p> <b>Huh, what,.. Moose??,.. what are you talking about??</b> </p><p> For those who don't know, <a href=";query=Moose">Moose</a> is a complete modern object framework for Perl based on the work done by myself and others in the <a href=";query=Pugs">Pugs</a> and Perl 6 projects. It does not claim to be Perl 6, but instead brings a Perl 6 like object system to Perl 5. This means it is built from the groud up to play nicely with existing Perl 5 objects and object systems. </p><p> <b>So where can I get more information?</b> </p><p> Well, lots of places actually. A good place to start is the <a href="">Moose::Cookbook</a>. Additional resources can be found from <a href="">here</a> as well. </p><p> There is also an ever growing set of <a href=";query=MooseX">MooseX::</a> plugins being developed to extend and enhance Moose (some are still under development <a href="">here</a>, but soon to be released). </p><p> I am also going to be giving a talk at the upcoming Perl NY Seminar on April 17th (I will post more details on this later), and (if they get accepted) hopefully at least one talk at this years YAPC::EU. </p><p> <b>Does this mean 1.0 is coming out soon?</b> </p><p> Nah, I decided 1.0 was just a number, and a silly one at that. The latest stable (0.18) should be thought of as "1.0" in spirit, just not in name. </p><p> -Stevan </p> Stevan 2007-04-03T20:24:08+00:00 journal Class::MOP browser - Now Smalltalk ain't got nothin' on us <p> I recently hacked together a very basic <a href="">Smalltalk-esque class browser</a> for <a href="">Class::MOP</a>. This is really just a basic proof of concept, and it was pretty simple to build, in fact, <a href="">it is pretty much all TT code</a>. (My CSS and HTML skills are sorely lacking, so my apologies if it looks really bad). </p><p> Of course being a proof of concept, it has many caveats. To start with, it needs the <a href="">bleeding edge (svn) version of Class::MOP</a>. It does not yet work well with Moose either (this is because the latest Moose is not yet synced up with the bleeding edge Class::MOP). </p><p> But it is not all bad news<nobr> <wbr></nobr>:) it does some really cool stuff as well. To start with, it is not just restircted to Class::MOP and Moose classes. Because Class::MOP is meant to also be able to introspect vanilla Perl OO, it can be used to browse those classes as well. And if you are using Moose or Class::MOP, the browser simply loads all the metaclasses in Class::MOP's metaclass cache, so as long as you load your classes, they will appear in the browser. </p><p> The eventual goal is to make this into a more full featured class browser, with full support for both Moose and non-Moose classes &amp; possibly also including documentation (parsed from the POD). But anyway, enough babbling, back to $work for now. </p><p> - Stevan </p> Stevan 2006-09-14T19:22:55+00:00 journal Moose::Autobox - Ruby ain't got nothin on us <p> I have just released the newest version of <a href="">Moose::Autobox</a> (0.03 to be exact), which adds a few nice improvements. First is that you no longer need to <code>use autobox</code>, just <code>use Moose::Autobox</code> will do. Next is the ability to mixin new roles at runtime, which makes neat things like this <a href="">Ruby ActiveSupport</a> style date trick very easy to accomplish. </p><blockquote><div><p> <tt>Moose::Autobox-&gt;mixin_additional_role(SCALAR =&gt; 'Units::Time');<br> <br>print 2-&gt;days-&gt;ago-&gt;as_string;<br>print 3-&gt;weeks-&gt;from_now-&gt;as_string;</tt></p></div> </blockquote><p> See the <a href="">Moose::Autobox examples</a> directory for more details. </p><p> The next new toy (and my personal favorite) is the Y combinator is now available for CODE references. For those who are not familiar the Y combinator is a <a href="">fixed-point combinator</a> which can be used to turn an unnamed or anonymous subroutine into a recursive one. It does this through a series of complex tricks which are beyond the scope of this post, so it is probably best to just show a code example. </p><blockquote><div><p> <tt>my $factorial = sub {<br>&nbsp; &nbsp; my $f = shift;<br>&nbsp; &nbsp; sub {<br>&nbsp; &nbsp; &nbsp; &nbsp; my $n = shift;<br>&nbsp; &nbsp; &nbsp; &nbsp; return 1 if $n &lt; 2;<br>&nbsp; &nbsp; &nbsp; &nbsp; return $n * $f-&gt;($n - 1);<br>&nbsp; &nbsp; }<br>}-&gt;y;<br> <br>$factorial-&gt;(10) # returns 3628800</tt></p></div> </blockquote><p> This is now much shorter then the <a href="">ruby</a> version (and cleaner to IMHO). </p><p> Now all we need is a <a href="">dashingly handsome spokesmodel</a> and Perl can be the new Ruby<nobr> <wbr></nobr>;) </p><p> - Stevan </p> Stevan 2006-08-17T19:38:28+00:00 journal Flexing Moose <p> I tried to build <a href="">Moose</a> to be a very flexible system. Pretty much <i>all</i> it's behaviors can be customized by overriding/extending it's default metaclasses. However, metaclass hacking can be both scary and very tricky, which is where <a href="">Moose::Policy</a> comes in. </p><p> One of the most <a href="">common complaints</a> I have heard about <a href="">Moose</a> is that it does not support { get, set }_foo (<i>Perl Best Practicies approved</i>) style accessors out of the box. Of course, this is easily done with a custom attribute metaclass, but that's not what people tend to want to hear. Now, with <a href="">Moose::Policy</a> it is as simple as this:</p><blockquote><div><p> <tt>package Point;<br>use Moose::Policy 'Moose::Policy::FollowPBP';<br>use Moose;<br> <br>has 'x' =&gt; (is =&gt; 'rw', isa =&gt; 'Int');<br>has 'y' =&gt; (is =&gt; 'rw', isa =&gt; 'Int');</tt></p></div> </blockquote><p>Now Point has <code>get_x, get_y, set_x</code> and <code>set_y</code> methods generated for it's accessors. </p><p> <a href="">Moose::Policy</a> is basically a way to manage a set of metaclass customizations on a class-per-class basis without having to deal with those metaclasses directly. It also makes it pretty easy to package up these customizations for distribution with your project since a Policy is just another Perl 5 package file (see <a href="">Moose::Policy</a> for some examples). </p><p> The future plans for <a href="">Moose::Policy</a> include creating a number of roles which can be composed together to create custom policies without even having to touch metaclasses at all. </p><p> So, if you have looked at <a href="">Moose</a> and thought to yourself, "I would use it if only it had <i>x</i> feature", then let me know. Chances are that feature can be made into a <a href="">Moose::Policy</a> and we can add it to the distribution. </p><p> - Stevan </p> Stevan 2006-08-11T18:24:12+00:00 journal Roles for Moose <p> I have just released <a href="">Moose 0.09_01</a> (as well as <a href="">Class::MOP 0.29_01</a> to go with it). It is a fairly significant update with a number of new features, the most interesting of them being a fairly complete implementation of Roles. For the most part the Role features are based on Perl 6 roles, but I have added a few features from <a href="">the original Traits paper</a> and some new ideas from <a href="">the Fortress spec</a>. </p><p> Roles in Moose look a lot like classes in Moose do, in fact almost all Moose class keywords are supported in Moose::Role. Here are some basic examples. </p><blockquote><div><p> <tt>package Equality;<br>use Moose::Role;<br> <br>requires 'equal_to';<br> <br>sub not_equal_to {<br>&nbsp; &nbsp; my ($self, $other) = @_;<br>&nbsp; &nbsp; not $self-&gt;equal_to($other);<br>}</tt></p></div> </blockquote><p> This is a basic Equality role, it requires any class which 'does' it to implement a method called 'equal_to', and then provides a 'not_equal_to' method to compliment it. The 'requires' feature is not from Perl 6, but from the original Traits paper, although Perl 6 mimics this with the 'method stub' feature. </p><blockquote><div><p> <tt>package Molecule::Organic;<br>use Moose::Role;<br> <br>excludes 'Molecule::Inorganic';<br> <br>package Molecule::Inorganic;<br>use Moose::Role;</tt></p></div> </blockquote><p> This is a feature from the latest Fortress language spec (the example is taken from there as well). Obviously a class would not want to 'do' both Molecule::Organic and Molecule::Inorganic roles, they are mutually exclusive. The 'excludes' keyword allows you to state that explicitly. This will assure than any class which 'does' Molecule::Organic (and all it's subsequent subclasses) will never be allowed to 'do' Molecule::Inorganic, and vice versa. </p><blockquote><div><p> <tt>package CGI::Application::Role::RequestLogger;<br>use Moose::Role<br> <br>before 'run' =&gt; sub {<br>&nbsp; &nbsp; my $self = shift;<br>&nbsp; &nbsp; warn '-' x 80;<br>&nbsp; &nbsp; warn "REQUEST_URI: " . $ENV{REQUEST_URI};<br>&nbsp; &nbsp; warn "Query Params:";<br>&nbsp; &nbsp; warn "\t$_ =&gt; " . $self-&gt;query-&gt;param($_)<br>&nbsp; &nbsp; &nbsp; &nbsp; for $self-&gt;query-&gt;param();<br>&nbsp; &nbsp; warn '-' x 80;<br>};</tt></p></div> </blockquote><p> Moose Roles also support the method modifiers as well. When a CGI::Application subclass 'does' this role, the 'run' method (which does all the dispatching) will be wrapped and a number of useful bits will be dumped to STDERR. Using it as simple as this: </p><blockquote><div><p> <tt>package My::CGI::Application;<br>use Moose;<br> <br>extends 'CGI::Application';<br>&nbsp; &nbsp;with 'CGI::Application::Role::RequestLogger';<br> <br>#<nobr> <wbr></nobr>... now write your CGI::App subclass<nobr> <wbr></nobr>...</tt></p></div> </blockquote><p> Role now also have fairly sophisticated conflict detection mechanism as well. This allows roles to be combined together in a symmetrical way which will catch a number of compositional problems, and assure all requirements are met. We even handle mutually recursive roles like these: </p><blockquote><div><p> <tt>package Role::Foo;<br>use Moose::Role;<br> <br>requires 'foo';<br>sub bar { 'Role::Foo::bar' }<br> <br>package Role::Bar;<br>use Moose::Role;<br> <br>requires 'bar';<br>sub foo { 'Role::Bar::foo' }<br> <br>package Foo::Bar;<br>use Moose;<br> <br># this will Just Work<br>with 'Role::Foo', 'Role::Bar';</tt></p></div> </blockquote><p> This is similar to how Perl 6 will work, but once again, we diverge slightly. Moose roles can be combined (as above), and conflicts and requirements will be handled automatically, and they can also be combined manually with multiple 'with' keywords. This allows for a greater degree of control when you need it. </p><p> Roles are also showing a lot of promise at $work as an excellent plugin mechanism. This is where the 'requires' and 'excludes' features are coming in quite handy. They have the potential to prevent a whole class of composition issues which the usual 'mixin' based plugin methods are sometimes plagued with. </p><p> Some people have been experimenting with Roles to implement abstract classes and Java-style interfaces. The 'abstract' methods which a classes must implement can just be marked with the 'requires' keyword, and the class which 'does' the role has to implement them. </p><p> So, please give Moose 0.09_01 a try and play with Roles, and let me know what you think<nobr> <wbr></nobr>:) </p><p> - Stevan </p> Stevan 2006-05-13T03:12:23+00:00 journal Moose, it's the new Camel <p> I have released a <a href="">Moose</a> onto CPAN<nobr> <wbr></nobr>:) </p><p> <a href="">Moose</a> is <i>yet another way to write Perl 5 OO</i>, however, this time it's different (it is, really, I swear). I have built <a href="">Moose</a> on top of the metaclass framework <a href="">Class::MOP</a>, so all the "magic" that <a href="">Moose</a> does is built upon the solid theoretical foundations found in other object systems like <a href="">CLOS</a>, <a href="">Smalltalk 80</a> and <a href="">SOM</a>. </p><p> <a href="">Moose</a> development is still in the early stages, but since it is really just an interface to the underlying meta-objects of <a href="">Class::MOP</a> it is pretty stable. In fact, stability and lack of deep/dark magic are two key design goals of both <a href="">Moose</a> and <a href="">Class::MOP</a>, as well as the idea that <i>you only pay for the features you use, and nothing else</i>. Because <a href="">Moose</a> is built upon a metaclass framework, it is possible to encode a lot of information in a very small amout of code, and let the metaclasses do the bulk of the work. Here is an example taken from the tests: </p><blockquote><div><p> <tt>package BankAccount;<br>use strict;<br>use warnings;<br>use Moose;<br> <br>has 'balance' =&gt; (isa =&gt; 'Int', is =&gt; 'rw', default =&gt; 0);<br> <br>sub deposit {<br>&nbsp; &nbsp; my ($self, $amount) = @_;<br>&nbsp; &nbsp; $self-&gt;balance($self-&gt;balance + $amount);<br>}<br> <br>sub withdraw {<br>&nbsp; &nbsp; my ($self, $amount) = @_;<br>&nbsp; &nbsp; my $current_balance = $self-&gt;balance();<br>&nbsp; &nbsp; ($current_balance &gt;= $amount)<br>&nbsp; &nbsp; &nbsp; &nbsp; || confess "Account overdrawn";<br>&nbsp; &nbsp; $self-&gt;balance($current_balance - $amount);<br>}<br> <br>package CheckingAccount;<br>use strict;<br>use warnings;<br>use Moose;<br> <br>extends 'BankAccount';<br> <br>has 'overdraft_account' =&gt; (isa =&gt; 'BankAccount', is =&gt; 'rw');<br> <br>before 'withdraw' =&gt; sub {<br>&nbsp; &nbsp; my ($self, $amount) = @_;<br>&nbsp; &nbsp; my $overdraft_amount = $amount - $self-&gt;balance();<br>&nbsp; &nbsp; if ($overdraft_amount &gt; 0) {<br>&nbsp; &nbsp; &nbsp; &nbsp; $self-&gt;overdraft_account-&gt;withdraw($overdraft_amount);<br>&nbsp; &nbsp; &nbsp; &nbsp; $self-&gt;deposit($overdraft_amount);<br>&nbsp; &nbsp; }<br>};</tt></p></div> </blockquote><p> The <code>has</code> keywords create instance attributes, with type constraints (<code>isa =&gt; 'Int'</code> etc), read/write accessors (<code>is =&gt; 'rw'</code>) and "before" method wrappers allow for AOP style method "advice" which runs before the superclass method is called. But there is just as much that you don't see, such as; automatic inheritance from <a href="">Moose::Object</a> (where you inherit <code>new</code> and the Perl 6 style BUILD/BUILDALL constructor semantics), and full class introspection and reflection capabilities through the <code>meta</code> method. </p><p> Now, there are also a number of things which <a href="">Moose</a> is <b>not</b>. It is not another Inside-out object builder, it currently only supports blessed HASH based objects (surely the most common style), and possible future plans include adding support for blessed ARRAYs and such. But to be honest, one of the key ideas of <a href="">Moose</a> is to take away the <i>need</i> to worry about those types of things, and have everything <i>Just Work</i>, so that writing OO Perl code can be just as enjoyable as writing other Perl code. </p><p> Anyway, enough evangalism for now, please give <a href="">Moose</a> a try, I welcome any and all feedback (positive <b>and</b> negative), and feel free to come see us on #moose over at </p><p> -- Stevan</p> Stevan 2006-03-23T14:17:20+00:00 journal Metaclasses in Perl 5 <p> I have just released <a href="">Class::MOP-0.01</a> to CPAN (appearing soon on a CPAN mirror near you). It attempts to create a complete meta-object protocol for Perl 5 and bring support for metaclass programming to Perl 5. Or course, this being a 0.01 release, there is still much that can be done and many improvements that can be made, but I feel it is a good start. </p><p> This is largely inspired by my work on the Perl 6 metamodel and my recent studies of CLOS, and as a side benefit, it is useful for my $work as well<nobr> <wbr></nobr>:) </p><p> Any questions, comments or criticisms are welcome. </p><p> - Stevan</p> Stevan 2006-02-02T22:08:04+00:00 journal Perl6::ObjectSpace in Haskell <p> <a href="">Audrey</a> recently began the process of porting the <a href="">Perl6::ObjectSpace</a> to Haskell to eventually become the new Pugs runcore. After creating the <a href="">core (native) types in Haskell</a>, <a href="">audrey</a> promptly implemented a <a href="">mini-language</a> using these types. It looks (of course) a lot like a very limited subset of Perl 6, but since we lambdacamels like our purity, it is side-effect free. Here is an example of a factorial function which uses a <a href="">fixed point combinator</a> to get around the fact we cannot call functions by name.</p><blockquote><div><p> <tt>(-&gt; $n {<br>&nbsp; &nbsp; (-&gt; &amp;fact {<br>&nbsp; &nbsp; &nbsp; &nbsp; &amp;fact.(&amp;fact, $n)<br>&nbsp; &nbsp; }).(-&gt; &amp;f, $x {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $x.eq(0).cond(<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; { 1 },<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -&gt; { $x.multiply( &amp;f.(&amp;f, $x.subtract(1)) ) }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )<br>&nbsp; &nbsp; &nbsp; &nbsp;});<br>}).(10);</tt></p></div> </blockquote><p> The real purpose of this mini-language is to script the core runtime types to bootstrap the Perl 6 MetaModel. Today I commited the skeleton of the <a href="">MetaModel Bootstrap PIL</a> to Pugs. These are the first steps towards Pugs 6.28.0 and a fully realized Perl 6 object model in pugs. </p><p> - Stevan </p> Stevan 2005-12-15T01:24:45+00:00 journal DBIx::Class meets Class::C3 meets GraphViz <p> mst has been busy converting his shiney new ORM masterpeice <a href="">DBIx::Class</a> to use <a href="">Class::C3</a> instead of <a href="">NEXT</a>, and I have been helping out by dutifully applying all his patches to <a href="">Class::C3</a>. After some discussion yesterday about a weird bug, I decided that <a href="">Class::C3</a> really needed a visualization tool to help in analyzing deep mulitple inheritance hierarchies. I thought about it for a while, then sat down and whipped <a href="">this</a> out in about 20 minutes to output in DOT (one of the Graphviz mini-languages). It is still rather primative, but it pretty much does what I wanted it to. Here are some examples I did to show mst:</p><blockquote><div><p> <i> NOTE: The green lines show the @ISA relationships, and the red lines show the C3 method dispatch order. </i></p></div> </blockquote><ul> <li> <a href="">DBIx::Class::Core</a> </li><li> <a href="">DBIx::Class::CDBICompat</a> </li></ul> Stevan 2005-11-24T16:35:56+00:00 journal Autogenerated Perl6::MetaModel diagrams <p> I have been pondering createing some kind of class-viewer of sorts for the Perl6::MetaModel prototype. For two reasons; first, it would be highly useful for my own debugging, and secondly because it would be really cool<nobr> <wbr></nobr>:) </p><p> Today I sat down and finally did <a href="">it</a>. It is currently an ugly kludge to print out GraphViz dot files, but it does the job. I have chosen some of the more interesting outputs from some of the test files, and uploaded them <a href="">here</a>. </p><p> -- Stevan </p> Stevan 2005-10-19T21:53:45+00:00 journal Method Dispatch with Eigenclasses <p> This past week I have been busy with $work, however, I have been thinking quite heavily about how Eigenclasses can fit into the <a href="">Perl6-MetaModel</a>. Currently the implementation has limited support (actually it's pretty much broken support) for eigenclasses, and the past 3-4 attempts I have made to clean things up have resulted in a lot of <code>svk revert</code> commands. So finally I decided to sit down and draw things out. </p><p> The <a href="">first diagram</a> I made was your basic vanilla method dispatch. It shows both instance method dispatch as well as class method dispatch. This diagram illustrates the key issue with class methods, in that they do not fit cleanly into a meta-model. This can also be seen when you look at the method signature of a class method:</p><blockquote><div><p> <tt>class Bar {<br>&nbsp; &nbsp; method foo (Class $c:) {<nobr> <wbr></nobr>... }<br>}</tt></p></div> </blockquote><p>In any other method, the invocant (shown as <code>$c</code> here) would be of the same type as the class in which it is defined. But here the signature of the class method shows that the invocant should be of type <code>Class</code>, however that is not where the method is defined. </p><p> This issue is even more apparent in CLOS, where methods are represented with generic functions (which are a lot like multi-methods). In CLOS the first parameter of a method has what is called a specializer (which is basically the "type" of that expected parameter) that parameter is used by the CLOS system to associate a method with a particular class. Here is a short example of a generic function <code>foo</code> which is associated with the class <code>Bar</code>.</p><blockquote><div><p> <tt>(defgeneric foo (self))<br>(defmethod foo ((Bar self) (<nobr> <wbr></nobr>... ))</tt></p></div> </blockquote><p>The first line defines the generic function <code>foo</code> with the single parameter <code>self</code>. The second line defines a method of that generic function, specialized for the <code>Bar</code> class. Now when we create a class-method called <code>baz</code>, it will look like this:</p><blockquote><div><p> <tt>(defmethod baz ((standard-class c)) (...))</tt></p></div> </blockquote><p>By making the type of our parameter <code>standard-class</code> CLOS will associate this method with all instances of <code>standard-class</code>, which is <i>every</i> class in the system. </p><p> So you can see, it is impossible to specialize a class method to one particular class using these meta-models. </p><p> <i>Eigenclasses to the rescue!!</i> </p><p> My <a href="">second diagram</a> shows how class-methods can be implemented using ruby-style eigenclasses (or singleton-methods as they are also called). The eigenclass hierarchy (show here with the <code>e-</code> prefix) essentially mirrors the normal class hierarchy, but instead of storing instance methods, they store class methods. (This parallel hierarchy actually reminds me of the <a href="">Smalltalk metaclass</a> hierarchy in some ways, which is why I think it "smells" right to me). </p><p> Using the eigenclasses results in a very normalized method dispatch mechanism where instance method and class method dispatch are exactly the same. What else can I say about that but ruby++. </p><p> The only point at which things get messy is when we introduce an intentional subclass of Class. Like this:</p><blockquote><div><p> <tt>class Baz is Class {<nobr> <wbr></nobr>... }<br>class Foo meta Baz {<nobr> <wbr></nobr>... }<br>class Bar is Foo {<nobr> <wbr></nobr>... }</tt></p></div> </blockquote><p>The result is that e-Foo inherits from Baz, and since e-Bar inherits from e-Foo, e-Bar gets methods from Baz, which is probably now what was intended. I didn't even bother to draw this out since it gets really really messy. However, it occurred to me that using Role composition to inject class methods, it might be possible to accomplish most anything you would want to accomplish through subclassing Class anyway. However, this needs more contemplation, and so I will save it for another day. </p><p> - Stevan </p> Stevan 2005-10-09T02:45:21+00:00 journal Perl6::MetaModel 2.0 <p> My $work has been keeping me busy lately, and so my Perl 6/pugs work has been suffering. However, due to a $work induced eratic sleep schedule I found myself up very early this morning with nothing to do, so I finished/fixed the bootstrapping phase of the <a href="">Perl6-MetaModel 2.0</a>. </p><p> This new version attempts to build upon the things that worked in 1.0, while reducing the dependence on Perl 5 magic in the core model. It also eliminates the "meta" layer (at least in name) in favor of a more direct "Class" and "Object" layers. The result is a much simplier implementation which I hope can be ported to the <a href="">other</a> <a href="">runtimes</a> even easier than 1.0. I have also adopted <a href="">autrijus's</a> gnostic naming conventions for the <a href="">core files</a>. </p><p> - Stevan </p> Stevan 2005-08-29T12:39:03+00:00 journal Perl 6, Class::Std and the C3 method dispatch <p> So all this work on the Perl 6 metamodel has made me really, <i>really</i>, <b> <i>really</i> </b> want some of the Perl 6 OO features in Perl 5. In particular things like opaque instances, inherited attributes and a sane method resolution order under multiple inheritance (C3). </p><p> Autrijus recently <a href="">recomended</a> I give <a href="">Class::Std</a> a try, since it provides many Perl6-ish features. And this morning, I did just that, and I was quite happy to find not only opaque instances (using inside-out objects), but inherited attributes as well as inherited destructors and multiply dispatching methods. </p><p> Now, being someone who actually likes to read code, I decided to go source-diving. And this being a Damian module, I was prepared for plenty of the insane code which Damian is known for. But much to my suprise, I found the code quite readable and very straightfoward. </p><p> I was happy to see that the BUILD and DESTROY orders are not the standard Perl 5 depth-first/left-to-right orderings. But instead use a custom ordering which seems to produce a fairly sane ordering. And it also seemed that the multple dispatch mechanisms and AUTOMETH feature used the same order as well. </p><p> However, I did not like the fact that these orderings stood in contrast with the way methods were actually dispatched. The standard Perl 5 method dispatch was still used for standard method dispatch. So after some head scratching and a little experimentation, I came up with <a href="">Class::C3</a>. </p><p> While still highly experimental, <a href="">Class::C3</a> is quickly evolving, and version 0.02 should available at a CPAN mirror near you very soon. It basically pre-caches all the method dispatch to insure that the C3 method resolution ordering will be used. Version 0.02 also supports re-initializing the dispatch cache as well for those crazy people who like to mess with @ISA during runtime. I have yet to actually test it with <a href="">Class::Std</a> yet, but I suspect the two modules will get along well. </p><p> - Stevan </p> Stevan 2005-08-08T05:33:39+00:00 journal 10,000 ft View of Perl 6 MetaModel <p> Earlier today on #perl6, kolibrie asked me about documentation for the metamodel. Sadly, none actually existed, and with all the bootstapping code in the Perl 5 version, just "reading the source" can be confusing. So while I was waiting for some large data files for $work to upload, I sketched out a quick 10,000 ft view of the metamodel. </p><blockquote><div><p><tt> <tt>&nbsp; &nbsp; i(Foo)&nbsp; &nbsp; &nbsp;- instance of Foo<br>&nbsp; &nbsp; Foo&nbsp; &nbsp; &nbsp; &nbsp; - the user-level Foo class<br>&nbsp; &nbsp; class(Foo) - the instance of Perl6::Class named "Foo"<br>&nbsp; &nbsp; meta(Foo)&nbsp; - the instance of Perl6::MetaClass which describes Foo<br> <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | i(Foo)&nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | class&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|------+<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | instance_data |&nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+&nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp;NOTE:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ___&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; &nbsp;At the Foo level is where<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(&nbsp; &nbsp;)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp;the interpreter will likely<br>&nbsp; &nbsp; &nbsp; +-------------( Foo )------------+&nbsp; &nbsp;perform some 'magic' to<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (___)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;connect the user and meta<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; levels.<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;user level&gt;<br>&nbsp;<nobr> <wbr></nobr>....|.........................................................<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;meta level&gt;<br>&nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+---------------+<br>&nbsp; &nbsp; &nbsp; +--------&gt;| class(Foo)&nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+<br>&nbsp; &nbsp; &nbsp; +---------| meta&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+---------------+<br>&nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+---------------+<br>&nbsp; &nbsp; &nbsp; +--------&gt;| meta(Foo)&nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | name&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | version&nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | authority&nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | %methods&nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | %attributes&nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +---------------+</tt></tt></p></div> </blockquote><p> Any comments, questions, suggestions or even disparaging remarks are welcome. A more complete document is in the pugs tree <a href="">here</a>. </p><p> - Stevan </p> Stevan 2005-08-06T06:04:26+00:00 journal My little Perl6::MetaModel is all grown up <p> So after months of mind-bendingly abstract work, my <a href="">Perl 6 MetaModel</a> work is now being integrated into both the <a href="">Pugs</a> core, and the <a href="">PILJS</a> Perl 6 runtime. </p><p> I feel like a proud father, sending my child off to school to play with the other language elements. I hope they can all play nice together<nobr> <wbr></nobr>:) </p><p> It is also nice to have some company here in meta-land. It is moments like this on #perl6, which bring me great joy.</p><blockquote><div><p> <tt> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* autrijus sees the entire metacircular light!<br> &nbsp;&nbsp;&lt;stevan&gt;<nobr> <wbr></nobr>:)<br> &lt;autrijus&gt; beautiful<nobr> <wbr></nobr>:)<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* stevan does the meta-dance<br> </tt></p></div> </blockquote><p> Of course now the real work begins, this is really just the first few steps in the brave new world of Perl 6 OO. But I for one am very excited about the road ahead. </p><p> - Stevan </p> Stevan 2005-08-04T21:07:30+00:00 perl6