Hatena::Groupdann

dann's blog このページをアンテナに追加 RSSフィード

Fork me on GitHub

2008-06-29

Catamooseのinterview

| Catamooseのinterview - dann's blog を含むブックマーク はてなブックマーク - Catamooseのinterview - dann's blog Catamooseのinterview - dann's blog のブックマークコメント

http://jjnapiorkowski.vox.com/library/post/catamoose.html

moosecatalystについての、いいinterviewですね。折角なので要点だけまとめておきます。

要点は、以下の5点くらい。

  • Moose
  • NEXT to C3
  • applicationとcontextの分離
  • Moose RoleをPluginに
  • Bread::Boardを拡張のwiringに

特にMoose RoleをPluginにという点とBread::BoardでPlugin(Component含む)郡のwiringにという2点が興味深いなと思いました。

Moose Roleについて

Moose Roles are a good fit for plugins, and will hopefully clarify some of the problems we used to have with people creating Catalyst plugins when that functionality was better off created as a base controller or model.

わかることは、

  • MooseのRoleをPluginとして使うのが適切だ
  • ControllerやModelとして作ったものがよいものについても、MooseのRoleになる可能性があるということ(世間一般でPluginといわれているものではないですが、見え方としてはPluginになるっていうことでしょう)

Bread::Boardについて

Matt Trout clarified the possible use of Bread::Board in a future version of Catalyst: “Bread::Board is going to replace the custom code in setup_components, it's -not- a replacement for the plugin system. Although we may extend Bread::Board to compose class+N roles classes for extensions, sort of like a more large-scale MooseX::Object::Pluggable.”

large-scale MooseX::Object::Pluggableというのは的確な表現だなぁと。複雑なオブジェクトの依存関係を解決してwiringしてやる役割をBread::Boardでもたしてやるって話なわけで、DIコンテナの現実的なユースケースだろうなぁと。

# どこまでがcatamooseの最初のリリースで入るんでしょうね。Moose RoleをPluginにってとこまで入ってくれるといいなぁ。

XIRCDでのMooseX::POEの使い方

| XIRCDでのMooseX::POEの使い方 - dann's blog を含むブックマーク はてなブックマーク - XIRCDでのMooseX::POEの使い方 - dann's blog XIRCDでのMooseX::POEの使い方 - dann's blog のブックマークコメント

MooseX::POEの使い方の例として、XIRCDを少し見てみました。

http://coderepos.org/share/browser/lang/perl/XIRCD/trunk/

以下、メモです

  • Component
    • MooseX::POEを使う
    • new時にPOCO::XXXをspawan
    • POE系の冗長な記述を簡易に書く仕組み
      • Sub::Exporterでpostなどなどをexportする使い方はとても綺麗
      • get_argsも同様に短く書けていい
  • Moose
    • MooseX::Daemonize, MooseX::POE, MooseX::POE::Aliased

ポイントは、以下の3点かなと思いました。 

  • MooseX::POEを使うことでPOE::Sessionうんぬんの記述を無くす事
  • ComponentでPOEの冗長な記述を簡易に記述できるように関数をexportすること
  • MooseX::Daemonizeでdaemonの記述が簡易になっている点

これだけコードがシンプルにできると、POEのコードも少し書いてみようかなぁなどと思えてきます。

id:mikihoshi++

まだ、MooseX::POEは全然触ってないのですが、ぱっと見た感じでは先ほどのやつをMoose化するのは、さほど難しいところはなさそうです。MooseX::POEのコードが読み終わったら移植してみます。

CPANモジュール作成の手順

CPANモジュール作成の手順  - dann's blog を含むブックマーク はてなブックマーク - CPANモジュール作成の手順  - dann's blog CPANモジュール作成の手順  - dann's blog のブックマークコメント

今年はCPANモジュールを何かリリースできればなぁと思っているのですが、CPANモジュール作成の手順を理解していないので少しまとめてみました。

