Perl 5.13.2 がもたらした package NAMESPACE BLOCK 構文があたえるもの
開発版の Perl 5.13.2 がリリースされたが、5.13.2 の目玉はなんといっても package NAMESPACE BLOCK 構文だろう。
use 5.13.2;
use warnings;
package Point {
use Moose;
has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');
__PACKAGE__->meta->make_immutable;
no Moose;
};
のように、パッケージを宣言することができるようになった。
この構文は非常に大きい変化をもたらす。
1 ファイルに複数のクラスを書くことが苦でなくなる。package NAME BOCK 構文を利用する場合、BLOCK の中はインデントすることになるため、複数パッケージを1つのファイルにかくことが苦ではなくなってくる。
もう一つは、あのいまわしき "1;" が必要なくなるということ。package NAME BLOCK 構文は true value をかえしているので、通常のクラスを利用する場合には明示的に 1; とかく必要がないようだ(これが明示的な仕様かどうかはまだみてない)。
今迄、ちょっとしたクラスをつくるときに、以下のようにかいていたのも、すっきりするでしょう。
{
package Foo::Bar;
}
これを利用して、Tatsumaki の eg/demo.pl を書きなおすと以下のようになる。
今迄の Perl5 コードよりも、見通しがいいんじゃないかとおもう。
#!/usr/bin/perl
use 5.13.2;
use warnings;
use Tatsumaki::Error;
use Tatsumaki::Application;
use Tatsumaki::HTTPClient;
use JSON;
package MainHandler {
use parent qw(Tatsumaki::Handler);
sub get {
my $self = shift;
$self->write("Hello World");
}
}
package StreamWriter {
use parent qw(Tatsumaki::Handler);
__PACKAGE__->asynchronous(1);
sub get {
my $self = shift;
$self->response->content_type('text/plain');
my $try = 0;
my $t; $t = AE::timer 0, 0.1, sub {
$self->stream_write("Current UNIX time is " . time . "\n");
if ($try++ >= 10) {
undef $t;
$self->finish;
}
};
}
}
package FeedHandler {
use parent qw(Tatsumaki::Handler);
__PACKAGE__->asynchronous(1);
sub get {
my($self, $query) = @_;
my $client = Tatsumaki::HTTPClient->new;
$client->get("http://friendfeed-api.com/v2/feed/$query", $self->async_cb(sub { $self->on_response(@_) }));
}
sub on_response {
my($self, $res) = @_;
if ($res->is_error) {
Tatsumaki::Error::HTTP->throw(500, $res->status_line);
}
my $json = JSON::decode_json($res->content);
$self->response->content_type('text/html;charset=utf-8');
$self->write("<p>Fetched " . scalar(@{$json->{entries}}) . " entries from API</p>");
for my $entry (@{$json->{entries}}) {
$self->write("<li>" . $entry->{body} . "</li>\n");
}
$self->finish;
}
}
use File::Basename;
my $app = Tatsumaki::Application->new([
'/stream' => 'StreamWriter',
'/feed/(\w+)' => 'FeedHandler',
'/' => 'MainHandler',
]);
if (__FILE__ eq $0) {
require Tatsumaki::Server;
Tatsumaki::Server->new(port => 9999)->run($app);
} else {
return $app;
}
Published: 2010-06-23(Wed) 22:41