The Room
How to Automate breaking half of CPAN with Dist::Zilla!
So last night I dropped a new module on to the CPAN. Normally this would be a cause for celebration, except it turns out I broke Moose.
A Date with Destiny
If you don't know local::lib, you should. I've been using it on a per-project level using John Napiorkowski's App::local::lib::helper. This works out incredibly well for those nasty internal projects that have hard dependencies on specific versions of modules, or have dependencies on modules that don't want to talk to each other.
I've been using this so much I have a couple scripts setup to make life easier for myself, I just run use-local-lib and it'll setup a perl5/ directory and setup a subshell to make that the default installation target for things like cpanm.
And because I've been incredibly busy learning new things that are totally unrelated to being a developer, Dist::Zilla has been helping me by making sure things happen the same way every time regardless of how long it's been since I'd done release engineering. It helps prevent issues like this.
With Great Automation comes Great Responsibility
So the stage was set last night. I'd decided to cut a release of my latest module that I'd been working on for a client project so that I could actually use it for that client project. Just fire up dzil release, fix the several issues that cropped up with the Git plugin and get it to ship off the latest dist.
Then I notice that it had shipped my local::lib.
This was made worse by the fact that I happen to have co-maint on a lot of modules that I used on a daily basis. Not that I wrote all of them, just that people (until today) thought I was responsible enough to be a bus number for them. So I had co-maint on large portions of my local::lib.
Crap.
The Fix
The main fix (and the one I didn't do in a timely enough manner) was to run crying to my local PAUSE admin and tell them what I'd done.
What I had done was, immediately when I noticed, issue a delete request for the bad dist, and create a new good dist and upload that. What needed to happen was for a PAUSE admin to force a reindex (and even then doy had to create a new release of Moose) of the affected modules.
Finally, I just needed to teach dzil to prune the perl5 directory so that it never happened again. Adding the following to my dist.ini fixed it.
[PruneFiles]
match = ^perl5
This will make sure that after dzil creates the build directory, it removes the local::lib it copied over from the source directory.
Knowing is Half the Battle
So Dist::Zilla is a huge boon not just to people who manage very large numbers of CPAN dists, it's also nice for people who in-frequently manage CPAN distributions. But with the great power of automation, comes great responsibilty to make sure that it does what you're expecting. I should have taken a minute or two to check that the distribution direction was what I had expected it to be, and when things had blown up I should have gone and talked to someone to make sure that it had been cleaned up properly.
By: Chris Prather on 2012-04-03T13:22:22
Tags:
link
I saw the best minds of my generation...
So there has been a recent post that stirred up some commentary. The basic gist is that the author decided to leave Perl because he got tired of living with the constant scolding over 'use strict'. Something that (as he points out in an update) even Mark Jason Dominus has commented on.
I agree with him. Not about use strict, I actually agree with the people that suggest using more training wheels like strict, warnings, and diagnostics. I think that not only do they help when you're first starting out, they help protect against stupid mistakes when you've been doing this for a decade. No, I agree that the Perl community has managed to make programming less-fun, and I think the comments on his post prove his (and now my) point.
The big reason for leaving Perl, though, was people in the Perl community, who had become annoying scolds.
Most of the comments focus on the 'OMG He is complaining about strict and then using Python!", without pausing for a moment and looking at the deeper issue. As one commenter points out we use strict as a test to identify people who are worthy of our support from those who are un-worthy. We have a lot of these shibboleths, and we can't even agree on them as a community. I've had people file bugs against modules I maintain because they use Module::Install. I've had people file bugs against modules I maintain because they don't use Module::Install. I've watched people get rather nasty in blog posts because an author decided to use Moose, or stop using Moose, or use Mouse, or Moo, or Mo, or M ... well maybe not M.
If we're going to have a reputation for being annoying scolds, we could at least have the decency to come up with an single set of standards to scold people with.
I'd rather however we stop for a minute and remember that there is another developer on the other side of the computer. I've been guilty of ignoring this as much as anybody. But we're not just losing developers like the author of this article. I've had someone who helped me get started in the Perl community tell me that this article sums up the way he feels. That's two people who have had over a deacde in Perl tell me they moved on because Perl stopped being fun. How many people are there that feel this way and don't say anything?
So here's the deal, the next time you feel you need to complain that someone is using Moose, or not using Moose, or using Dist::Zilla, or using Module::Install ... rather than explaining to them how their decision has personally caused you anguish and has been shown in peer reviewed studies to cause cancer in Kittens, stop. Email them, or message them, or whatever and ask them why they chose that path. They may tell you that they didn't know a better way, that they were just trying something new, or that they need more research candidates for their research studies on curing cancer.
If you can't accept their opinion at that point, ask yourself what you can do to help people become better informed on what the appropriate opinions are in the future. If you can't come up with something simple you can do, ask yourself why you can't contribute to making the Perl community better.
Then submit a talk to the next Perl workshop about why you hate kittens.
By: Chris Prather on 2012-02-13T19:05:00
Tags:
link
Perl Oasis 2012
How to organize a conference in your home town, and then not attend!
So last weekend (January 14th specifically) was the 4th Orlando Perl Workshop
aka "Perl Oasis". From the feedback I've seen people generally had an
excellent time. Which is good because I missed most of it.
Friday Night Lights
Friday I taught the Moose course to four excellent students, afterwards we had
a wonderful welcome party that started in the foyer of the conference area and
eventually moved up to the Hospitality Suite that we'd booked for the weekend.
People contributed money towards ordering Pizza and Drinks, and everyone hung
out until around 2am. Or at least thats when I went to bed. Unfortunately
the sleep wasn't to last long.

Take My Breath Away
About 4am my phone rang. I hung up. It rang again and woke me up enough to
notice it was my mother-in-law calling. She was the grandparent we had left my
son with, and if she was calling it probably was important. During the
night our son Eoin had started having breathing issues and had woken them up
coughing and wheezing. He'd reached the point in the night where needed to go
to the ER.
.
Since my wife, Jamie, had partaken a bit more heavily of some of the adult beverages
than she'd intended, I was the one sober enough at 4am to drive across
town to the hospital.
My son has had breathing issues since he was born premature. It has been in
fact the only lasting effect of the time he spent in the hospital after he was
born. So the time I spent on saturday sitting in an ER waiting for his O2
levels to rise to acceptable levels was not unfamiliar. My wife on the other
hand woke up to being the lead organizer for a Perl Conference.
Herding Cats
When my wife showed up at the conference venue (happily downstairs from the
hotel rooms!) she'd discovered there had been a mis-communication between the
staff and the kitchen and the buffet we thought was to be served in the
conference foyer was instead being served in the restaurant ... and involved
coupons we never received and couldn't give to attendees. Recovering from this
only pushed the conference start times back 30 minutes.
The amazing Mark Keating stepped in and helped organize
things. This was familiar to him as he'd only just finished being lead
organizer for the London Perl Workshop. Between him and Jamie they managed to
get talks going and run things until 3pm when my son had been formally
admitted to a hospital for observation and I could return to the hotel and
switch off with Jamie.
It's Almost the End of the Show
I arrived in time to hang out a little bit before the lightning talks started.
Mark again stepped up and provided introductions to the Lighting Talks, and I
got to watch several excellent and enthralling talks. This was only a slight
problem as I was supposed to be timing the talks and giving notice when they
were getting short on time. I got so wrapped up in a few talks I was late
giving the notice and a few of them almost ran over.
After the lightning talks came Cory Watson's
Keynote. I'd asked Cory to give it last year knowing I wouldn't have to worry
about it again. I was proven exactly right, Cory knocked it out of the park.
I'd been approached afterwards by people who were absolutely not technical
people who told me that the talk was excellent. Hopefully he has a chance to
give it again this year at other events! (If you're an organizer this is a
blatant hint.)
Thank You and Good Night
So Perl Oasis 2012 turned out to be a success, despite the organizers hectic
lives. We had 30 attendees from at least three continents again, we had
18 talks over two and a half tracks, and we had 3 excellent sponsors:

My wife and I were so busy this fall that we came into this event thinking
that perhaps it would be our last. We both had so much fun at the event,
despite everything else going on in our lives, that we're ready to go again
next year. Mark Keating has even started recruiting volunteers to help us
organize it again.
By: Chris Prather on 2012-01-20T12:00:00
Tags:
link
Blackjack in 10 Lines of Modern Perl.
There is this thread on Reddit (and StackOverflow) about what's the
coolest thing you can pull off in 10 lines of code. Obviously the first
question people have is how do you define a "line", cause unless you have
significant whitespace issues you can do a lot on a single line.
If you limit yourself to a line is equal to a single idea or step in an
application you restrict things a lot, but it's still amazing what you can
pull off. For example, here's a game of Blackjack in 10 lines of code:
use 5.14.1; use IO::Prompt; use List::Util qw(shuffle);
sub deal { state $shoe = [ shuffle map { my $c = $_; map {"$c$_"} qw(❤ ◆ ♣ ♠) } ( 2 .. 10, qw( J Q K A ) ) x 6 ]; push $_[0], shift $shoe for ( 1 .. $_[1] ); $_[0]; }
sub value { my $v; for ( local @_ = @{ shift() } ) { s/[ ❤ ◆ ♣ ♠ ]//; s/[JQK]/10/; $v < 11 ? s/A/11/ : s/A/1/; $v += $_; } $v; }
sub show { say sprintf "%s (%i)", "$_[0] @{$_[1]}", value( $_[1] ) }
my ( $player, $dealer ) = map { deal( $_, 2 ) } ( [], [] );
while ( prompt( "@$player\nHit? ", '-tyn1' ) ) { if ( value( deal( $player, 1 ) ) > 21 ) { show( "Busted!", $player ); exit; } }
while ( say("Dealer @$dealer") && value($dealer) < 17 ) { show( "Dealer busted!", $dealer ) && exit if value( deal( $dealer, 1 ) ) > 21; }
value($player) >= value($dealer) ? show( "Player wins", $player ) : show( "Dealer wins", $dealer );
Simple no?
Okay so this wasn't the most legible code I've ever written, let's run
Perl::Tidy on it and step through what's going. The first thing you'll notice
is that tidied up the code is 3x longer, but that's still only 30 lines of code.
use 5.14.1;
use IO::Prompt;
use List::Util qw(shuffle);
We start with importing the stuff we'll need, we're going to rely upon David
Golden's work to make ArrayRef's work properly with push/shift. This feature
was introduced in 5.14 we we'll make a hard dependency on that, and also take
advantage of the other modern features this will import (like say and
state).
sub deal {
state $shoe = [
shuffle map {
my $v = $_;
map {"$v$_"} qw(❤ ◆ ♣ ♠)
} ( 2 .. 10, qw( J Q K A ) ) x 6
];
push $_[0], splice($shoe, 0, $_[1]);
$_[0];
}
The second thought, or major chunk, is dealing cards. This little subroutine
is doing a lot in a small space so let's break it out a little.
A deck of cards can be though of as the cartesian product of the values of the
cards (2..10, J, Q, K, A) and the Suits (❤ ◆ ♣ ♠).
We use nested maps to build this cartesian product. We do it for six decks
of cards because that gives the house better odds.
The six decks of cards are shuffled and stored in an ArrayRef inside a lexical
variable. We use a state variable so that we don't build a new shoe every time
we ask for a new card to be dealt.
Finally we actually deal the cards. The hand is passed in as $_[0], and the
number of cards to be dealt is passed in as $_[1]. We just splice off of the
shoe and into the hand.
Now that we have a way to deal hands we need a way to calculate the value of a
hand.
sub value {
my $v;
for ( local @_ = @{ shift() } ) {
s/[ ❤ ◆ ♣ ♠ ]//;
s/[JQK]/10/;
$v < 11 ? s/A/11/ : s/A/1/;
$v += $_;
}
$v;
}
so the hand is passed in via $_[0], since we're going to munge the value we
need to take a local copy of the hand. The idiom local @_ = @_; is what gave
me the basic idea.
Once we iterate through each card in the hand we start by stripping off the
suit since in Blackjack they're all equal. Then if it's a face card (but not
an Ace) we replace it with it's value. Can you spot the bug in the next line?
Aces in Blackjack are a little special, they can be either 1 or 11 depending
which one is to the player's advantage. If the value of the hand is less than
11 we'll want the Ace to be worth 11, if the value of the hand is more than
11 we'll want it to be worth 1. In the real world the value of a hand is the
same irregardless of the order of the cards, Q 2 A and A 2 Q should both
be worth 13, not 23. I spent far too much time trying to figure out how to
make that work here, and couldn't come up with anything simple. Patches
welcome.
Finally we return the running tally.
sub show { say sprintf "%s (%i)", "$_[0] @{$_[1]}", value( $_[1] ) }
We had a common idiom for displaying a hand with some extra information so we
make a simple subroutine here that takes a String and a Hand and prints them
plus the value of the hand to STDOUT.
These last four chunks have all been setup for the main game. The game we've
implemented is a little different from Casino blackjack. I don't play
blackjack at a casino and I'm not a stickler for the rules. I may go through
and clean up this up to be more accurate ... but right now "meh".
my ( $player, $dealer ) = map { deal( $_, 2 ) } ( [], [] );
Deal two cards to the player and the dealer.
Now we let the player choose to Hit or Stay. This line is a little convoluted
so let's dig into it.
while ( prompt( "@$player\nHit? ", '-tyn1' ) ) {
if ( value( deal( $player, 1 ) ) > 21 ) {
show( "Busted!", $player );
exit;
}
}
First we prompt the user what if they want to Hit. If they choose to take
another card check if the value of that new hand is greater than 21. If it is
we tell the player they've busted and quit. Eventually the player will either
bust or quit taking cards, and it'll become the dealer's turn.
while ( say("Dealer @$dealer") && value($dealer) < 17 ) {
if ( value( deal( $dealer, 1 ) ) > 21 ) {
show( "Dealer busted!", $dealer );
exit;
}
}
According to Wikipedia Dealer's in Blackjack are constrained to always draw if the value of their
hand is less than 17. So we draw for the dealer and perform the same check to see if they bust.
Finally if nobody has busted.
value($player) >= value($dealer)
? show( "Player wins", $player )
: show( "Dealer wins", $dealer );
We check to see if the player's hand beats the dealer's hand and show the winner.
All told the original draft of the code took me less than an hour to write,
and the rest of the evening to clean up into something I'd be willing to show
off. It's this kind of thing that keeps me fascinated by programming, and part
of what got me started with it all those years ago.
By: Chris Prather on 2011-12-31T18:00:00
Tags:
link
Future Moose Support
There has been a little bit of noise on twitter about the recent policy decision by the Moose core team. Most of it seems to focus on this line:
Moose will be dropping support for perl 5.8 with the 2.06 release (in January of 2012).
Which is stating that nearly a year after support for 5.10 has been dropped by the core perl development team (i.e. perl5-porters), Moose will be dropping support for the version before that. A version that hasn't been supported by perl5-porters since 5.12.0 was released in April 2010, and which hasn't seen a release since December 2008.
If that was all that Jesse had said in the announcement, I would totally understand the tempest in a teapot. Mojolicious recently went through the same reaction, and I've commented on it previously. It isn't, and people seem to be ignoring the entire paragraph that follows that first sentence.
As for what this actually means: we will not be immediately rushing in to start using smart
matching and ripping out our existing 5.8 compatibility code. The specified version requirement
will stay at 5.8.3. Moose will likely continue to work on perl 5.8 for a good while after next
January. What this does mean, however, is that we will not be spending any more time fixing 5.8-
specific issues. If critical bugs are found (unlikely at this point, but still possible), we
will likely just bump our version requirement if no patch is forthcoming. New features are a
fuzzier topic, but if someone comes along and implements a new Moose feature that requires
features in perl 5.10, that patch will likely be accepted.
This means that the of current Moose core team, all 9 of us, noone has a vested interest in maintaining 5.8 compatibility. It means that if you have a vested interest on Moose working on 5.8, that you will need to step up and help support Moose working on 5.8. It means that if nobody from the community steps up to help out that we'll have assume that the interest in supporting Moose on 5.8 is not a priority.
It also means that if people propose feature requests that utilize 5.10 specific code, and nobody steps up to back-port the feature we'll assume that 5.8 support is not a priority and apply the feature patch.
This is as Jesse has said, how Open Source works.
By: Chris Prather on 2011-05-20T12:50:49
Tags:
link
The Tyranny of Distributions
The Mojolicious team has deprecated Mojolicious on Perl 5.8. Sebastian has a really good argument for doing this, 5.8's regular expression engine is causing security problems. Considering that Perl 5.8 has been deprecated by the core Perl developers, and that 5.10 will be deprecated when Perl 5.14 is released sometime very soon, dropping support for 5.8 really shouldn't be very controversial.
So it's no surprised that he has seen a lot of push-back. The most eloquent critic has been rassie. The point is that some distributions (notably RedHat Enterprise Linux, and CentOS that mirrors it) haven't yet migrated off of 5.8.
A lot of Perl code runs in closed corporate environments and thus has to obey some rules, like
using special software distributions, so [unsurprisingly], a big chunk of those 5.8ers are
enterprise Linux distributions like RHEL or SLES.
The standard response to this is incredulity at using the system Perl for anything. While I fully agree that relying upon the system Perl is itself a security risk, the solution of "Just install perlbrew" leaves a lot lacking. Again rassie states it elegantly:
Nobody in their right mind would have allowed perlbrew on production servers. Nobody in their
right mind would allow me to allocate hours and days of developers’ and testers’ time to
retest everything with the newest Perl version (you don’t seriously assume legacy code had any
amount of reasonable regression tests?)
The standard answer again is to blame the distributions. I know I have complained but as rassie points out modern Perl version simply weren't there when RHEL5 was released.
Perl 5.8 has been released in 2002 and as you see, RHEL3, released a year later, has [caught]
up and delivered 5.8. RHEL4 and RHEL5 have seen minor Perl updates, since no major updates for
Perl came out in that time. Perl 5.10 appeared half a year after RHEL5 released, so it hasn’t
been included, Perl 5.12 has appeared roundabout at the same time as RHEL6 beta, so only 5.10
could have been shipped.
But this obscures the real problem. One that Sebastian points out in the email thread about deprecating Mojolicious on 5.8.
Perl 5.8 is no longer supported by the community, RedHat will keep it
compiling on their platform but nothing more, these bugs will never
get fixed in the 5.8 family. (http://rt.perl.org/rt3//Public/Bug/Display.html?id=49956)
It's wonderful that RedHat has a 7 year support license for RedHat Enterprise Linux. That means absolutely nothing for Perl. RedHat doesn't promise to even maintain security patches for Perl for 7 years. If your company depends upon Perl, the RedHat support license is only half the story.
So what then is the answer? Well the best answer would be for the companies making promises of 7 years of support to actually provide support for those 7 years and to step up and make sure that security patches and what not are applied to Perl 5.8. That isn't going to happen.
An answer could be that firms that depend upon Perl realize that Perl has a separate support license from the Operating System and to employ someone, or hire a company who offers a support license for Perl to maintain Perl 5.8 for however long they need. That probably won't happen either.
The answer is not to blame people who volunteer their time for not being mindful of your distribution environment. To be frank that isn't their problem. The guilt/feel-good motivations of Open Source only work so far. I personally am tempted to drop support for any unsupported Perl version for my own modules (and to recommend to the communities, and clients I work with to do the same). None of those communities has the ability to support deprecated versions of Perl independently. My company certainly doesn't employ anybody with sufficient knowledge to contribute to the current version of Perl, let alone be able to maintain a legacy version of Perl single handedly. So what are we left with?
We do what the Perl core team does (under Jesse Vincent's admirable leadership). We try to maintain compatibility as best we can, while trying to keep things moving forward to be more useful, secure, and robust. This is what Sebastian is doing with Mojolicious.
If you have a need to support a legacy version of any of my modules, I am wildly supportive of you forking that to maintain compatibility with your environment. I don't work in your environment, I'm not motivated by guilt (or money) enough to pretend that I do.
By: chris prather on 2011-05-08T12:39:00
Tags:
link
The PSGI is the Limit
Miyagawa has recently linked to a bunch of forums where he has encountered a lot of push back against PSGI. The argument basically goes "We're using CGI/mod_perl/FastCGI just fine and it works for us, why should we change?" Let me tell you a couple of stories.
For the last year and a half I consulted on a large web application. It was a closed application but based on Catalyst and used mod_perl as a deployment. The site had a decent amount of traffic but with a combination of nginx as a front-end proxy, proper caching, and a CDN the systems we had were handling things just fine.
The lead systems guy was often in the mood to experiment with alternatives to see if we could get better performance out of the cluster of machines that ran the site. Because we happened to be using Catalyst, and thus Catalyst::Engine, we suggested that he try moving to FastCGI and dropping Apache out of the mix. So he took a box out of commission, re-jiggered it and tried it. There was a 30% reduction in the system load.
30% … nearly 1/3 as much load … that meant by just re-tooling our application stack with no actual changes to the code base we could eliminate 1 out of every 3 servers. We saved the company 30% of our hosting costs by simply changing the deployment scenario all because with Catalyst::Engine we could try a new deployment scenario with no effort.
This is where PSGI saves people money. PSGI is the generalization of Catalyst::Engine and HTTP::Engine and several other projects over the years (yes dating all the way back to Apache::Request and Apache::PerlRun which emulated a CGI environment in mod_perl). It de-couples the application deployment logic from the business logic and allows you to perform trivial changes to the deployment.
The second story I wanted to tell you was this. Way back in the day I was playing around learning POE. Someone had written a POE server, POE::Component::Server::HTTP and there was a page on the POE wiki talking about how to run CGI applications under it. The code was incomplete because it didn't really implement the CGI environment, it just did the GET and POST stuff.
So I went and read the Specs for CGI (they're ancient-by-web-standards NCSA webserver documents) and sorted out which pieces needed to be glued into where.
I have to tell you it wasn't difficult but it certainly isn't the most elegant code I've written. The same basic idea was taken on as HTTP::Request::AsCGI and judging by the 14 releases that package has had over the last five years it's not exactly edge-case free.
PSGI as a specification is much simpler to implement for a Perl application than the CGI environment. PSGI is at it's core a subroutine that takes a HashRef and returns an ArrayRef.
Now I hear you crying out that CGI is just that easy, but really it's not. CGI is a pollution of environment variables and a system call (or something that fakes system call that by dumping it's output into STDIN). Tell me honestly as a programmer, which is easier: a subroutine dispatch, or faking a capture of the output of a system call?
So while CGI may be "good enough" for you (hopa!) there are cases where it's not "good enough" for the people implementing the tools. While you may never ever ever move off of CGI, FastCGI or mod_perl, that doesn't mean that something better won't ever be invented. It also doesn't mean that what you're using is the best possible solution for your application, but you'll never know that because you didn't see a reason to abstract your deployment in such a way that you can try out alternatives quickly and easily.
By: Chris Prather on 2011-05-08T03:34:45
Tags:
link
The conversations about documentation of Object Oriented Perl brought up a classic disagreement about the nature of encapsulation. It doesn't help that the term 'encapsulation' is overloaded.
Encapsulation is the wrapping of an object's data, also know as it's state, with guard behavior. This is so the state cannot be easily changed without the object being complicit. Think of it as the warranty sticker on an object, while you can (especially in Perl - through various levels of heroic effort depending on the object data type) violate the encapsulation, you break any guarantees that the object will continue to function as advertised. Just as with a broken seal, or a water damage indicator if we are talking Apple products, you get no guarantees from the manufacturer.
For many people, especially Geeks who are more often prone to violating a warranty as soon as they get the wrappings open. This may sound like a pain and hassle. In many ways it is a hassle, intelligent people should be allowed to take risks and do what they want or need with property they own. Even if that property is a copy of a project released under an Open Source license. On the other hand, the warranty seal really is a savings because you no longer have to worry about your object working correctly. So long as your doing what it says on the box, or documentation, it will do the right thing. If it doesn't you can rightly complain to the manufacturer and expect some level of help.
What then is the other definition of encapsulation, Information Hiding?
It really is just another step further in this same direction. Information hiding says that not only should nobody have a warrant to poke into the private parts of the object( including it's state), nobody even be aware of (or care about) how the inside is implemented.
Let me use an example that came up that I think illustrates it well. An example came up that we use $foo++ to increment the value in $foo. This suggests we should be able to use $obj->foo++ to increment the value of the foo attribute in $obj. With proper overloading and use of lvalues (and possibly ignoring some of the lurking dragons in Perl's implementations of these) it is possible and will keep true to the first definition of encapsulation.
This sounds really reasonable at first, and I admit I thought for a bit "well why not?" But I realized soon enough that what this did is created more work for myself. It meant I and any users of my objects were forced to violate Larry's Law of Laziness.
But, you say, how does it make us less Lazy? It reuses an idiom we already know. The quick dismissal is that you can't handle multiple arguments, for example in a table with cells. This is rightly countered with $obj->get_cell(1,3)++. Really the problem is more subtle.
By making a distinction between state and behavior we are forced us to be aware that similar things are treated differently. Even if we have proper encapsulation and all state is guarded with some behavior, we're still forced to be aware that some thing's behave like values; they increment, decrement, and are assigned with operators; while others will behave like ... well behaviors, that is like methods.
This then is the problem that information hiding is protecting. It means we have a uniform API, and it doesn't matter how the underlying implementation is handled. It means that I am protected from deciding at some future point that a given value is a poor choice and I can re-factor it out. It means that I don't have to play "Language Designer" and worry about how the increment operator plays with pure methods in my objects (what would $obj->book_hotel($client, $hotel)++ mean?). It means in short that I can in fact trust that my warranty is what I claim on the box.
By: Chris Prather on 2011-04-12T14:08:02
Tags:
link
Party like it's 1979
So recently I've been playing Lacuna Expanse more
than I probably should be. It's an interesting game with a lot of other Perl
programmers involved, so the community feeling is very familiar.
One of the things that Lacuna Expanse does that I haven't seen in other games,
not that I game a lot, is they expose their server API fully. This means
not only can you use the official JS/HTML Client, or the iPhone client, or the
Adobe AIR client, but you can write your own scripts to target the API.
Shortly after the game was formed, tsee created
Games::Lacuna::Client.
After that there was an explosion of small Perl scripts doing everything from
building reports of ships in the empire, to doing full automation of your
account through a limited AI "Governor".
Earlier this week in the in-game chat someone suggested there should be a
text-based version of the game. I suspect that the suggestion was in jest, a
text-based client to a Web Based game that has a GUI already is ... well
awesome but silly. It did however get me thinking. With Games::Lacuna::Client
it shouldn't be that hard to write. Two days later...
Well here is a Screen Shot:

Games::Lacuna::MUD
The code is still in developer release mode. It may never get beyond that
point. If you'd like to get started with Games::Lacuna::MUD simply do the
following.
On a box with Perl 5.12.2 installed download a copy of this Games::Lacuna::MUD
either by cloning it or downloading a
tarball.
I'm gonna assume you have CPANMINUS installed. If not it use your own
preferred client or install cpanm from the web.
> curl -L http://cpanmin.us | perl - --self-upgrade
Make sure you have Dist::Zilla installed, this will make installing the dependencies easier.
> cpanm Dist::Zill
Once Dist::Zilla is installed simply do the following to install the dependencies required for Games::Lacuna::MUD
> dzil listdeps | cpanm
Once the dependencies are installed you will need to have a developer API
Key that you can acquire from
this site.
With the developer key you can create a configuration file for Games::Lacuna::Client.
---
api_key: [KEY]
empire_name: [EMPIRE]
empire_password: "[PASSWORD]"
server_uri: https://us1.lacunaexpanse.com/
Save this as $HOME/.le-mudrc and you can start the MUD client with the following
> perl bin/le-mud.pl
Some basic MUD commands work: look, go planet, go building, leave building, quit
Beyond this the commands are still rudimentary. There is no help system
because I wasn't happy with the on that I had and haven't come up with a slick
way of integrating a cross cutting concern like that. You are free of course
to view the source.
I'm really happy with the design of this project, I thought I'd take a few
blog posts to explain some of the tools I used to throw it together in about 2
days of work and how Moose and CPAN really helped make it work quickly and be
fun.
Tags:
link
Perl Oasis 2011
With London Perl Workshop closing up this weekend, I realized So Perl Oasis
2011 is rapidly approaching. It will in
fact be happening January 15th, 2011, and the deadline for Talk Submissions is
December 17th. Worse yet the deadline for booking the hotel rooms with our
discount rate is December 16th!
The call for speakers is open and we have had some speakers submit talks
already on Catalyst, Moose, Javascript, Template::Zoom, MozRepl. However we
need more! Additionally there will be space for a hackathon on the Sunday
after for people who are interested in getting together and working on a
project or two.
The cost for the workshop is $20 USD for non-students, and $10 for students.
Finally for the first year we are offering the Introduction to Moose corporate
training course on January 14th. This class was developed by Dave Rolsky. It
has been presented several times at YAPC's here and in Europe, as well as at
various Perl Workshops around the country. The cost for this course is $180
USD, which for corporate style training is dirt cheap.
I look forward to seeing as many people as possible come!
By: Chris Prather on 2010-12-05T00:00:00
Tags:
link
Traits vs Roles
In natural languages lot of objects have multiple names. For example I
am known on CPAN and IRC as perigrin, I am know to my friends and
family as Chris, to the TSA as David, and to my children as Daddy. Each
of these different names illuminate a different context or role that the
object, me, is thought of or used in.
Recently there was a debate or argument about the concept of Traits vs
Roles in #moose. This has been a issue for a good long
while. Ultimately the answer is that Traits are another name
for Roles. Just as I am both perigrin and Chris, Traits and Roles both
refer to the same concept but with different context or conceptual
baggage allowed.
But this isn't really a satisfying answer for a programmer. Two names
for a single concept isn't very efficient, especially if the
differentiation isn't very concrete. For example Chris vs perigrin is
(in theory) cleanly delineated by Offline vs Online. I think a little
history will help explain the reason that these two names exist and are
adopted by the Moose community.
First the concept of Roles is generally based upon a paper
Traits —Composable Units of Behavior. For this paper they created an
implementation of what we call Roles for Smalltalk 80, and named them
Traits. So outside of the Perl world, Roles are Traits. This is the
first point of confusion.
Next, like many good things in Perl these days, Traits and Roles started
in Perl with Perl6. Roles in Perl6 are effectively identical to Perl5,
however Perl6 has a specialized concept under the name 'traits'.
According to Synopsis 06:
Compile-time properties are called "traits".The is NAME (DATA)
syntax defines traits on containers and subroutines, as part of
their declaration:
constant $pi is Approximated = 3; # variable $pi has Approximated trait
my $key is Persistent(:file<.key>);
sub fib is cached {...}
If you follow the idea that in Perl6 everything is an object, these
traits at compile time modify a given instance. In the examples above
the $pi instance of the constant class is modified to have a
Approximated trait that is set to 3, the $key object is made
persistent to a .key file, and the subroutine instance fib is given
the cached trait for presumably memoization.
Synopsis 6 goes on to state:
Properties are predeclared as roles and implemented as mixins--see
S12.
So at some level in Perl6 Traits are Roles that are applied to
instances. This is the second point of confusion.
Finally in the evolution of Moose we, that is the people in #moose at
the time, originally tended to only refer to Traits to Roles that
applied to metaclass instances. Traits in this case were things like
MooseX::Storage's 'DoNotSerialize'. This trait you can apply to a
attribute and that attribute is skipped when MooseX::Storage does it's
serialization routine. These traits are used all over, MooseX::POE is
implemented as just such a trait. Mostly they do their work hidden in
the Meta Object Protocol.
The logic behind calling these things Traits was two fold, one if you
consider the concept of a trait from perl6 it is conceptually similar to
a Role applied to an instance. and since Metaobjects in Moose are
themselves just instances that define things like Classes, Attributes,
Methods, and Roles the idea of a Role that applies instances being
called a Trait is small step. At the time we didn't have a lot of places
where people generally applied Roles to non-metaobjects instances.
This was before MooseX::Traits was written, before
MooseX::Object::Pluggable (the basis for Devel::REPLs plugin system),
before a lot of things we have now.
So where do we stand now? We have this concept, "a composable unit of
behavior", that has two names: Roles and Traits. Is this confusing? Yes,
somewhat. It's messy and confusing to new people. Is it useful? yes,
somewhat. Just like having multiple names for myself is useful to help
differentiate context, having different names for subtly different
contexts is an "Advanced Feature". Like so much in Perl you can choose
not to use it and refer to everything as a Role, or a Trait, or a
"composable unit of behavior".
By: Chris Prather on 2010-08-11T00:00:00
Tags:
link