色々と手順は抜けているような気がするので、このステップは絶対にないといけない!とかあったほうがいい!というステップがあれば、是非教えてください。

# id:dayflowerさんにテストが抜けてるよ!というツッコミをもらったので追記してみました。間違いがあればツッコミおねがいします!

# id:dankogaiさんの指摘から、prove -bvについて追記しました。blib

See also:

Shipitでgithubにリリース

Shipitでgithubにリリース - dann's blog を含むブックマーク はてなブックマーク - Shipitでgithubにリリース - dann's blog Shipitでgithubにリリース - dann's blog のブックマークコメント

steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist
git.tagpattern = release-%v
git.push_to = origin

git.tagpatternでtagの付け方を指定、git.pushtoでpushする先を指定といった感じです。これで、tag付けして、commitしてくれます。

初めてshipitを触ってみたのですがこれはリリース手順を簡単に自動化できていいですね。ShipitのStepの拡張も簡単にできそうなので、リリースツールの拡張はShipitベースでやるのがよさそうです。

See also:

http://blog.clouder.jp/archives/001044.html

MooseX::AttributeHelpersでArrayRef、HashRefのアクセッサを簡単に作成する

|  MooseX::AttributeHelpersでArrayRef、HashRefのアクセッサを簡単に作成する - dann's blog を含むブックマーク はてなブックマーク -  MooseX::AttributeHelpersでArrayRef、HashRefのアクセッサを簡単に作成する - dann's blog  MooseX::AttributeHelpersでArrayRef、HashRefのアクセッサを簡単に作成する - dann's blog のブックマークコメント

Moose標準だと、ArrayRefのattributeを作ってそれをラップするメソッドを書く事になりますが、これは面倒です。そんなときに、使うのがMooseX::AttributeHelpersです。

attributeを拡張してくれます。これで、arrayrefにaliasのようなものを追加できるようになります。以下は、urlsのaccessorにurladdするメソッドを提供する例です。

providesに書いたadd_urlというメソッドがarray refのpushに対応します。HashRefなども同様の形で簡単に追加できるので、array, hashへのラッパメソッドを書いている人は、これを使ってみるといいかと思います。


ArrayRefの場合

#!/usr/bin/env perl
use Data::Dumper;

{
  package Crawler;
  use Moose;
  use MooseX::AttributeHelpers;

  has 'urls' => (
      metaclass => 'Collection::Array',
      is        => 'ro',
      isa       => 'ArrayRef[Str]',
      default   => sub { [] },
      provides  => {
          'push' => 'add_url',
      }   
  );  
}

my $crawler = Crawler->new;
$crawler->add_url('http://www.google.co.jp');
$crawler->add_url('http://www.yahoo.co.jp');

warn Dumper $crawler->urls;

実行結果

$VAR1 = [
          'http://www.google.co.jp',
          'http://www.yahoo.co.jp'
        ];

HashRefの場合

#!/usr/bin/env perl
use Data::Dumper;
use Perl6::Say;

{
  package Stuff;
  use Moose;
  use MooseX::AttributeHelpers;
  
  has 'options' => (
      metaclass => 'Collection::Hash',
      is        => 'ro',
      isa       => 'HashRef[Str]',
      default   => sub { {} },
      provides  => {
          'set'    => 'set_option',
          'get'    => 'get_option',            
          'empty'  => 'has_options',
          'count'  => 'num_options',
          'delete' => 'delete_option',
      }
  );
}

my $stuff = Stuff->new;
$stuff->set_option('option1' => 'value1');
$stuff->set_option('option2' => 'value2');

say 'option1 value: ' . $stuff->get_option('option1');
say Dumper $stuff->options;

$stuff->delete_option('option1');
say Dumper $stuff->options;

say 'option nums: ' . $stuff->num_options;
say 'has option?: ' . $stuff->has_options('option2');

実行結果

