mpeters's Friends' Journals http://use.perl.org/~mpeters/journal/friends/ mpeters's Friends' use Perl Journals 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:16:47+00:00 pudge pudge@perl.org Technology hourly 1 1970-01-01T00:00+00:00 mpeters's Friends' Journals http://use.perl.org/images/topics/useperl.gif http://use.perl.org/~mpeters/journal/friends/ Finally, some Test::Builder2 examples! http://use.perl.org/~schwern/journal/40528?from=rss <p>For my PDX.pm presentation tonight on <a href="http://github.com/schwern/test-more/tree/Test-Builder2">Test::Builder2</a> I threw together some quick examples of some of its killer features, in particular demonstrating changing how Test::Builder2 behaves using method modifiers and applying object roles.</p><p>First, demonstrating end-of-assert actions, there's <a href="http://github.com/schwern/test-more/blob/Test-Builder2/examples/TB2/lib/TB2/DieOnFail.pm">die on fail</a> but even cooler is <a href="http://github.com/schwern/test-more/blob/Test-Builder2/examples/TB2/lib/TB2/DebugOnFail.pm">DEBUG on fail</a>! That's right, run your test in the debugger and have it automatically set a breakpoint on a failure. How cool is that?</p><p>I'm sure somebody with better debugger foo than I can make it even cooler and stop at the top of the assert stack rather than inside DebugOnFail.</p><p>The second is reimplementing <a href="http://search.cpan.org/perldoc?Test::NoWarnings">Test::NoWarnings</a> safely. <a href="http://github.com/schwern/test-more/blob/Test-Builder2/examples/TB2/lib/TB2/NoWarnings.pm">TB2::NoWarnings</a> demonstrates hooking into the start and end of the test as well as safely altering the number of tests planned by trapping the call to set_plan.</p><p>You can safely use them all together, though its a crap shoot if DebugOnFail or DieOnFail will trigger first.</p><p>While roles and method modifiers are relatively new to the Perl community, using them in lieu of designing my own event system for TB2 has two great advantages. First, I didn't have to design and debug my own event system.<nobr> <wbr></nobr>:) Second, rather than having to learn the quirks of a one-off system, you learn the quirks of Mo[uo]se and then can apply that knowledge all over the place.</p><p>There's <a href="http://github.com/schwern/test-more/issues/labels/Test-Builder2">a pile of stuff to be done in TB2</a>, a lot of them are fairly small and self contained. Have a look. Patches welcome.</p> schwern 2010-09-09T08:33:42+00:00 journal Test::Builder2 at 10k Feet http://use.perl.org/~schwern/journal/40527?from=rss <p>Here's a diagram of the "flow" of assert results through Test::Builder version 1.</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.-------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| foo.t |<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;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp;.-------------.&nbsp; &nbsp; &nbsp;|&nbsp; &nbsp; &nbsp;.----------------.<br>&nbsp; &nbsp; &nbsp;| Test::More&nbsp; |&lt;---------&gt;| Test::Whatever |<br>&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;|<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;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '----&gt;| Test::Builder |&lt;----'<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '---------------'<br>&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; v<br>&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;| TAP |<br>&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; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.---------------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Test::Harness |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '---------------'</tt></p></div> </blockquote><p>You write foo.t using Test::More and Test::Whatever. These both<br>use the same Test::Builder object. It spits out TAP which<br>Test::Harness converts into something human readable.</p><p>The big problem there is Test::Builder is monolithic. There's no<br>further breakdown of responsibilities. It only spits out TAP, and<br>only one version of TAP.</p><p>Here's what Test::Builder2 looks like:</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.-------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.----------------| foo.t |-------------------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &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; &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.------------.&nbsp; &nbsp; &nbsp;.----------------.&nbsp; &nbsp; &nbsp;.------------------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Test::More |&nbsp; &nbsp; &nbsp;| Test::Whatever |&nbsp; &nbsp; &nbsp;| Test::NotUpdated |<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; &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; v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v<br>&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;'----------&gt;| Test::Builder2 |&lt;------| Test::Builder |<br>&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; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.--------------.&nbsp; &nbsp;<nobr> <wbr></nobr>.-------------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| TB2::History |&lt;---| TB2::Result |<br>&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; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp;<nobr> <wbr></nobr>.--------------------------.&nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; &nbsp; &nbsp;.---------------------.<br>&nbsp; &nbsp; | TB2::Formatter::TAP::v13 |&lt;-----'------&gt;| TB2::Formatter::GUI |<br>&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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp;<nobr> <wbr></nobr>.-------------------------------.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; | TB2::Formatter::Streamer::TAP |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v&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; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| TAP |&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; &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; v<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.---------------.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.-----------------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Test::Harness |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| Pretty Pictures |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '---------------'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'-----------------'</tt></p></div> </blockquote><p>It starts out the same, foo.t uses a bunch of test modules<br>including Test::More and Test::Whatever using the same Test::Builder2<br>object, but it also uses Test::NotUpdated which is still using<br>Test::Builder. That's ok because Test::Builder has been rewritten in<br>terms of Test::Builder2 (more on that below).</p><p>Test::Builder2, rather than being a monolith, produces a<br>Test::Builder2::Result object for each assert run. This gets stored<br>in a Test::Builder2::History object for possible later use. It also<br>gets handed to a Test::Builder2::Formatter object, the default is<br>Test::Builder2::TAP::v13 which produces TAP version 13. This is fed<br>to a Streamer that prints it to STDOUT and STDERR which is read by<br>Test::Harness and made human readable.</p><p>Because Test::Builder2 is not monolithic, you can swap out parts. For<br>example, instead of outputting TAP it could instead hand results to a<br>formatter that produced a simple GUI representation, maybe a green<br>bar, or something that hooks into a larger GUI. Or maybe one that<br>produces JUnit XML.</p><p>Here's how Test::Builder and Test::Builder2 Relate.</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.-----.&nbsp; &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; | TB2 |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| TB1 |<br>&nbsp; &nbsp; &nbsp; &nbsp; '-----'&nbsp; &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; &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; &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; &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v<br>&nbsp; &nbsp;<nobr> <wbr></nobr>.-------------.&nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.--------------.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.-------------.<br>&nbsp; &nbsp; | TB2::Result |-------&gt;| TB2::History |&lt;--------| TB2::Result |<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; &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; &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.----------------.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'-------------&gt;| TB2::Formatter |&lt;--------------'<br>&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;|<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;v<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>.--------.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | Output |<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '--------'</tt></p></div> </blockquote><p>Test::Builder and Test::Builder2 coordinate their actions by sharing<br>the same History and Formatter objects. If you call TB1-&gt;ok() it<br>produces a Result object which it hands to the History singleton and<br>the Formatter singleton. If you call TB2-&gt;ok() it produces a Result<br>object which it hands to the same History and Formatter objects.</p><p>This allows most of the Test::Builder code to remain the same while<br>still coordinating with Test::Builder2. It also allows radically<br>different builders to be made without Test::Builder2 dictating how<br>they're to work.</p><p>The downside is that roles applied to Test::Builder2 will not effect<br>Test::Builder. Because of this, Test::Builder may become more closely<br>coupled with Test::Builder2 in the future.</p><p>Diagrams by <a href="http://search.cpan.org/dist/App-Asciio">App::Asciio</a>.</p> schwern 2010-09-09T08:15:22+00:00 journal DBD::SQLite 1.31 releasing next week and may break your code http://use.perl.org/~Alias/journal/40526?from=rss <p>After 6 or 7 months (mainly waiting around for the next "recommended upgrade instruction" from the SQLite project) the latest DBD::SQLite release should occur next week.</p><p>You can get the 1.30_06 release candidate from the CPAN, or from the following URL if your mirror hasn't synced yet.</p><p><a href="http://svn.ali.as/cpan/releases/DBD-SQLite-1.30_06.tar.gz">http://svn.ali.as/cpan/releases/DBD-SQLite-1.30_06.tar.gz</a></p><p>Apart from the normal batch of SQLite upgrades (from 3.6.22 to 3.7.2), bug fixes, and minor enhancements, this release has two changes that may break your code.</p><p>These changes have been in the dev releases for some time, but you may want to take the opportunity to test more intensively if you use either of the following features.</p><p>1. BLOB columns with UTF8 content</p><blockquote><div><p> <tt>- Resolved #54271: Inserting a string with utf-8 flag on<br>&nbsp; corrupts BLOB data; now BLOB data is always stored as bytes<br> &nbsp; (without the utf-8 flag) even if it has the flag set (ISHIGAKI)</tt></p></div> </blockquote><p>2. FTS3 queries</p><blockquote><div><p> <tt>- Added support for FTS3 tokenizers written in Perl. Added tests<br>&nbsp; and documentation on how to use FTS3. Changed compilation flag<br>&nbsp; to use the recommanded -DSQLITE_ENABLE_FTS3_PARENTHESIS<br>&nbsp; *** MAY POSSIBLY BREAK OLD APPLICATIONS THAT ALREADY USED FTS3 ***<br>&nbsp; (DAMI)</tt></p></div> </blockquote><p>If you are currently using FTS3, please see <a href="http://search.cpan.org/perldoc?DBD::SQLite::FTS3Transitional">DBD::SQLite::FTS3Transitional</a> which contains a helper function for automatically upgrading old FTS3 queries to the new syntax.</p> Alias 2010-09-09T02:11:54+00:00 journal The Pugs repository is dead; long live Mu! http://use.perl.org/~masak/journal/40524?from=rss <p>This weekend marks the end of a quite astonishing era. The Pugs repo, that hosted all the <a href="http://use.perl.org/~masak/journal/40451">amazing Perl 6 activity</a>, is no more. At its height, this repository had 242 committers! I just checked.</p><p>The Pugs repository has functioned as a common writing area for Perl 6-related things. First <a href="http://github.com/audreyt/pugs">Pugs</a>; then a lot of external <a href="http://github.com/perl6/perl6-examples">modules and scripts</a> written in Perl 6; what would eventually morph into <a href="http://github.com/perl6/roast">the Perl 6 test suite</a>; even the <a href="http://github.com/perl6/specs">Perl 6 specification</a> and the <a href="http://github.com/perl6/std">standard grammar</a>. Commit bits (write access credentials) were handed out liberally, and newcomers were encouraged to help improve things they found amiss. The degree to which this system worked without a hitch has been quite astonishing. There have been no edit wars, no vandalism, no banning. Just the continuing flow of commits. Trust the anarchy.</p><p>So why are we killing off the Pugs repository? Well, technologies come and go; not so much because they worsen by each year, but because our expectations rise in a sort of software inflation. The SVN repository became too high-maintenance, and a transition to git was the natural next step. The Pugs repository has been split up into the git repositories linked to in the previous paragraph. Those bits that don't belong in any of the standard bins remain in the <a href="http://github.com/perl6/mu">Mu repository</a>. (Its name is a reference to the most-general object type in Perl 6, what in other languages is commonly known as 'Object'.)</p><p>I for one salute our new git-based overlords! May the commits keep flowing even under this new system. Also, moritz++ for carrying out the move.</p> masak 2010-09-06T06:30:29+00:00 perl6 Should Module::Install move to explicit plugin declaration? http://use.perl.org/~Alias/journal/40523?from=rss <p>Module::Install has been through a long period of gradual stability over the last year, without any really dramatic improvements to the grammar or APIs.</p><p>With the more urgent "it doesn't work with blah" stuff mostly solved now, one of the big remaining issues is around error clarity and excessive magic.</p><p>For example, some random author that is trying to checkout a Catalyst project needs:</p><p>1. To have Module::Install installed.<br>2. To have Module::Install::Catalyst installed.</p><p>In the case of the former, you get the semi-cryptic but at least standard "Can't find inc/Module/Install.pm in @INC" message, so the error is resolvable.</p><p>But in the latter case, you're likely to get something like "Unknown command 'catalyst_ignore'", with no real obvious resolution mechanism.</p><p>I think this idea of automatic plugin discovery is starting to hit it's limits in terms of clarity.</p><p>And so I'd like to do something counter to my natural instincts here, and make M:I more verbose.</p><p>I'm thinking of something like the following for explicitly declaring the use of a non-core Module::Install extension.</p><blockquote><div><p> <tt>use inc::Module::Install qw{ Catalyst XSUtil };</tt></p></div> </blockquote><p>This would both allow M:I to error with a much more meaningful error when you don't have a plugin, and also prevent the loading of unused plugins which should prevent accidental plugin collisions (some of which I've seen occurring in the CPAN Testers machines).</p><p>Thoughts?</p> Alias 2010-09-06T02:26:06+00:00 journal Yapsi 2010.09 Released! http://use.perl.org/~masak/journal/40519?from=rss <p>It is with a peevish exultation of spirit that I announce on behalf of the Yapsi development team the September 2010 release of Yapsi -- soon to be a major motion picture -- a Perl 6 compiler written in Perl 6.</p><p>You can download it <a href="http://github.com/downloads/masak/yapsi/yapsi-2010.09.tar.gz">here</a> (or, if you happen to be on an <a href="http://en.wikipedia.org/wiki/IP_over_Avian_Carriers">avian-carrier-based</a> network, you can "pidgeon" it <a href="http://github.com/downloads/masak/yapsi/yapsi-2010.09.tar.gz">here</a>).</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. This release of Yapsi has been confirmed to work on both Rakudo Star 2010.08 and Rakudo Star 2010.07.</p><p>Yapsi is an "official and complete" implementation of Perl 6. Yapsi's official status has been publicly confirmed by Patrick Michaud, the Rakudo pumking. The claim about Yapsi being complete... well, it might just be what PR people sometimes refer to as "a slight exaggeration". On the bright side, it's becoming less so with each new release.</p><p>This month's release brings you <code>unless</code> and <code>until</code>, as well as <code>our</code>-scoped variables:</p><p> <code> $ yapsi -e 'my $a = 0; unless $a { say 42 }'<br> 42 </code> </p><p> <code> $ yapsi -e 'my $a = 0; until $a { say ++$a }' 1 </code> </p><p> <code> $ yapsi -e 'our $a = 42; { my $a = 5; { say our $a } }' 42 </code> </p><p>For a complete list of changes, see <a href="http://github.com/masak/yapsi/tree/master/doc/ChangeLog">doc/ChangeLog</a>.</p><p>Quite a lot of features are within reach of people who are interested in hacking on Yapsi. See the <a href="http://github.com/masak/yapsi/tree/master/doc/LOLHALP">doc/LOLHALP</a> file for a list of 'em. In fact, that's how isBEKaml++ implemented 'unless' this month. (After which he exclaimed "that was easy!" and tackled 'until'.) If you're wondering whether you're qualified to help with the Yapsi project, that probably means you are.</p><p>Yapsi consists of a compiler and a runtime. The compiler generates instruction code which the runtime then interprets. In Yapsi, that instruction code (unfortunately) is called SIC[!]. Until further notice, SIC as a format changes with each monthly release for various, mostly good reasons. However, if you write a downstream tool that makes assumptions about the SIC format, someone might change it just out of spite. SIC is explicitly not compatible with later, earlier, or present versions of itself.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li> A time-traveling debugger (tardis), which hooks into the runtime.</li><li> A coverage tool (lid), which will also hook into the runtime.</li><li> A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes.</p><p>Have the appropriate amount of fun!</p> masak 2010-09-01T22:31:48+00:00 perl6 Rakudo Star 2010.08 released http://use.perl.org/~pmichaud/journal/40518?from=rss <p>[This announcement was made last week on rakudo.org -- I'm reposting to use.perl.org so it will show up in the various Perl aggregators. --Pm]</p><p>On behalf of the Rakudo and Perl 6 development teams, I'm happy to announce the August 2010 release of "Rakudo Star", a useful and usable distribution of Perl 6. The tarball for the August 2010 release is available from <a href="http://github.com/rakudo/star/downloads">http://github.com/rakudo/star/downloads</a>.</p><p>Rakudo Star is aimed at "early adopters" of Perl 6. We know that it still has some bugs, it is far slower than it ought to be, and there are some advanced pieces of the Perl 6 language specification that aren't implemented yet. But Rakudo Perl 6 in its current form is also proving to be viable (and fun) for developing applications and exploring a great new language. These "Star" releases are intended to make Perl 6 more widely available to programmers, grow the Perl 6 codebase, and gain additional end-user feedback about the Perl 6 language and Rakudo's implementation of it.</p><p>In the Perl 6 world, we make a distinction between the language ("Perl 6") and specific implementations of the language such as "Rakudo Perl". The August 2010 Star release includes release #32 of the Rakudo Perl 6 compiler [1], version 2.7.0 of the Parrot Virtual Machine [2], and various modules, documentation, and other resources collected from the Perl 6 community.</p><p>This release of Rakudo Star adds the following features over the previous Star release:<br>* Nil is now undefined<br>* Many regex modifiers are now recognized on the outside of regexes<br>* Mathematic and range operations are now faster (they're still slow, but they're significantly faster than they were in the previous release)<br>* Initial implementations of<nobr> <wbr></nobr>.pack and<nobr> <wbr></nobr>.unpack<br>* MAIN can parse short arguments<br>* Removed a significant memory leak for loops and other repeated blocks</p><p>This release (temporarily?) omits the Config::INI module that was included in the 2010.07 release, as it no longer builds with the shipped version of Rakudo. We hope to see Config::INI return soon.</p><p>There are some key features of Perl 6 that Rakudo Star does not yet handle appropriately, although they will appear in upcoming releases. Thus, we do not consider Rakudo Star to be a "Perl 6.0.0" or "1.0" release. Some of the not-quite-there features include:<br>* nested package definitions<br>* binary objects, native types, pack and unpack<br>* typed arrays<br>* macros<br>* state variables<br>* threads and concurrency<br>* Unicode strings at levels other than codepoints<br>* pre and post constraints, and some other phasers<br>* interactive readline that understands Unicode<br>* backslash escapes in regex character classes<br>* non-blocking I/O<br>* most of Synopsis 9<br>* perl6doc or pod manipulation tools</p><p>In many places we've tried to make Rakudo smart enough to inform the programmer that a given feature isn't implemented, but there are many that we've missed. Bug reports about missing and broken features are welcomed.</p><p>See <a href="http://perl6.org/">http://perl6.org/</a> for links to much more information about Perl 6, including documentation, example code, tutorials, reference materials, specification documents, and other supporting resources. An updated draft of a Perl 6 book is available as in the release tarball.</p><p>The development team thanks all of the contributors and sponsors for making Rakudo Star possible. If you would like to contribute, see <a href="http://rakudo.org/how-to-help">http://rakudo.org/how-to-help</a>, ask on the perl6-compiler@perl.org mailing list, or join us on IRC channel #perl6 on freenode.</p><p>Rakudo Star releases are created on a monthly cycle or as needed in response to important bug fixes or improvements. The next planned release of Rakudo Star will be on September 28, 2010.</p><p>[1] <a href="http://github.com/rakudo/rakudo">http://github.com/rakudo/rakudo</a><br>[2] <a href="http://parrot.org/">http://parrot.org/</a></p> pmichaud 2010-09-01T12:36:56+00:00 perl6 A month of Test::Builder2 http://use.perl.org/~schwern/journal/40517?from=rss <p>I've had <a href="http://www.perlfoundation.org/test_builder_2">a grant open for Test::Builder2</a> for, oh god over two years now. Since I started it, Perl 6 has had a release! I think its the second oldest running dev grant.</p><p>I've cleared the decks of other responsibilities and can dedicate September to, if not finishing, then at least releasing something people can poke at. First alpha release was supposed to be "two weeks after the start" ha ha ha! oh god. The design has evolved and simplified greatly in the intervening two years, but its time to get something the hell out the door. At least a <a href="http://github.com/schwern/test-more/tree/Test-Builder2">Test::Builder2</a> Star if you will.</p><p>There's critical components missing. There's no diagnostics, YAML or otherwise. The issues with nested asserts are still congealing. Plans are not enforced. Result objects are in the middle of being remodeled... again. But Test::Builder is using what parts of Test::Builder2 are usable. Multiple output formats and streams work. Asserts can be nested in the common, simple cases without having to fiddle with $Level. And you can hook into various events.</p><p>Step one is I'm going to seal up what's there, write docs where they're missing, and release something.</p><p>A release before October or the grant dies.</p> schwern 2010-08-28T04:08:39+00:00 journal Idiomatic Perl 6 http://use.perl.org/~masak/journal/40516?from=rss <p>So, I wrote a program to generate <a href="http://en.wikipedia.org/wiki/Pascal">Pascal's triangle</a>. The first ten rows of the triangle, at least. It only used simple features of Perl 6, such as scalars, nested arrays, and <code>for</code> loops.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current;<br> &nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[0];<br> &nbsp;&nbsp;&nbsp;&nbsp;for 0<nobr> <wbr></nobr>.. @last - 2 {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[$_] + @last[$_ + 1];<br> &nbsp;&nbsp;&nbsp;&nbsp;}<br> &nbsp;&nbsp;&nbsp;&nbsp;push @current, @last[ * - 1 ];<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>In fact, save for simple mechanically substitutable differences, it could have been a Perl 5 script. In fact, with a bit of manual array allocation, it could have been a C script. That's OK; there's a tolerance in the Perl community of writing code that looks like it was thunk in some other language.</p><p>But I've heard that Perl 6 is great at doing things with operators. For example, the <code>Z</code> operator, which interleaves two lists, seems to be able to help me write my <code>push</code> statements more succinctly:</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current;<br> &nbsp;&nbsp;&nbsp;&nbsp;<b>for (0, @last) Z (@last, 0) -&gt; $left, $right {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push @current, $left + $right;<br> &nbsp;&nbsp;&nbsp;&nbsp;}</b> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>The parentheses before and after the <code>infix:&lt;Z&gt;</code> aren't necessary, because the <code>Z</code> operator has looser precedence than comma. They're just shown here to make your eyes accustomed to reading this construct.</p><p>In fact, now that only the addition is performed in the inner loop, I might as well use the <code>Z+</code> operator, which does this for me.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current <b>= 0, @last Z+ @last, 0;</b> <br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, [@current];<br> }<br> <br> say @pascal.perl; </code> </p><p>Now as the remaining loop shrinks to a size I can take in all at once, I see a bit more clearly what I'm doing: I'm building each new list from the previous one. I could feed the previous list into a named function to get the current one:</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <b> <br> sub next-list(@p) {<br> &nbsp;&nbsp;&nbsp;&nbsp;[0, @p Z+ @p, 0]<br> }<br> </b> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;my @current = <b>next-list(@last)</b>;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, @current;<br> }<br> <br> say @pascal.perl; </code> </p><p>Or I could just feed it into a in-place anonymous sub.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, <b>(sub (@p) { [0, @p Z+ @p, 0] }).(@last)</b>;<br> }<br> <br> say @pascal.perl; </code> </p><p>But why even a sub? Perl 6 has a lighter construct, namely a "pointy block" (also known as a "closure" or a "lambda"). It doesn't participate in the call stack, and it's slightly easier to write.</p><p> <code> my $ELEMENTS = 10;<br> my @pascal = [1];<br> <br> for 1<nobr> <wbr></nobr>.. $ELEMENTS - 1 {<br> &nbsp;&nbsp;&nbsp;&nbsp;my @last = @pascal[ * - 1 ].list;<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;push @pascal, (<b>-&gt; @p</b> { [0, @p Z+ @p, 0] }).(@last);<br> }<br> <br> say @pascal.perl; </code> </p><p>Let's look at what the code does. Seed with one element. Calculate the next element based on the previous one. Stop at some point.</p><p>But that's exactly what the series operator does. The one that's written with three dots. We have a starting value, a way to get from one value to the next (our code block above), and a stopping value.</p><p>Well actually, we don't have the stopping value. But that's OK, since the series operator is <em>lazy</em>. So if we only request the first 10 values, it won't loop forever giving us the rest of the list.</p><p> <code> <b>my @pascal<nobr> <wbr></nobr>:= do [1], -&gt; @p { [0, @p Z+ @p, 0] }<nobr> <wbr></nobr>... *;</b> <br> <br> say <b>@pascal[^10]</b>.perl; </code> </p><p>(The extra <code>do</code> required because of a <a href="http://rt.perl.org/rt3/Ticket/Display.html?id=77462">shortcoming in Rakudo</a>.)</p><p>Now. Something very much like this code was posted first <a href="http://rosettacode.org/wiki/Pascal's_triangle#Perl_6">on Rosetta code</a> and then <a href="http://perlgeek.de/blog-en/perl-6/pascal-triangle.html">on Moritz' blog</a>. (TimToady used a sub, but said later that he'd have preferred binding.)</p><p>A couple of Perl 5 people's reactions were &#8212; somewhat uncharacteristically &#8212; of a negative flavour, similar to how people <a href="http://use.perl.org/~masak/journal/40339">seem to react</a> to the periodic table of operators:</p><p> <code> <a href="http://twitter.com/shadowcat_mst/status/22112066276">@shadowcat_mst</a>: an excellent example of why I consider camelia perl to be a language research project more than a production language </code> </p><p> <code> <a href="http://twitter.com/pedromelo/status/22110965152">@pedromelo</a>: I'm seriously considering this post as an example of what I don't want Perl6 to become... </code> </p><p>I think these reactions are mainly feature shock. Higher-order operators, pointy blocks, and the series operator... they're all good, well-established features, which find daily use in Perl 6 programs. Maybe using them all together like that flung some people off the deep end. Never mind that the resulting script is all <a href="http://en.wikipedia.org/wiki/Essential_complexity">essential complexity</a>, with virtually no boilerplate from the original script left.</p><p>This is the first time that's happened. I think it's important to listen to what Perl 5 people think and to try to respond to that. But I also think that this time, it's a case of them seeing some highly idiomatic Perl 6, and freaking out a bit.</p><p>And I think that that, in some odd sense, is a good thing. Well, not freaking people out, per se. But the fact that we did shows that there's something forming which might be tentatively called "idiomatic Perl 6": people on the inside can read it quite easily, but those on the outside, even Perl 5 folks looking in, instinctively go "eeeeew!".</p><p>That's OK. You're not meant to start with the idiomatic stuff. <em>Language acquisition takes place step by step</em>, and that goes for learning Perl 6 as well. On the way there, just don't confuse distaste with lack of familiarity.</p> masak 2010-08-27T00:22:03+00:00 perl6 Where in the world is the package lexpad? http://use.perl.org/~masak/journal/40511?from=rss <p> <i>(This post isn't very punny. For those of you who need puns to survive, try to figure out why jnthn++ named the IRC logs "the hottest footwear" recently. The answer, as with all good puns, is highly unsatisfying.)</i> </p><p>My quest for a Perl 6 implementation takes me ever deeper into the esoterics of lexpads, runtimes, and a far-more-than-everything-you-needed-to-know mindset. Today some random firings in my brain turned into the following conversation on #perl6.</p><p>During the conversation, I proposed two theories, both of which turned out to be wrong. (pmichaud++ shone the necessary light both times.) Being wrong felt less important than getting my mental model fixed.</p><p>I first thought of presenting the results of the below conversation as a simple tutorial ("How <code>our</code> declarations work. The complete guide."), but now I think that the conversation, minimally edited, manages to be such a tutorial on its own.</p><p>Besides, blogging things in their raw and undigested form is a sign of the times. Enjoy!</p><p> <code> &lt;masak&gt; I have a question. is there a need for a special "package lexpad" containing 'our'-declared variables, or can the package lexpad simply be equated to the topmost lexpad in the package?<br> <br> &lt;masak&gt; my suspicion is the latter, but I might be missing something.<br> <br> &lt;pmichaud&gt; the package lexpad can't be the same as the top most lexical<br> <br> &lt;pmichaud&gt; <b>module XYZ { my sub abc() {<nobr> <wbr></nobr>... } }; # abc should not appear in the package</b> <br> <br> &lt;masak&gt; oh!<br> <br> &lt;masak&gt; right.<br> <br> &lt;masak&gt; so, separate one, then.<br> <br> &lt;jnthn&gt; Additionally, lexpads are meant to be static by the time we hit runtime, and you're allowed to shove stuff into the package dynamically. Not quite sure how those two hold together.<br> <br> &lt;pmichaud&gt; well, <b>module XYZ {<nobr> <wbr></nobr>... }</b> creates a lexical XYZ entry that holds the package entries<br> <br> &lt;jnthn&gt; Aha!<br> <br> &lt;pmichaud&gt; and it's just a hash, really.<br> <br> &lt;masak&gt; does inserting the package lexpad below the outside lexpad (and above the topmost lexpad) make sense? that way, Yapsi wouldn't need any special opcodes for doing 'our'-variable lookups.<br> <br> &lt;pmichaud&gt; the package lexpad is an entry in the outside lexpad, yes.<br> <br> &lt;pmichaud&gt; I'm not sure it encapsulates the nested lexpad, though.<br> <br> &lt;masak&gt; hm.<br> <br> &lt;masak&gt; if it doesn't, I don't really see how it's visible from inside the package.<br> <br> &lt;masak&gt; I've more or less convinced myself that sandwiching it between outer and topmost is what I want to do for Yapsi.<br> <br> &lt;pmichaud&gt; <b>our &amp;xyz</b> can make an entry in both the package and in the lexical.<br> <br> &lt;pmichaud&gt; this is what rakudo does now.<br> <br> &lt;pmichaud&gt; we have to do similar things for methods already, too.<br> <br> &lt;masak&gt; sure. it makes entries in both.<br> <br> &lt;pmichaud&gt; by having entries in both, that's how it's visible inside the package<br> <br> &lt;masak&gt; hm, indeed.<br> <br> &lt;masak&gt; no need to have the package lexpad visible from inside.<br> <br> &lt;pmichaud&gt; anyway, sandwiching might work too. haven't quite gotten to that point in Rakudo thinking yet. And it can get a bit tricky with multis.<br> <br> &lt;masak&gt; no need to sandwich it in, either. it can sit in limbo outside the tree of scopes.<br> <br> &lt;pmichaud&gt; oh, I know why it perhaps shouldn't (or should) be visible:<br> <br> &lt;pmichaud&gt; <b>my $x = 'lexical'; module XYZ { say $x; { our $x = 'package'; } }</b> <br> <br> &lt;masak&gt;<nobr> <wbr></nobr>...yes?<br> <br> &lt;pmichaud&gt; I'm pretty sure "say $x" needs to grab the 'lexical' $x, not the one that might be "sandwiched" in a package.<br> <br> &lt;masak&gt; of course.<br> <br> &lt;masak&gt; that falls out from ordinary scope nesting and shadowing.<br> <br> &lt;masak&gt; innermost block binds its lexical to the container in the package lexpad.<br> <br> &lt;masak&gt; so, that speaks out against sandwiching.<br> <br> &lt;masak&gt; pmichaud++ </code> </p><p>So there you go. There's a separate package scope, and it isn't sandwiched.</p><p> <i>(Answer: The missing link is the "IR clogs" meme from #parrot. I can hear you groaning... I did warn you.)</i> </p> masak 2010-08-22T21:39:58+00:00 perl6 Will parrot be the last one standing? http://use.perl.org/~nicholas/journal/40509?from=rss <p>I'm a bit behind the times here, but I read today that one of the two remaining developers of IronRuby has left Microsoft:</p><blockquote><div><p>Overall, I see a serious lack of commitment to IronRuby, and dynamic language on<nobr> <wbr></nobr>.NET in general. At the time of my leaving Tomas and myself were the only Microsoft employees working on IronRuby.</p></div></blockquote><p> <a href="http://blog.jimmy.schementi.com/2010/08/start-spreading-news-future-of-jimmy.html">http://blog.jimmy.schementi.com/2010/08/start-spreading-news-future-of-jimmy.ht<nobr>m<wbr></nobr> l</a>*</p><p>So if Microsoft's interest in dynamic languages is wilting, and Oracle's litigation scares everyone away from Java, will that leave <a href="http://parrot.org/">Parrot</a> as the last one standing?</p><p> <small>* yep, that's a formatting bug. I assume that it's not worth reporting while the site's future is unclear.</small> </p> nicholas 2010-08-20T09:37:19+00:00 journal Speaking at Microsoft TechEd - Any issues you want raised? http://use.perl.org/~Alias/journal/40508?from=rss <p>Next week I will at Microsoft's TechEd Australia event, courtesy of Microsoft Australia and Microsoft Open Source Labs.</p><p>More specifically, I'll be attending the Open Source mini-conf and discussion day on Tuesday, and presenting in the Community Presentations to Microsoft session on the current state of Perl and Windows on Wednesday.</p><p>Likely topics will include a review of the first year of the CPAN Testing Lab and a second-generation based on their Cloud Services, free code signing certificates for open source developers, and what issues are slowing us down or blocking progress.</p><p>So consider this your opportunity to raise any outstanding issues you have with Microsoft and Perl. What problems are you still seeing, what would like fixed or changed, and what is on your want-to-have list?</p><p>I'll try to address as many of your issues as possible in the time I have available with them (which is actually pretty substantial).</p> Alias 2010-08-20T03:20:46+00:00 journal New WWW::Salesforce release details http://use.perl.org/~Phred/journal/40506?from=rss <p>I've taken over the maintainership role for WWW::Salesforce and have pushed out a maintenance release that resolves some long standing issues.</p><p><a href="http://search.cpan.org/dist/WWW-Salesforce/">http://search.cpan.org/dist/WWW-Salesforce/</a></p><p>0.12 Tue Aug 17 19:34:00 2010 PST<br> &nbsp; &nbsp; &nbsp; &nbsp; - New maintainer PHRED<br> &nbsp; &nbsp; &nbsp; &nbsp; - Thanks to Mark Stosberg for several patches for this version<br> &nbsp; &nbsp; &nbsp; &nbsp; - Die with an error string instead of carping and returning<br> &nbsp; &nbsp; &nbsp; &nbsp; - Skip tests in automated testing mode<br> &nbsp; &nbsp; &nbsp; &nbsp; - Skip tests unless user, pass, and sectoken environment vars set<br> &nbsp; &nbsp; &nbsp; &nbsp; - Fix failing test - base64binary =&gt; base64Binary namespace change<br> &nbsp; &nbsp; &nbsp; &nbsp; - Perltidy file contents and remove unnecessary package scope braces<br> &nbsp; &nbsp; &nbsp; &nbsp; - Handle undefined return values from SOAP client<br> &nbsp; &nbsp; &nbsp; &nbsp; - Fix Type =&gt; type doc error in create()<br> &nbsp; &nbsp; &nbsp; &nbsp; - Add describeSObjects method [tom@eborcom.com]</p> Phred 2010-08-19T17:24:05+00:00 journal Alien::SVN - new release, new management http://use.perl.org/~schwern/journal/40503?from=rss <p>Those of you still stuck using Subversion will be happy to find <a href="http://search.cpan.org/~mlanier/Alien-SVN-1.6.12.0/">a new release of Alien::SVN</a>. It drags it forward to 1.6.12, doesn't do much else.</p><p>Also, Alien::SVN has finally found a new manager! From out of the blue comes <a href="http://search.cpan.org/~mlanier/">Matthew Lanier</a> with a patch and the will and a PAUSE ID. He'll be taking care of things from now on. Its his first CPAN module, be gentle. Godspeed, Matthew.</p> schwern 2010-08-18T22:33:29+00:00 journal Perlmongers Dinner http://use.perl.org/~Phred/journal/40502?from=rss <p>We'll be having a group dinner for the August meeting, and have<br>a few drinks after for those interested. This will mostly<br>be a planning meeting for future meetings, but all are welcome<br>for Perl discussion and agreat food.</p><p>"Naan-N-Curry" at 336 O'Farrell Street, between Mason and Taylor.</p><p> &nbsp; http://maps.google.com/maps?q=336+OFarrell+St,+San+Francisco,+CA+94102,+USA</p><p>This place has moved around a few times, and has many satellite<br>locations now, so look at that address carefully. This is across the<br>street from the Hilton, and next to the entrance to a large parking<br>garage.</p><p>From the Powell Street Bart station: walk two blocks north along Powell,<br>and 1.5 blocks west. Don't try to walk up Mason or Taylor, unless<br>you're in an adventurous mood.</p><p>The food is inexpensive, high quality Indian food. They have a buffet<br>these days, which makes things simpler. Free chai. The dining room<br>is double-sized, with large tables: there's no need to worry too much<br>about RSVPs.</p><p> &nbsp; http://naancurry.com/branches.php?brn=5</p><p>This place used to be 24 hours, but I guess they've scaled back to<br>11:00 AM to 4:00 AM. But I don't think we'll need to rush out of<br>there.</p><p>Announcement posted via App::PM::Announce</p><p>RSVP at Meetup - <a href="http://www.meetup.com/San-Francisco-Perl-Mongers/calendar/14453668/">http://www.meetup.com/San-Francisco-Perl-Mongers/calendar/14453668/</a></p> Phred 2010-08-17T20:49:00+00:00 journal Class::XSAccessor now even faster'er http://use.perl.org/~Alias/journal/40497?from=rss <p>The new 1.07 release of <a href="http://search.cpan.org/perldoc?Class::XSAccessor">Class::XSAccessor</a> mentions the use a new somewhat-evil technique for making the code even faster than it was previously.</p><p>But how much faster is it?</p><p>The following are being run on a fairly typical corporate Windows XP machine, with Strawberry Perl 5.10.1 and thread support.</p><p>First, some benchmarks using the previous 1.05 release (two runs)</p><blockquote><div><p> <tt>Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...<br>accessor_get:&nbsp; 1 wallclock secs ( 2.51 usr +&nbsp; 0.00 sys =&nbsp; 2.51 CPU) @ 3976143.14/s (n=10000000)<br>accessor_set:&nbsp; 2 wallclock secs ( 3.09 usr +&nbsp; 0.00 sys =&nbsp; 3.09 CPU) @ 3233107.02/s (n=10000000)<br>constructor: 16 wallclock secs (15.67 usr +&nbsp; 0.00 sys = 15.67 CPU) @ 638080.65/s (n=10000000)<br>&nbsp; &nbsp; &nbsp;false:&nbsp; 2 wallclock secs ( 1.91 usr +&nbsp; 0.00 sys =&nbsp; 1.91 CPU) @ 5243838.49/s (n=10000000)<br>&nbsp; &nbsp; getter:&nbsp; 1 wallclock secs ( 2.34 usr +&nbsp; 0.00 sys =&nbsp; 2.34 CPU) @ 4266211.60/s (n=10000000)<br> &nbsp; predicate:&nbsp; 1 wallclock secs ( 2.38 usr +&nbsp; 0.00 sys =&nbsp; 2.38 CPU) @ 4210526.32/s (n=10000000)<br>&nbsp; &nbsp; setter:&nbsp; 2 wallclock secs ( 3.27 usr +&nbsp; 0.00 sys =&nbsp; 3.27 CPU) @ 3061849.36/s (n=10000000)<br>&nbsp; &nbsp; &nbsp; true:&nbsp; 1 wallclock secs ( 1.80 usr +&nbsp; 0.00 sys =&nbsp; 1.80 CPU) @ 5564830.27/s (n=10000000)<br> &nbsp; <br>Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...<br>accessor_get:&nbsp; 3 wallclock secs ( 2.51 usr +&nbsp; 0.00 sys =&nbsp; 2.51 CPU) @ 3976143.14/s (n=10000000)<br>accessor_set:&nbsp; 3 wallclock secs ( 3.14 usr +&nbsp; 0.00 sys =&nbsp; 3.14 CPU) @ 3183699.46/s (n=10000000)<br>constructor: 15 wallclock secs (15.73 usr +&nbsp; 0.00 sys = 15.73 CPU) @ 635566.29/s (n=10000000)<br>&nbsp; &nbsp; &nbsp;false:&nbsp; 2 wallclock secs ( 1.86 usr +&nbsp; 0.00 sys =&nbsp; 1.86 CPU) @ 5379236.15/s (n=10000000)<br>&nbsp; &nbsp; getter:&nbsp; 3 wallclock secs ( 2.50 usr +&nbsp; 0.00 sys =&nbsp; 2.50 CPU) @ 4000000.00/s (n=10000000)<br> &nbsp; predicate:&nbsp; 3 wallclock secs ( 2.47 usr +&nbsp; 0.00 sys =&nbsp; 2.47 CPU) @ 4050222.76/s (n=10000000)<br>&nbsp; &nbsp; setter:&nbsp; 4 wallclock secs ( 3.13 usr +&nbsp; 0.00 sys =&nbsp; 3.13 CPU) @ 3200000.00/s (n=10000000)<br>&nbsp; &nbsp; &nbsp; true:&nbsp; 2 wallclock secs ( 1.98 usr +&nbsp; 0.00 sys =&nbsp; 1.98 CPU) @ 5037783.38/s (n=10000000)</tt></p></div> </blockquote><p>And now again with the new 1.07 release.</p><blockquote><div><p> <tt>Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...<br>accessor_get:&nbsp; 2 wallclock secs ( 1.75 usr +&nbsp; 0.00 sys =&nbsp; 1.75 CPU) @ 5711022.27/s (n=10000000)<br>accessor_set:&nbsp; 1 wallclock secs ( 2.69 usr +&nbsp; 0.00 sys =&nbsp; 2.69 CPU) @ 3721622.63/s (n=10000000)<br>constructor: 15 wallclock secs (15.62 usr +&nbsp; 0.00 sys = 15.62 CPU) @ 640000.00/s (n=10000000)<br>&nbsp; &nbsp; &nbsp;false:&nbsp; 1 wallclock secs ( 1.28 usr +&nbsp; 0.00 sys =&nbsp; 1.28 CPU) @ 7806401.25/s (n=10000000)<br>&nbsp; &nbsp; getter:&nbsp; 1 wallclock secs ( 1.56 usr +&nbsp; 0.00 sys =&nbsp; 1.56 CPU) @ 6397952.66/s (n=10000000)<br> &nbsp; predicate:&nbsp; 2 wallclock secs ( 1.92 usr +&nbsp; 0.00 sys =&nbsp; 1.92 CPU) @ 5205622.07/s (n=10000000)<br>&nbsp; &nbsp; setter:&nbsp; 3 wallclock secs ( 2.50 usr +&nbsp; 0.00 sys =&nbsp; 2.50 CPU) @ 4000000.00/s (n=10000000)<br>&nbsp; &nbsp; &nbsp; true:&nbsp; 2 wallclock secs ( 1.55 usr +&nbsp; 0.00 sys =&nbsp; 1.55 CPU) @ 6464124.11/s (n=10000000)<br> &nbsp; <br>Benchmark: timing 10000000 iterations of accessor_get, accessor_set, constructor, false, getter, predicate, setter, true...<br>accessor_get:&nbsp; 2 wallclock secs ( 1.78 usr +&nbsp; 0.00 sys =&nbsp; 1.78 CPU) @ 5614823.13/s (n=10000000)<br>accessor_set:&nbsp; 3 wallclock secs ( 2.63 usr +&nbsp; 0.00 sys =&nbsp; 2.63 CPU) @ 3809523.81/s (n=10000000)<br>constructor: 16 wallclock secs (15.69 usr +&nbsp; 0.00 sys = 15.69 CPU) @ 637429.88/s (n=10000000)<br>&nbsp; &nbsp; &nbsp;false:&nbsp; 2 wallclock secs ( 1.22 usr +&nbsp; 0.00 sys =&nbsp; 1.22 CPU) @ 8203445.45/s (n=10000000)<br>&nbsp; &nbsp; getter:&nbsp; 2 wallclock secs ( 1.53 usr +&nbsp; 0.00 sys =&nbsp; 1.53 CPU) @ 6535947.71/s (n=10000000)<br> &nbsp; predicate:&nbsp; 2 wallclock secs ( 1.78 usr +&nbsp; 0.00 sys =&nbsp; 1.78 CPU) @ 5614823.13/s (n=10000000)<br>&nbsp; &nbsp; setter:&nbsp; 2 wallclock secs ( 2.56 usr +&nbsp; 0.00 sys =&nbsp; 2.56 CPU) @ 3903200.62/s (n=10000000)<br>&nbsp; &nbsp; &nbsp; true:&nbsp; 2 wallclock secs ( 1.48 usr +&nbsp; 0.00 sys =&nbsp; 1.48 CPU) @ 6738544.47/s (n=10000000)</tt></p></div> </blockquote><p>The numbers are pretty impressive.</p><p>The 'accessor', 'setter', 'predicate' and 'true' methods are about 25% faster, while 'getter' is a whopping 60% faster and (curiously) 'false' is about 50% faster as well.</p><p>Constructors are really the only thing that hasn't changed.</p><p>Impressive work, even if the code is a bit risky.</p> Alias 2010-08-16T03:04:05+00:00 journal Why does Object::Tiny only support getters http://use.perl.org/~Alias/journal/40496?from=rss <p><a href="http://perlalchemy.blogspot.com/2010/08/objecttinyrw-and-moosexnonmoose.html">http://perlalchemy.blogspot.com/2010/08/objecttinyrw-and-moosexnonmoose.html</a></p><p>Zbigniew Lukasiak tries out <a href="http://search.cpan.org/peldoc?Object::Tiny">Object::Tiny</a> and wonders why it is that I didn't allow for the creation of setters when it is only a one line change.</p><p>Like most<nobr> <wbr></nobr>::Tiny modules the reason is a bit complex and the result of compromises.</p><p>Object::Tiny began as an attempt to create a lighter, faster, version of Class::Accessor. A way to bulk-generate the accessor code I had to type over and over again.</p><p>However, where I differ is a strong preference for light and elegant API design.</p><p>And so I decided to implement mine with as little implementation code as possible, and as little API code as possible.</p><p>Once you have decided to go down the simplicity path, there's a couple of standard techniques you often end up using.</p><p>The first and most important is state reduction.</p><p>In their introduction to Erlang, the founders of that language describe state as one of the main sources of failures in programs. And so anything that removes state, at the very least unnecessary state, is a positive. Especially if the state reduction also results in code reduction, and a reduction in computation.</p><p>So take the following example, where we create an object with some attributes and then run some code that will use those object attributes..</p><blockquote><div><p> <tt>my $object = Class-&gt;new;<br>$object-&gt;foo(1);<br>$object-&gt;bar(2);<br>$object-&gt;do_something;</tt></p></div> </blockquote><p>This is a use case that we see fairly often, but it's really quite horrible code. It is really only the object-oriented equivalent of something like the following.</p><blockquote><div><p> <tt>our $Object::foo = 1;<br>our $Object::bar = 2;<br>do_something('Object');</tt></p></div> </blockquote><p>It is especially bad code if the following code would throw an exception.</p><blockquote><div><p> <tt>my $object = Class-&gt;new;<br>$object-&gt;do_something;</tt></p></div> </blockquote><p>If this blows up, then you are REALLY doing something wrong, because you have allowed the creation of completely invalid objects. Now anybody taking one of these objects as a parameters needs to do with following.</p><blockquote><div><p> <tt>sub foo {<br>&nbsp; &nbsp; my $object = shift;<br>&nbsp; &nbsp; unless (<br>&nbsp; &nbsp; &nbsp; &nbsp; $object-&gt;isa('Class')<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; defined $object-&gt;foo<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; $object-&gt;foo &gt; 0<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; defined $object-&gt;bar<br>&nbsp; &nbsp; &nbsp; &nbsp; and<br>&nbsp; &nbsp; &nbsp; &nbsp; $object-&gt;bar &gt; 2<br>&nbsp; &nbsp; ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; die "Invalid object";<br>&nbsp; &nbsp; }<br>}</tt></p></div> </blockquote><p>If you are going to create an object for something, you HAVE to be sure that the objects are trustworthy.</p><p>And so you should never allow objects to exist that are invalid. EVERY object should be a valid object.</p><p>At the absolute minimum objects should be able to default every attribute to something reasonable and unlikely to cause problems.</p><p>But this still results in excess and wasteful work, because the object has to transition through two or more states.</p><p>You start with an object with parameters and defaults, and you validate them. And then you change on of the attributes immediately, validating it AGAIN. In the mean time, your object exists in a state that it will never actually be used in.</p><p>And so everywhere you possibly can, you should be setting attributes in the constructor rather than afterwards.</p><blockquote><div><p> <tt>my $object = Class-&gt;new(<br>&nbsp; &nbsp; foo =&gt; 1,<br>&nbsp; &nbsp; bar =&gt; 2,<br>);<br>$object-&gt;do_something;</tt></p></div> </blockquote><p>Less state, less complexity, less CPU, and less bugs.</p><p>If we accept this model of pushing all the configuration into the object up front to reduce state, then why change the object arbitrarily?</p><p>In fact, anything that you ARE going to change should be done under very controlled conditions.</p><p>It should require a dedicated method to apply the change, it should require validation, and work. It shouldn't be trivial, and it shouldn't be automatic.</p><p>If I had my way, Moose would set is =&gt; 'ro' by default, to make people think before they go about simply allowing stuff to change.</p><p>It also happens to let you shrink down the API markedly.</p><p>There are three potential use cases available when implementing accessors. Everything readonly, everything readwrite, or mixed.</p><p>With Object::Tiny, I was aiming for the smallest possible code.</p><p>Implementing either all-readonly or all-readwrite can be done with the following.</p><blockquote><div><p> <tt>use Class qw{<br>&nbsp; &nbsp; foo<br>&nbsp; &nbsp; bar<br>};</tt></p></div> </blockquote><p>By contrast, if we want to allow mixed readonly and readwrite, we would need some way of distinguishing. Something like the following.</p><blockquote><div><p> <tt>use Class {<br>&nbsp; &nbsp; readonly =&gt; [ 'foo' ],<br>&nbsp; &nbsp; readwrite =&gt; [ 'bar' ],<br>};<br> &nbsp; <br>use Class [ qw{<br>&nbsp; &nbsp; foo<br>} ], [ {<br>&nbsp; &nbsp; bar<br>} ];<br> &nbsp; <br>use Class {<br>&nbsp; &nbsp; foo =&gt; 'ro',<br>&nbsp; &nbsp; bar =&gt; 'rw',<br>};</tt></p></div> </blockquote><p>No matter how you try, there's always an inherent additional element of complexity that results from the split between them.</p><p>And so the decision to go with all-readonly in Object::Tiny is a combination of these two issues.</p><p>If went with all-readwrite, I'm practically encouraging bad behaviour and more bugs. If I went with mixed accessors, the API would remain relative complex.</p><p>In the end, the best way to achieve both API simplicity and code safety is to only provide read-only accessors, and anything more complex should require both though and effort.</p> Alias 2010-08-15T01:39:50+00:00 journal Weeks 8..12 of GSoC work on Buf -- not packing it in yet http://use.perl.org/~masak/journal/40494?from=rss <p> <em>I was reproached by my colleague because of the lack of "no cake"-style jokes in this last grant update. So what can I do to amend the situation? Firstly, let me concede that the below blog post is almost tear-inducingly boring. Secondly, let me remind you that when accosted by boring material such as that in this post, the most important thing to have is a positive outlook on life. Thank you.</em> </p><p>The past couple of days have been really eventful. The coming couple of days probably will be, too. It seems fitting to punctuate all this eventfulness with a status-updating blog post, something that I apparently haven't gotten around to in a few weeks.</p><p>So, what's been happening?</p><ul> <li>In the <a href="http://use.perl.org/~masak/journal/40440">last update</a>, I was at a point where I needed to encode to different encodings, not just UTF-8. Tonight I had <a href="http://irclog.perlgeek.de/parrot/2010-08-13#i_2701004">an enlightening discussion</a> with the Parrot people, which gave all the pieces of the puzzle. Now it's just a Simple Matter of Programming. More precisely, I need to apply it to <a href="http://github.com/rakudo/rakudo/blob/0839993ed01c816dc8b3459fa7b79608be4fbf3a/src/core/Str.pm#L17">this spot</a> in the code base.</li><li>By that discussion, I was once again made aware that Parrot differs between <em>encodings</em> and <em>charsets</em>. For example, <code>utf8</code> is an encoding, but <code>iso-8859-1</code> is a charset. It's confusing me slightly, but that's OK. I can make the code work so that both are treated as "encodings" on the Perl 6 level.</li><li>I got unexpected assistance from oha++, who took me aside in private discussions to discuss new wild ideas for <code>Buf</code>. It all culminated in a <a href="http://www.mail-archive.com/perl6-language@perl.org/msg32689.html">p6l thread</a>. Oha is writing code that uses Buf for network traffic, and has been preparing a patch for making <code>IO::Socket::INET</code> return <code>Buf</code>s instead of <code>Str</code>s. In trying out this patch, oha++ found that some tests <a href="http://irclog.perlgeek.de/perl6/2010-08-12#i_2694900">will never work</a> when <code>Buf</code>s are used. Those tests will probably need to be rewritten.</li><li>During the past week or so, I've been implementing <code>pack</code> and <code>unpack</code> in a branch. I'm making steady progress, and trying to take in documentation such as Perl 5's <a href="http://perldoc.perl.org/functions/pack.html"> <code>perldoc -f pack</code> </a> and <a href="http://perldoc.perl.org/perlpacktut.html"> <code>perlpacktut</code> </a> and <a href="http://www.erlang.org/doc/man/ei.html">Erlang's</a> <a href="http://www.trapexit.org/How_to_use_ei_to_marshal_binary_terms_in_port_programs"> <code>ei</code> </a> and <a href="http://www.tcl.tk/man/tcl8.5/TclCmd/binary.htm">Tcl's <code>binary</code> </a>. It's a lot to take in, and I won't aim for full functionality &#8212; look, <a href="http://github.com/mirrors/perl/blob/blead/t/op/pack.t">Perl 5 has 14699 tests</a> for pack! &#8212; but rather a reasonable subset of the directives from Perl 5.</li></ul><p>There's a lot to be said about the interplay between Perl 6's high level of abstraction and the almost reckless to-the-metal feeling of <code>&amp;pack</code>/<code>&amp;unpack</code>. Add to this that the "metal" in this case is Parrot, which in some regards is there to abstract away the real metal. I think the details of this interplay might well be the subject of a separate blog post. When I'm not busy finishing up the code itself. &#21704;&#21704;</p><p>The hard pencils-down deadline for GSoC is on Monday. I'm pretty sure I will have tied up the remaining loose ends by then, but I also foresee a couple of fairly focused hours programming before that. Time to dig back in; see you on the other side.</p> masak 2010-08-13T22:35:51+00:00 perl6 There's just no way to keep up with all you people http://use.perl.org/~masak/journal/40490?from=rss <p>Let's look at a week two years ago in the perl6 RT queue. Who submitted bugs?</p><p> <code> Moritz<br> Moritz<br> Moritz<br> Moritz<br> Yaakov<br> Yaakov<br> <strong>Carl</strong> <br> Moritz<br> Moritz<br> Ron<br> Charlie<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> </code> </p><p>Seems I just managed to tie with Moritz++ there. Almost one ticket a day sounds about right from what I remember of my submit pace from that time. In total, there were 16 tickets in that week.</p><p>Ok, that was two years ago. What about one year ago? By this time, Rakudo had already picked up a bit of a reputation.</p><p> <code> Patrick<br> Patrick<br> <strong>Carl</strong> <br> Alex<br> Alex<br> Timothy<br> Moritz<br> Gilbert<br> <strong>Carl</strong> <br> Timothy<br> Timothy<br> Eduardo<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> dakkar<br> dakkar<br> Hanno<br> Solomon<br> Ben<br> Solomon<br> Ben<br> dakkar<br> Aaron<br> Solomon<br> </code> </p><p>Dang, only five tickets that week. &#21704;&#21704;</p><p>Still, a pretty typical week. 25 tickets all in all. We see a bit more variation in the names now. That's the new people.</p><p>Finally, let's look at last week:</p><p> <code> Ekkehard<br> Timothy<br> Tom<br> cognominal<br> Cosimo<br> Sven<br> Chris<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Moritz<br> Simon<br> Mulander<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Pawe&#322;<br> Tadeusz<br> Aaron<br> cognominal<br> cognominal<br> <strong>Carl</strong> <br> Pawe&#322;<br> Lithos<br> Lithos<br> <strong>Carl</strong> <br> <strong>Carl</strong> <br> Tyler<br> Alex<br> Lithos<br> Moritz<br> Lithos<br> Brian<br> Moritz<br> Moritz<br> Pawe&#322;<br> Steve<br> Francesco<br> Lithos<br> Jarrod<br> Lithos<br> Francesco<br> <strong>Carl</strong> <br> Moritz<br> </code> </p><p>These figures help express what I feel. I'm still submitting a fair amount of tickets &#8212; all of nine last week &#8212; and still they make up an ever-smaller proportion of the growing deluge of perl6 tickets on RT.</p><p>Or, put differently, all you other people finally caught up with me. I can no longer compete with the rest of you. &#21704;&#21704;</p><p>It makes me proud and excited to disappear under the waves of other people's contributions. There's been both a slow buildup over the past two years, and a sudden spike thanks to Rakudo Star. Together, they help drown out my insistent, repeating splashes on RT.</p><p>Rakudobugs are love. There's a whole lotta love out there right now. &#9829; This uptake is what we've been waiting for.</p> masak 2010-08-10T20:22:42+00:00 perl6 Test::Builder2::Design http://use.perl.org/~schwern/journal/40487?from=rss <p>In an effort to shed some light on what Test::Builder2 is about, I took a few hours and performed a brain dump about its goals and design. You can see the result in the new <a href="http://github.com/schwern/test-more/blob/Test-Builder2/lib/Test/Builder2/Design.pod">Test::Builder2::Design</a> document.</p><p>The key design goals are 1) that it has to work, 2) that it has to work everywhere and 3) that it has to test everything. This throws out a lot of 98% solutions.</p> schwern 2010-08-10T02:31:05+00:00 journal Ctypes update: pretty objects http://use.perl.org/~doubi/journal/40485?from=rss <p>Since my last couple of posts, things have been done: </p><ul> <li>Complete revamping of call logic</li><li>Finished objects for basic C Types (int, double etc.)</li><li>A fairly sound cast() function for Ctypes</li><li>Array objects</li></ul><p> Despite this, I don't think I'm going to get everything implemented for the GSoC deadline<nobr> <wbr></nobr>:-/ Still a long list of features I want to add. Particularly notable by their absence are Pointers, Structures, Unions, paramflags and support for special Win32 objects (COM stuff, HRESULT and friends).</p><p>Crap... when you list it like that, sounds pretty dire, don't it?</p><p>Don't beat me up just yet though. I'll definitely get Pointers done in the next 48 hours. Not sure how tricky Structs and Unions will be but they'll definitely be done by the deadline too. <i>Anyway</i>, instead of wasting more time worrying I want to talk a bit more about my favourite topic...</p><p> <b>Type object API revisited</b> </p><p>In response to my <a href="http://blogs.perl.org/users/doubi/2010/07/thoughts-on-ctypestype-object-api.html">full post on the matter</a> [0], <a href="http://plasmasturm.org/">Aristotle</a> [1] pointed out that if tie'd behaviour was the objective we could have the rather nice</p><blockquote><div><p> <tt>c_int my $intobj = 5;</tt></p></div> </blockquote><p> This is cool, but I was scundered by the fact that you couldn't then call methods on your $intobj. Boo-hoo.</p><p>The solution was embarrassingly simple, actually. I didn't so much think of it as came across it naturally when implementing Array types. To make an $arrayobject act like an array, I overloaded <code>'@{}'</code> to return the tied member of its internal hash, so you use it as an array and as an object like so:</p><blockquote><div><p> <tt>use Ctypes;<br>my $array = Array( 1, 2, 3, 4, 5 );<br># makes array of smallest necessary type, c_short<br> <br>print $array;&nbsp; &nbsp; # Ctypes::Type::Array=HASH(0x8b2d550)<br> <br>print @$array;&nbsp; &nbsp;# 12345<br> <br>my $int1 = c_int( $$array[0] );<br># $int1-&gt;val = 3<br> <br>my $int2 = c_int( $array-&gt;[1] );<br># $int2-&gt;val = 2<br> <br>my $oops = c_int( $array[2] );<br># $oops = 0, $arr[x] is undef<br> <br>print "Top index of \$array is $#$array\n";<br># Top index of $array is 4<br> <br>print $array-&gt;type-&gt;typecode;&nbsp; &nbsp;# 's' for short</tt></p></div> </blockquote><p>Some might call sigil soup on that, but I like it. It gives you the best of both tied variables and objects. When using the object to do regular array stuff, you can think of '$array', including the dollar, as the var's identifier, so you put another sigil in front depending on what you want from it (@$array for contents as a list, $$array[x] for returning individual values, etc). For object stuff, just momentarily remember that '$array' is an object in its own right and call methods on it.</p><p>The embarrassing thing is, I basically overlooked the fact that <code>'${}'</code> is also overloadable. So we could easily assign to simple Type objects like <code>$$int = 10</code>, which is an improvement of 2 characters on the current shortest option, <code>$int-&gt;(10)</code>. Well, not counting the spaces...</p><p>But it's less about the character count than about looking at a piece of code and immediately seeing that the value 10 is being assigned to something, which is the semantic that operation is representing, rather than it appearing that some method is being called with 10 as an argument. I don't think the hyper-sigilism is too bad in exchange for that. It'll make Ctypes code 'distinctive' to look at<nobr> <wbr></nobr>:-)</p><p>As always, comments are strongly encouraged; on my pointer to array problem, the Type object API, or the project in general. Go on, take a shot...</p><p> [0] <a href="http://blogs.perl.org/users/doubi/2010/07/thoughts-on-ctypestype-object-api.html">http://blogs.perl.org/users/doubi/2010/07/thoughts-on-ctypestype-object-api.htm<nobr>l<wbr></nobr> </a> <br> [1] Aristotle: <a href="http://plasmasturm.org/">http://plasmasturm.org</a></p> doubi 2010-08-09T03:24:22+00:00 journal Perl 6 and Perl 5 are different languages http://use.perl.org/~masak/journal/40481?from=rss <p>Today at the YAPC::EU keynote, the inimitable Larry Wall, accompanied by his guardian angel and his guardian devil, made a poll asking which ones in the audience believed Perl 5 and Perl 6 are the same language, and which ones believed they are two different languages.</p><p>I was in the front row, so I didn't see the sea of hands and which way the poll tipped. But on my row, both Patrick Michaud and Jonathan Worthington voted "different". I was slightly surprised to find myself voting "different" as well. I'm the one who only last year wrote <a href="http://use.perl.org/~masak/journal/39861">this entry</a> which seems to insist on a "same" vote, if only by criticizing those who take the opposite view.</p><p>I think that what's happened in the past year is that there's a bit more room in the "Perl" space. We're now talking of <a href="http://www.shadowcat.co.uk/blog/matt-s-trout/-5-v-6.html">two different languages in the Perl family</a>, and the Perl community being <a href="http://use.perl.org/~masak/journal/40037">shaped like a tuning-fork</a> with its Perl-5 people, Perl-6 people, and Perl-omnivore people. It simply feels safer now to state "different", in a way it didn't last year.</p><p>One thing about the tuning fork that I really like is that it's basically two universes in one. We could've had</p><dl> <dd>(a) Perl 6 taking off early and essentially killing Perl 5, precluding its renaissance as Modern Perl, or</dd><dd>(b) Perl 6 floundering so badly and for so long that Perl 5 took over with such force that no-one bothered to develop Perl 6 anymore, and a "Forever Five" condition in the community was announced.</dd></dl><p>Instead we find ourselves in a junctional universe where both languages are thriving and evolving. And they're different, not least because Perl 5 is older, more mature, and more used in business-oriented environments. But Perl 6 is getting there too, and the two languages will start playing together on increasingly equal footing, just like half-a-generation-apart siblings would.</p><p>I like that.</p> masak 2010-08-04T23:10:09+00:00 perl6 Trailer Theory - Reinvented for Ignite Sydney as Economics http://use.perl.org/~Alias/journal/40480?from=rss <p>Back in 2005 in <a href="http://use.perl.org/~Alias/journal/23820">only my fifth use.perl post ever</a>, I outlined an idea I had been developing for a couple of years that I called "Trailer Theory".</p><p>A few years ago on my Portable Perl world hack'a'tour, I took with me a lightning talk version of the concept. It was a pretty crude talk but was received, it seemed, fairly well by the development community.</p><p>Since that trip, and inspired by the unexpected conversion of my "Perl is unparsable" claims in the PPI docs into a formal mathematical proof (complete with "Kennedy's Lemma") I've been wondering if this "Trailer Theory" idea could really be developed as a proper scientific proof, and if so what would that look like.</p><p>A couple of months ago I presented a new version of the talk at Ignite Sydney, speaking to an mixed audience of Twitterati, social media, advertising and journalist types.</p><p>I've rebuilt the talk from scratch and tried to outline the same idea, but in the form of a kind of layman's Economics Proof.</p><p>I hope you enjoy the result.</p><p><a href="http://igniteshow.com/videos/using-economics-make-movies-suck-less">Adam Kennedy - Using Economics to make movies suck less</a></p><p><i><br>Notes for other speakers:</i></p><p><i>1. Ignite advances slides every 15 seconds, no clickers allowed. This turns out to take a shitload of practice to get right.</i></p><p><i>2. When someone says to you "Here's your mark, you need to stay on this line to be in the fixed spot" it helps to pay attention. FAIL<nobr> <wbr></nobr>:)<br></i></p> Alias 2010-08-04T05:40:53+00:00 journal SF.pm grant funding proposal to TPF up for public review http://use.perl.org/~Phred/journal/40479?from=rss <p>A grant proposal I wrote for SF.pm is up for public review. All views welcome - <a href="http://news.perlfoundation.org/2010/08/2010q3-grant-proposal-sfpm-fun.html">http://news.perlfoundation.org/2010/08/2010q3-grant-proposal-sfpm-fun.html</a> </p> Phred 2010-08-03T20:43:17+00:00 journal Protesting the Moose with sugary alternatives http://use.perl.org/~Alias/journal/40477?from=rss <p>At work, we've been experimenting with Moose because in our enormous and complex codebase we think we can probably benefit a lot from the extra rigour that it brings.</p><p>Before I continue, let me note that ours is a typical mod_perl enterprise setup with 6gig of memory per machine, so any memory consumed before the Apache fork is essentially free.</p><p>So none of the issues people (including me) have with startup code and memory consumption apply in this case, and I won't be addressing performance issues in this post.</p><p>The consensus of the half-dozen people at work is how Moose tries to look like a declarative extension, but doesn't actually act like it.</p><p>The following is what Moose seems to have been aiming for.</p><blockquote><div><p> <tt>package Foo;<br> &nbsp; <br>use Moose;<br> &nbsp; <br>extends 'Bar';<br>with&nbsp; &nbsp; 'Role1';<br>with&nbsp; &nbsp; 'Role2';<br> &nbsp; <br>has this =&gt; (<br>&nbsp; &nbsp; is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; isa =&gt; 'Str',<br>);<br> &nbsp; <br>has that =&gt; (<br>&nbsp; &nbsp; is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; isa =&gt; 'Str',<br>);<br> &nbsp; <br>1;</tt></p></div> </blockquote><p>Unfortunately, this is what we've had to do instead.</p><blockquote><div><p> <tt>package Foo;<br> &nbsp; <br>use Moose;<br> &nbsp; <br>BEGIN { # When we use Catalyst<br>&nbsp; &nbsp; extends 'Bar';<br>}<br> &nbsp; <br>has this =&gt; (<br>&nbsp; &nbsp; is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; isa =&gt; 'Str',<br>);<br> &nbsp; <br>has that =&gt; (<br>&nbsp; &nbsp; is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; isa =&gt; 'Str',<br>);<br> &nbsp; <br>with&nbsp; &nbsp; 'Role1';<br>with&nbsp; &nbsp; 'Role2';<br>no Moose;<br>__PACKAGE-&gt;meta-&gt;make_immutable;</tt></p></div> </blockquote><p>This "real Moose" code totally spoils the dream of what we felt like we were going to get when we started to play with it.</p><p>Most of our current options for fixing this amount to either.</p><p>a) Add this extra dependency that will unscrew one of the other of the problems (namespace::autoclean)</p><p>b) Use this SECOND heavy sugar layer on top of the FIRST sugar layer, on top of Class::MOP.</p><p>Is fixing the syntax or writing light weight sugar really so hard?</p><p>As a kind of protest, I tried it for myself and managed to create <a href="http://search.cpan.org/perldoc?MooseX::Atom">MooseX::Atom</a>.</p><p>This still has some flaws, but the current equivalent of the above would just be this.</p><blockquote><div><p> <tt>package Foo;<br> &nbsp; <br>use MooseX::Atom [<br>&nbsp; &nbsp; extends =&gt; 'Bar',<br>&nbsp; &nbsp; with&nbsp; &nbsp; =&gt; 'Role1',<br>&nbsp; &nbsp; with&nbsp; &nbsp; =&gt; 'Role2',<br>&nbsp; &nbsp; has&nbsp; &nbsp; &nbsp;=&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;this =&gt; (<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;isa =&gt; 'Str',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;),<br>&nbsp; &nbsp; ],<br>&nbsp; &nbsp; has&nbsp; &nbsp; &nbsp;=&gt; [<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;that =&gt; (<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;is&nbsp; =&gt; 'ro',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;isa =&gt; 'Str',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;),<br>&nbsp; &nbsp; ]<br>];<br> &nbsp; <br>1;</tt></p></div> </blockquote><p>You can do the same thing for roles with <a href="http://search.cpan.org/perldoc?MooseX::Role::Atom">MooseX::Role::Atom</a>.</p><p>Now clearly, this might have some issues. It's the work of an hour and not a whole lot of thought.</p><p>But it's still light and clean, with all the class spec in one place up the top where people are used to seeing the declarative stuff in Perl modules.</p><p>Perhaps something like this might be a little better...</p><blockquote><div><p> <tt>package Foo;<br> &nbsp; <br>use MooseX::Hash {<br>&nbsp; &nbsp; extends =&gt; 'Bar',<br>&nbsp; &nbsp; with&nbsp; &nbsp; =&gt; [ 'Role1', 'Role2' ],<br>&nbsp; &nbsp; default =&gt; { is =&gt; 'ro' },<br>&nbsp; &nbsp; has&nbsp; &nbsp; &nbsp;=&gt; {<br>&nbsp; &nbsp; &nbsp; &nbsp; this =&gt; { isa =&gt; 'Str' },<br>&nbsp; &nbsp; &nbsp; &nbsp; that =&gt; { isa =&gt; 'Str' },<br>&nbsp; &nbsp; },<br>);<br> &nbsp; <br>1;</tt></p></div> </blockquote> Alias 2010-08-03T05:09:02+00:00 journal Yapsi 2010.08 Released! http://use.perl.org/~masak/journal/40475?from=rss <p>It is with vertiginous modesty that I want to announce, on behalf of the Yapsi development team, the August 2010 release of Yapsi, a Perl 6 compiler written in Perl 6. (Am I using, too many, commas?)</p><p>You can get it <a href="http://github.com/downloads/masak/yapsi/yapsi-2010.08.tar.gz">here</a> &#8212; as a bonus, if you download within 24 hours, the bits in your download will be hand-painted and signed by nine indefatigable mice from northern Belarus.</p><p>Yapsi is implemented in Perl 6. It thus requires a Perl 6 implementation to build and run. Both Rakudo Star and the latest monthly release ("Atlanta") seem to be fit to the task.</p><p>Yapsi is an "official and complete" implementation of Perl 6. It's official because we stole the "Official Perl 6" rubber stamp and applied it liberally. Unfortunately, we also used all the special ink -- please don't tell any of the other implementors that. It's complete because we implemented all the parts of the synopses that weren't eaten by the team's pet dugong.</p><p>This month's release consists of a total refactor of both the runtime and the compiler. The Yapsi.pm file is about 100 lines shorter, with the same functionality. Lexical variables are now handled more correctly. For a complete list of changes, see <a href="http://github.com/masak/yapsi/blob/master/doc/ChangeLog">doc/ChangeLog</a>.</p><p>Quite a lot of features are within reach of people who are interested in hacking on Yapsi. See the <a href="http://github.com/masak/yapsi/blob/master/doc/LOLHALP">doc/LOLHALP</a> file for a list of 'em.</p><p>Yapsi consists of a compiler and a runtime. The compiler generates a so-called instruction code, which is a code of instructions, for the runtime to run. This is fairly common, and nothing to be agitated about. The instruction code is called SIC, which is probably slightly less common. SIC is extended, re-thought and eaten by the team's pet dugong on a regular basis, so don't expect SIC from one release to be runnable on another.</p><p>An overarching goal for making a Perl 6 compiler-and-runtime is to use it as a server for various other projects, which will hook in at different steps:</p><ul> <li> A time-traveling debugger (tardis), which hooks into the runtime.</li><li> A coverage tool (lid), which will also hook into the runtime.</li><li> A syntax checker (sigmund), which will use output from the parser.</li></ul><p>Another overarching goal is to optimize for fun while learning about parsers, compilers, and runtimes.</p><p>Gotta go feed S16 to the team's pet dugong. We wish you the appropriate amount of fun!</p> masak 2010-08-01T23:50:48+00:00 perl6 Method::Signatures returns! 5.12, func() and fast! http://use.perl.org/~schwern/journal/40474?from=rss <p>Chip submitted a minor performance patch to Method::Signatures today. That drove me to push out <a href="http://github.com/schwern/method-signatures/blob/v20100730/Changes">a new release</a> making it friendly to 5.12 and adding func() for non methods!</p><p> &nbsp; &nbsp; &nbsp; &nbsp; func hello(:$greeting = "Hello",<nobr> <wbr></nobr>:$place = "World") {<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print "$greeting, $place!\n";<br> &nbsp; &nbsp; &nbsp; &nbsp; }</p><p> &nbsp; &nbsp; &nbsp; &nbsp; hello( place =&gt; "Earth" );</p><p>For those who don't know, one of the neato features of <a href="http://search.cpan.org/perldoc?Method::Signatures">Method::Signatures</a> is that it can <a href="http://search.cpan.org/~mschwern/Method-Signatures-20090620/lib/Method/Signatures.pm#Aliased_references">alias references</a> to make working with references less of a trial:</p><p> &nbsp; &nbsp; &nbsp; &nbsp; func popn(\@array, $howmany) {<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return splice @array, -$howmany;<br> &nbsp; &nbsp; &nbsp; &nbsp; }</p><p> &nbsp; &nbsp; &nbsp; &nbsp; my @stuff = (1,2,3,4,5);<br> &nbsp; &nbsp; &nbsp; &nbsp; my @last_three = popn(\@stuff, 3); # 3,4,5<br> &nbsp; &nbsp; &nbsp; &nbsp; print @last_three;</p><p>It does this with the amazing <a href="http://search.cpan.org/perldoc?Data::Alias">Data::Alias</a> module. Unfortunately, 5.12 broke its black magic and its non-trivial to fix. Method::Signatures now makes Devel::Alias an optional dependency. If its available, it'll use it. Otherwise, no aliasing for you.</p><p>But that's ok, because perl5i makes working with references enjoyable. And while perl5i is adding its own simple signatures, they're forward compatible with Method::Signatures! They play together, so if you want perl5i and the full power of Method::Signatures you can have them.</p><p> &nbsp; &nbsp; &nbsp; &nbsp; use perl5i::2;<br> &nbsp; &nbsp; &nbsp; &nbsp; use Method::Signatures;</p><p> &nbsp; &nbsp; &nbsp; &nbsp; func echo($message is ro) {<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; say $message;<br> &nbsp; &nbsp; &nbsp; &nbsp; }</p><p>Just make sure you load MS after perl5i. The last one loaded wins.</p><p>Finally, I was comparing Method::Signatures with MooseX::Method::Signatures and made a disturbing discovery. I always new MooseX::Method::Signatures would have a performance penalty, it does more checks than Method::Signatures, I just didn't realize how bad it was.</p><p>Here's comparing an empty signature: <code>method foo() {}</code>.</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rate&nbsp; &nbsp; MMS&nbsp; &nbsp; &nbsp;MS&nbsp; &nbsp; Std<br>MMS&nbsp; &nbsp; 3207/s&nbsp; &nbsp; &nbsp;--&nbsp; -100%&nbsp; -100%<br>MS&nbsp; 1498875/s 46644%&nbsp; &nbsp; &nbsp;--&nbsp; &nbsp; -1%<br>Std 1508351/s 46940%&nbsp; &nbsp; &nbsp;1%&nbsp; &nbsp; &nbsp;--</tt></p></div> </blockquote><p>That's showing MooseX::Method::Signatures is 450x slower than either Method::Signatures or a normal method call creaking out a mere 3500 method calls per second as compared to the 1.5 million it should be doing. And that's for a method with an empty signature!</p><p>To be clear, that's the speed of calling a method, not compiling them.</p><p>Here's one comparing a simple signature that requires a check, so MS can't optimize it away: <code>method foo($arg!) { return $arg + 1 }</code> That's a required positional argument.</p><blockquote><div><p> <tt>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Rate&nbsp; &nbsp; MMS&nbsp; &nbsp; &nbsp;MS&nbsp; &nbsp; Std<br>MMS&nbsp; &nbsp; 2928/s&nbsp; &nbsp; &nbsp;--&nbsp; -100%&nbsp; -100%<br>MS&nbsp; &nbsp;983127/s 33481%&nbsp; &nbsp; &nbsp;--&nbsp; &nbsp; -2%<br>Std 1005357/s 34240%&nbsp; &nbsp; &nbsp;2%&nbsp; &nbsp; &nbsp;--</tt></p></div> </blockquote><p>3000 method calls instead of a million.</p><p>Now I'm the first to counter arguments bemoaning method call overhead. Usually it doesn't matter. Usually the extra cost of calling a method and checking arguments is insignificant compared to what that method actually does. And MooseX::Method::Signatures has features Method::Signatures does not, most significantly type checking. But my god! Three orders of magnitude of performance lost! And its not even using the extra MMS features. That's just too much.</p> schwern 2010-07-31T00:49:55+00:00 journal Perl 6 Is The Language Your Language Could Smell Like http://use.perl.org/~schwern/journal/40472?from=rss <p><a href="http://www.youtube.com/watch?v=owGykVbfgUE">Hello programmers</a>. Look at your code, now at Perl 6, now back at your code, now back at Perl 6! Sadly, your code is not written in Perl 6. But if you use <a href="http://rakudo.org/announce/rakudo-star/2010.07">Rakudo Star</a> then Perl 6 is the language your code could be written in!</p><p><a href="http://github.com/rakudo/star/downloads">Now Microsoft scented!</a></p> schwern 2010-07-29T19:24:09+00:00 journal Help? http://use.perl.org/~Alias/journal/40470?from=rss <p>(Before I begin, I should clarify I did not write this code, I'm just trying to maintain it)</p><p>The following error is the first thing spat out by make test for the Padre sync server, located at <a href="http://svn.perlide.org/padre/trunk/Madre-Sync">http://svn.perlide.org/padre/trunk/Madre-Sync</a>.</p><p>Wasn't the move of Catalyst to Moose going to make things easier?</p><p>Can someone explain how you debug this?</p><p>I get the basics, I can see the "Can't locate Madre/Sync/Schema.pm". But that file should be, I think, automatically generated. And I don't really get how to dig down the 75 caller levels from the start to the end to work out where the actual functionality is failing...</p><blockquote><div><p> <tt>not ok 1 - use Catalyst::Test;<br> &nbsp; <br>#&nbsp; &nbsp;Failed test 'use Catalyst::Test;'<br>#&nbsp; &nbsp;at t\01app.t line 7.<br>#&nbsp; &nbsp; &nbsp;Tried to use 'Catalyst::Test'.<br>#&nbsp; &nbsp; &nbsp;Error:&nbsp; Couldn't load class (Madre::Sync) because: Couldn't instantiate component "Madre::Sync::Model::padreDB", "Can't locate Madre/Sync/Schema.pm i<br>n @INC (@INC contains: blib\lib blib\arch C:/strawberry/perl/lib C:/strawberry/perl/site/lib C:\strawberry\perl\vendor\lib<nobr> <wbr></nobr>.). at C:\strawberry\perl\vendor<br>\lib/Class/MOP.pm line 132<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_first_existing_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_class('Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Catalyst/Model/DBIC/Schema/Types.pm line 21<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Model::DBIC::Schema::Types::__ANON__[C:\strawberry\perl\vendor\lib/C<nobr>a<wbr></nobr> talyst/Model/DBIC/Schema/Types.pm:21]('Madre::Sync::Schema') called<br>at C:\strawberry\perl\vendor\lib/Moose/Meta/TypeCoercion.pm line 63<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::TypeCoercion::__ANON__[C:\strawberry\perl\vendor\lib/Moose/Meta/T<nobr>y<wbr></nobr> peCoercion.pm:67]('Madre::Sync::Schema') called at C:\strawberry\per<br>l\vendor\lib/Moose/Meta/TypeCoercion.pm line 97<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::TypeCoercion::coerce('Moose::Meta::TypeCoercion=HASH(0x4a2b444)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/Moose<br>/Meta/TypeConstraint.pm line 90<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::TypeConstraint::coerce('Moose::Meta::TypeConstraint=HASH(0x4a2985<nobr>4<wbr></nobr> )', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\lib/M<br>ooseX/Types/TypeDecorator.pm line 206<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 205<br>#&nbsp; &nbsp; &nbsp; &nbsp;MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a<nobr>3<wbr></nobr> 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l<br>ib/Moose/Meta/Attribute.pm line 743<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b46<nobr>7<wbr></nobr> fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db<br>7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(<nobr>0<wbr></nobr> x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M<br>odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C<br>lass.pm line 540<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm<br>line 256<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin<br>e 25<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/<br>Traits/Pluggable.pm line 131<br>#&nbsp; &nbsp; &nbsp; &nbsp;MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen<br>t/Traits.pm line 146<br>#&nbsp; &nbsp; &nbsp; &nbsp;CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl<br>ass/MOP/Method/Wrapped.pm line 48<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/<nobr>M<wbr></nobr> ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '<br>HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C<br>atalyst.pm line 2502<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/<nobr>M<wbr></nobr> ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven<br>dor\lib/Class/MOP/Method/Wrapped.pm line 89<br>#&nbsp; &nbsp; &nbsp; &nbsp;Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62<br>#&nbsp; &nbsp; &nbsp; &nbsp;require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67<br>#&nbsp; &nbsp; &nbsp; &nbsp;Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('C<nobr>a<wbr></nobr> talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a<br>t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call<br>ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S<br>ub/Exporter.pm line 742<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Ca<nobr>t<wbr></nobr> alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per<br>l\vendor\lib/Catalyst/Test.pm line 112<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2<br>#&nbsp; &nbsp; &nbsp; &nbsp;main::BEGIN() called at blib\lib/Madre/Sync.pm line 0<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at blib\lib/Madre/Sync.pm line 0<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval 'package main;<br># use Catalyst::Test @{$args[0]};<br># 1;<br>#<br>#<nobr> <wbr></nobr>;' called at C:/strawberry/perl/lib/Test/More.pm line 858<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p<br>m line 833<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7<br>#&nbsp; at C:\strawberry\perl\vendor\lib/MooseX/Types/TypeDecorator.pm line 208<br>#&nbsp; &nbsp; &nbsp; &nbsp;MooseX::Types::TypeDecorator::AUTOLOAD('MooseX::Types::TypeDecorator=HASH(0x4a<nobr>3<wbr></nobr> 1424)', 'Madre::Sync::Schema') called at C:\strawberry\perl\vendor\l<br>ib/Moose/Meta/Attribute.pm line 743<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x4b46<nobr>7<wbr></nobr> fc)', 'Madre::Sync::Schema', 'Madre::Sync::Model::padreDB=HASH(0x4db<br>7c64)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Attribute.pm line 398<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(<nobr>0<wbr></nobr> x4b467fc)', 'Moose::Meta::Instance=HASH(0x4db7ed4)', 'Madre::Sync::M<br>odel::padreDB=HASH(0x4db7c64)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Class.pm line 567<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Class/MOP/C<br>lass.pm line 540<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Meta/Class.pm<br>line 256<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x4942ffc)', 'HASH(0x4db53ac)') called at C:\strawberry\perl\vendor\lib/Moose/Object.pm lin<br>e 25<br>#&nbsp; &nbsp; &nbsp; &nbsp;Moose::Object::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at generated method (unknown origin) line 4<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Model::DBIC::Schema::new('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4b404ec)') called at C:\strawberry\perl\vendor\lib/MooseX/<br>Traits/Pluggable.pm line 131<br>#&nbsp; &nbsp; &nbsp; &nbsp;MooseX::Traits::Pluggable::new_with_traits('Madre::Sync::Model::padreDB', 'Madre::Sync') called at C:\strawberry\perl\vendor\lib/CatalystX/Componen<br>t/Traits.pm line 146<br>#&nbsp; &nbsp; &nbsp; &nbsp;CatalystX::Component::Traits::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Cl<br>ass/MOP/Method/Wrapped.pm line 48<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/<nobr>M<wbr></nobr> ethod/Wrapped.pm:49]('Madre::Sync::Model::padreDB', 'Madre::Sync', '<br>HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 89<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Model::DBIC::Schema::COMPONENT('Madre::Sync::Model::padreDB', 'Madre::Sync', 'HASH(0x4c6b93c)') called at C:\strawberry\perl\vendor\lib/C<br>atalyst.pm line 2502<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2502<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup_component('Madre::Sync', 'Madre::Sync::Model::padreDB') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 2416<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP/Method/Wrapped.pm line 54<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::Method::Wrapped::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP/<nobr>M<wbr></nobr> ethod/Wrapped.pm:64]('Madre::Sync') called at C:\strawberry\perl\ven<br>dor\lib/Class/MOP/Method/Wrapped.pm line 89<br>#&nbsp; &nbsp; &nbsp; &nbsp;Madre::Sync::setup_components('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst.pm line 1142<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::setup('Madre::Sync') called at blib\lib/Madre/Sync.pm line 62<br>#&nbsp; &nbsp; &nbsp; &nbsp;require Madre/Sync.pm called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 114<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:118]() called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 74<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 67<br>#&nbsp; &nbsp; &nbsp; &nbsp;Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('C<nobr>a<wbr></nobr> talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a<br>t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call<br>ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S<br>ub/Exporter.pm line 742<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Ca<nobr>t<wbr></nobr> alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per<br>l\vendor\lib/Catalyst/Test.pm line 112<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2<br>#&nbsp; &nbsp; &nbsp; &nbsp;main::BEGIN() called at blib\lib/Madre/Sync.pm line 0<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at blib\lib/Madre/Sync.pm line 0<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval 'package main;<br># use Catalyst::Test @{$args[0]};<br># 1;<br>#<br>#<nobr> <wbr></nobr>;' called at C:/strawberry/perl/lib/Test/More.pm line 858<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p<br>m line 833<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7"Compilation failed in require at C:\strawberry\perl\vendor\lib/Class<br>/MOP.pm line 114.<br>#&nbsp; at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 121<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::__ANON__[C:\strawberry\perl\vendor\lib/Class/MOP.pm:125]('Couldn\'<nobr>t<wbr></nobr> instantiate component "Madre::Sync::Model::padreDB"...') called at<br>C:\strawberry\perl\vendor\lib/Try/Tiny.pm line 98<br>#&nbsp; &nbsp; &nbsp; &nbsp;Try::Tiny::try('CODE(0x36d759c)', 'Try::Tiny::Catch=REF(0x33a9584)') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 125<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_first_existing_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Class/MOP.pm line 137<br>#&nbsp; &nbsp; &nbsp; &nbsp;Class::MOP::load_class('Madre::Sync') called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 24<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::__ANON__[C:\strawberry\perl\vendor\lib/Catalyst/Test.pm:93]('C<nobr>a<wbr></nobr> talyst::Test', 'all', 'HASH(0x36d768c)', 'HASH(0x25de3a4)') called a<br>t C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 493<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_group('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d4994)', 'HASH(0x25de3a4)', 'HASH(0x36d755c)', 'HASH(0x25de334)') call<br>ed at C:\strawberry\perl\vendor\lib/Sub/Exporter.pm line 424<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::_expand_groups('Catalyst::Test', 'HASH(0x36d4ce4)', 'ARRAY(0x36d723c)', 'HASH(0x25de3a4)') called at C:\strawberry\perl\vendor\lib/S<br>ub/Exporter.pm line 742<br>#&nbsp; &nbsp; &nbsp; &nbsp;Sub::Exporter::__ANON__[C:\strawberry\perl\vendor\lib/Sub/Exporter.pm:756]('Ca<nobr>t<wbr></nobr> alyst::Test', '-all', 'HASH(0x36cc8d4)') called at C:\strawberry\per<br>l\vendor\lib/Catalyst/Test.pm line 112<br>#&nbsp; &nbsp; &nbsp; &nbsp;Catalyst::Test::import('Catalyst::Test', 'Madre::Sync') called at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2<br>#&nbsp; &nbsp; &nbsp; &nbsp;main::BEGIN() called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval {...} called at C:\strawberry\perl\vendor\lib/Catalyst/Test.pm line 2<br>#&nbsp; &nbsp; &nbsp; &nbsp;eval 'package main;<br># use Catalyst::Test @{$args[0]};<br># 1;<br>#<br>#<nobr> <wbr></nobr>;' called at C:/strawberry/perl/lib/Test/More.pm line 858<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::_eval('package main;\x{a}use Catalyst::Test @{$args[0]};\x{a}1;\x{a}', 'ARRAY(0x2308474)') called at C:/strawberry/perl/lib/Test/More.p<br>m line 833<br>#&nbsp; &nbsp; &nbsp; &nbsp;Test::More::use_ok('Catalyst::Test', 'Madre::Sync') called at t\01app.t line 7<br># BEGIN failed--compilation aborted at (eval 11)[C:/strawberry/perl/lib/Test/More.pm:858] line 2.</tt></p></div> </blockquote> Alias 2010-07-29T13:23:44+00:00 journal Rakudo Star - an "early adopter" distribution of Perl 6 http://use.perl.org/~pmichaud/journal/40469?from=rss <p>On behalf of the Rakudo and Perl 6 development teams, I'm happy to announce the July 2010 release of "Rakudo Star", a useful and usable distribution of Perl 6. The tarball for the July 2010 release is available from <a href="http://github.com/rakudo/star/downloads">http://github.com/rakudo/star/downloads</a>.</p><p>Rakudo Star is aimed at "early adopters" of Perl 6. We know that it still has some bugs, it is far slower than it ought to be, and there are some advanced pieces of the Perl 6 language specification that aren't implemented yet. But Rakudo Perl 6 in its current form is also proving to be viable (and fun) for developing applications and exploring a great new language. These "Star" releases are intended to make Perl 6 more widely available to programmers, grow the Perl 6 codebase, and gain additional end-user feedback about the Perl 6 language and Rakudo's implementation of it.</p><p>In the Perl 6 world, we make a distinction between the language ("Perl 6") and specific implementations of the language such as "Rakudo Perl". "Rakudo Star" is a distribution that includes release #31 of the Rakudo Perl 6 compiler [1], version 2.6.0 of the Parrot Virtual Machine [2], and various modules, documentation, and other resources collected from the Perl 6 community. We plan to make Rakudo Star releases on a monthly schedule, with occasional special releases in response to important bugfixes or changes.</p><p>Some of the many cool Perl 6 features that are available in this release of Rakudo Star:</p><ul> <li>Perl 6 grammars and regexes</li><li>formal parameter lists and signatures</li><li>metaoperators</li><li>gradual typing</li><li>a powerful object model, including roles and classes</li><li>lazy list evaluation</li><li>multiple dispatch</li><li>smart matching</li><li>junctions and autothreading</li><li>operator overloading (limited forms for now)</li><li>introspection</li><li>currying</li><li>a rich library of builtin operators, functions, and types</li><li>an interactive read-evaluation-print loop</li><li>Unicode at the codepoint level</li><li>resumable exceptions</li></ul><p>There are some key features of Perl 6 that Rakudo Star does not yet handle appropriately, although they will appear in upcoming releases. Thus, we do not consider Rakudo Star to be a "Perl 6.0.0" or "1.0" release. Some of the not-quite-there features include:</p><ul> <li>nested package definitions</li><li>binary objects, native types, pack and unpack</li><li>typed arrays</li><li>macros</li><li>state variables</li><li>threads and concurrency</li><li>Unicode strings at levels other than codepoints</li><li>pre and post constraints, and some other phasers</li><li>interactive readline that understands Unicode</li><li>backslash escapes in regex &lt;[...]&gt; character classes</li><li>non-blocking I/O</li><li>most of Synopsis 9</li><li>perl6doc or pod manipulation tools</li></ul><p>In many places we've tried to make Rakudo smart enough to inform the programmer that a given feature isn't implemented, but there are many that we've missed. Bug reports about missing and broken features are welcomed.</p><p>See <a href="http://perl6.org/">http://perl6.org/</a> for links to much more information about Perl 6, including documentation, example code, tutorials, reference materials, specification documents, and other supporting resources.</p><p>Rakudo Star also bundles a number of modules; a partial list of the modules provided by this release include:</p><ul> <li> Blizkost - enables some Perl 5 modules to be used from within Rakudo Perl 6</li><li> MiniDBI - a simple database interface for Rakudo Perl 6</li><li> Zavolaj - call C library functions from Rakudo Perl 6</li><li> SVG and SVG::Plot - create scalable vector graphics</li><li> HTTP::Daemon - a simple HTTP server</li><li> XML::Writer - generate XML</li><li> YAML - dump Perl 6 objects as YAML</li><li> Term::ANSIColor - color screen output using ANSI escape sequences</li><li> Test::Mock - create mock objects and check what methods were called</li><li> Math::Model - describe and run mathematical models</li><li> Config::INI - parse and write configuration files</li><li> File::Find - find files in a given directory</li><li> LWP::Simple - fetch resources from the web</li></ul><p>These are not considered "core Perl 6 modules", and as module development for Perl 6 continues to mature, future releases of Rakudo Star will likely come bundled with a different set of modules. Deprecation policies for bundled modules will be created over time, and other Perl 6 distributions may choose different sets of modules or policies. More information about Perl 6 modules can be found at <a href="http://modules.perl6.org/">http://modules.perl6.org</a>.</p><p>Rakudo Star also contains a draft of a Perl 6 book -- see "docs/UsingPerl6-draft.pdf" in the release tarball.</p><p>The development team thanks all of the contributors and sponsors for making Rakudo Star possible. If you would like to contribute, see <a href="http://rakudo.org/how-to-help">http://rakudo.org/how-to-help</a>, ask on the perl6-compiler@perl.org mailing list, or join us on IRC #perl6 on freenode.</p><p>Rakudo Star releases are created on a monthly cycle or as needed in response to important bug fixes or improvements. The next planned release of Rakudo Star will be on August 24, 2010.</p><p>[1] <a href="http://github.com/rakudo/rakudo">http://github.com/rakudo/rakudo</a> <br>[2] <a href="http://parrot.org/">http://parrot.org/</a> </p> pmichaud 2010-07-29T12:28:04+00:00 perl6