option1 value: value1
$VAR1 = {
          'option1' => 'value1',
          'option2' => 'value2'
        };

$VAR1 = {
          'option2' => 'value2'
        };

option nums: 1
has option?: 1

POEでIRC bot

POEでIRC bot - dann's blog を含むブックマーク はてなブックマーク - POEでIRC bot - dann's blog POEでIRC bot - dann's blog のブックマークコメント

Yokohama.pmで、kanさんの発表を聞いて、MooseX::POEはなかなか良さそうだと思い、少し使ってみようと思っていたのですが、そもそもPOEのことを全然わかってないので、POE::Component::IRCを使って簡単なbotを作ってみました。

http://github.com/dann/yaircbot/tree/master

bot用のコマンドは、Shell::Amazon::S3で使ったCommand拡張の仕組みを使ったので、Commandは簡単に拡張できるようになっています。YAIRCBot::Command以下にファイルを置けば、Commandが追加できるようになっています。

さて、POEを触ってわかってことですが、

  • Componentはeventをhookするだけで実装できるようになっている。定型処理はcomponent側で実装されている
  • 引数はPOE::Sugar::Argsで。生で扱うと引数がとても汚くなる
  • $poe->kernel->postなどと全体的に処理が長くなる
  • デバッグは、以下のようにしてKernelのデバッグを出しておくと、少しやりやすい
sub POE::Kernel::ASSERT_DEFAULT () {1}
sub POE::Kernel::TRACE_DEFAULT ()  {1}
  • POE::Componenet::IRCをspwanしてから、POE::Kernel->runというのが定型処理

大体処理の流れはわかったので、次はMooseX::POEを使って、Mooooooooooooose化して遊んでみようかなと思ってます。今はお遊びスクリプトですが、最終的にはIRC botを簡単に作る仕組みをMooseベースで作ってみたいかなと。

起動スクリプト

#!/usr/bin/env perl
use strict;
use warnings;
use FindBin::libs;
use YAIRCBot;

my $nick   = 'commandbot';
my $server = 'localhost';
my $port   = 6667;

my $bot = YAIRCBot->new(
    nick   => $nick,
    server => $server,
    port   => $port
);
$bot->run;

__END__

main class

package YAIRCBot;
use Moose;

use POE::Component::IRC;
use POE::Session;
use POE::Kernel;
use YAIRCBot::Component::IRCClient;
use YAIRCBot::CommandDispatcher;

our $VERSION = '0.01';

has 'nick' => (
    isa => 'Str',
    is => 'rw',
);

has 'server' => (
    isa => 'Str',
    is => 'rw',
);

has 'port' => (
    isa => 'Int',
    is => 'rw',
);

sub run {
    my $self = shift;
    POE::Component::IRC->spawn(
        alias  => 'bot',
        nick   => $self->nick,
        server => $self->server,
        port   => $self->port,
    );

    POE::Session->create(
        inline_states => {
            _start     => \&YAIRCBot::Component::IRCClient::irc_start,
            irc_001    => \&YAIRCBot::Component::IRCClient::irc_001,
            irc_public => \&YAIRCBot::Component::IRCClient::irc_public,
            irc_error  => \&YAIRCBot::Component::IRCClient::irc_reconnect,
        }
    );

    POE::Kernel->sig( INT => sub { POE::Kernel->stop } );
    POE::Kernel->run;
}

1;
__END__

Component

r

dayflowerdayflower2008/07/02 09:53>CPANモジュール作成の手順
先生! テストまわりについて書いてありません :)
あと make disttest とか distclean とか realclean とか。

danndann2008/07/02 22:24エントリに追記してみました。間違っている点があれば是非コメントお願いします!

dankogaidankogai2008/07/03 06:51- prove -lv t/hoge.t
+ prove -bv t/hoge.t # でないとXSに対応しない

danndann2008/07/04 03:02ありがとうございます。エントリに追記してみました。