Perlの最近のブログ記事

先日メインで使ってるDoCoMoのフィーチャーフォンをGalaxy Nexusに機種変したのですが、それまでiPhoneで受け取っていたim.kayac.comの通知をAndroidでも受け取りたくなったのでどういう方法があるのか調べてみました。

im.kayac.comはGoogle Talk(Jabber)でも通知ができるので、やるとしたらその方向しかないんだろうなぁと思いつつググってみると案の定Google Talkのアプリで通知を受け取るっていう記事がいくつかみつかりました。

でも、なんか「素のGoogle Talkで通知を確認するのはなんかクールじゃない!」

と思っちゃったので、それ以外の方法ないのかといろいろ探してみたらみつかりました。
(みつかったというかアプリを利用して足りない部分は自分で作ったんですが...)

簡単に方法を説明しちゃうと、自前でXMPPのクライアントを立てて、im.kayac.comからの通知を「Notify My Android」っていうNotify専用のアプリに流すという方法です。

簡単に書くとこんな感じ。
[im.kayac.com] -> [XMPP client] -> [Notify My Android]


ちなみにNotify My Androidは有料です。
有料だけど、今回この実装をやってみたら買う価値はあるかなと。
缶ビール2本我慢すれば買える値段ですし(※お酒はあまりのみませんが!)。

ってことで手順を説明します。

  • AndroidマーケットでNotify My Androidを購入し、Notify My Androidのサイトでアカウント登録とAPI Keyの発行を済ませておく。
  • 以下のスクリプトを使って、im.kayac.comのGoogle Talkのアクティベーションします。
    実行にはAnyEvent::XMPPのインストールと、pitを使ってgtalkって名前で設定(usernameとpassword)を追加しておく必要があります。

    実行は引数にim.kayac.comで発行されたアクティベーションコードを渡すだけ。
    % ./register.pl アクティベーションコード
    session ready at ./register.pl line 27.
    connected at ./register.pl line 31.message from api@im.kayac.com/123456: Your jabber account has been activated! at ./register.pl line 36.
  • あとは以下のスクリプトを起動するだけです。
    実行にはWebService::NotifyMyAndroidのインストールと、pitを使ってnma(Notify My Androidの略)って名前で設定(apikey)を追加しておく必要があります。

    実行は普通に以下な感じ。
    % ./server.pl &
    ちなみに、
    request to https://nma.usk.bz/publicapi/verify?apikey=YOUR_API_KEY failed at ./server.pl line 19
    とかでる人はLWP::Protocol::httpsが入ってないからだと思います。
これでサーバさえちゃんと動いてたら、Notify My Androidに通知が来るはずです。 興味ある方がいたらやってみてください。
Yokohama.pm #8で「Plack on SL4A」というタイトルでLTしてきました。

実はこの話は元ネタがあって、去年のperl.krのAdventカレンダーで紹介されていたものを実践してみたものになっています。

本当は、これを元にAmon2などのフレームワークを動かしたかったのですが、XS依存の問題があってそのXSモジュールをインストールしようと頑張ったのですが、どうしてもインストールできなかったため今回のPlackのインストールまでの話になってしまいました。

もうちょっとだけSL4AでXSを動かせるか試してみたいと思っていて、進捗があったらここでお知らせしたいと思います。

ちなみにSL4AのXSのmakeできない問題は、すでにSL4AのIssueに上っていて、このIssueの最後の方のポストでgithubのPerlのブランチを切って書き換えたやつでビルドできたという話が出ているのですが、ARMのクロスコンパイル環境を用意してやってみたもののうまくいなかいんですよねぇ...。
GNU Parallelがすごすぎて生きるのがつらいを見て使ってみました。

そもそも複数のサーバのaccess_logをtail -fで一括で見たかったからです。

GNU Parallelからダウンロードして
% ./configure
% make
% make install
でインストールは終了。簡単!

Perlで書かれてるんでコンパイルとか必要ないっす。

インストールしたら目的のサーバ群に対して tail -f /path/to/access_log を発行するだけ。
% parallel -u ssh {} 'tail -f /path/to/access_log' :::: /path/to/server_list.txt
こうするとserver_list.txtに列挙されてるサーバに対してtail -f /path/to/access_logが実行されます。

-u っていうオプションを付けないと出力がバッファリングされちゃうので、tail -f するときは -u を付けないとだめです。

ちょっと引数にクセがあるけど慣れですね。
マニュアルは man parallel で見られます。

他にもこういうのあるけど、Perlで書かれてて使い易かったのでしばらく使ってみようと思います。
MacBook Airの11インチを遅ればせながら購入したclouderです、こんにちは。

購入したその日にさっそく開発環境を整えようとXcode4を入れて、iPhoneアプリ開発を...と思いきや、Perlの開発を始めたんですが、いくつかのCPANモジュールがインストール(コンパイル)できないのに気付きました。

コンパイル時のエラーは以下のようなもの。
lipo: can't open input file: /var/tmp/hoge.out (No such file or directory)
どうやらXSなどのコンパイルが必要なモジュールでこの現象がおこっているようです。いろいろ調べてみたら、コンパイルオプションに「-arch ppc」があるのにppcのアーキテクチャのファイルが適切な場所にないからエラってしまうようです。

なんでだよーと思いつつ、Xcode4のREADMEを見たら以下のような記述を発見。

Xcode 4 does not support developing for PowerPC; you must continue to use Xcode 3.2.6 to develop applications for the PowerPC architecture. The Custom Install section below has instructions to install both Xcode 4 and Xcode 3.2.6 on the same Mac.

「Xcode4じゃPowerPCのサポートしないぜよw」って書いてありますね。

どうしようかなぁと思いつつ、その後もいろいろ調べてみたらこれに対する解決方法を2つ発見しました。

1つはppcのアーキテクチャを無視してx86_64とi386だけでコンパイルしちゃう方法で、もう1つは(実は入っている)ppcのアーキテクチャのファイルを適切な場所に置いてしまうという方法があります。

1つ目は、以下の環境変数を設定してコンパイルする方法。
ARCHFLAGS='-arch i386 -arch x86_64'
これをドットファイルに設定するとか
$ env ARCHFLAGS='-arch i386 -arch x86_64' perl Makefile.PL
とかすると問題なくコンパイルできます。
この方法は「perldoc perlmacosx」っていうpodに書いてあります。
こんなpodがあったんですね!知らなかったよ。

そして、もう1つの方法は「Xcode4でPowerPC」に書いてありました。
適切な場所に(実はインストールされている)ppcのアーキテクチャのファイルのシンボリックリンクをはるという方法です。
$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /Developer/usr/libexec/gcc/darwin/
$ sudo ln -s /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gcc/darwin/ppc /usr/libexec/gcc/darwin/
どっちでも好きな方でいいと思うんだけど、個人的には後者の方法で対応しました。

なお、この現象はXcode4が出る以前にXcodeをインストールしていた環境ではおこらないので、特定の人しかこの問題に遭遇しないかもしれません。

困っている人がいたら、どっちかを試してみてください。

Perl CPANモジュールガイド - 冨田尚樹 CPAN本、献本頂きました!

ちょっと前に存在は知っていたのですが、4/8ついに出版ということで、tomi-ruさん、誠におめでとうございます!

内容としては、PerlのCPANモジュールを1コ1コ丁寧に紹介する内容となっていて、各カテゴリ毎にそのカテゴリで有名だったりよく使われるモジュールをわかりやすく説明するといったものになっています。

僕がいつもPerlのモジュールを探すときは、CPANの検索で有象無象のモジュールの海を泳いで、これはどうだろうってドキュメントやソースを見てみたり、もしくは「Perl やりたいこと」とかでぐぐって探したりということをやっていたりしましたが、これからはまずこの本でよさげなモジュールがないかを見てからになりそうです!

自分は本を1冊書いたことはないのですが、個人的に書く大変さはちょっとだけ知っていたりするので、これだけの分量のものを書くのはかなり大変だったんだろうなぁと想像しています。

tomi-ruさん、ほんとうにお疲れ様でした。
熟読させて頂きます。

Perl CPANモジュールガイド
冨田尚樹
ワークスコーポレーション
売り上げランキング: 3184
いつも忘れちゃうのでメモ。

UNIVERSAL::isaは、UNIVERSAL::isa()を呼んでも自分のクラス(階層)内にisa()が定義されてればそっちを呼ぶようにするためのモジュール。

以下のようにmainでUNIVERSAL::isaをuseしないと、最後の2つのUNIVERSAL::isa()は1を返します。つまり本当のUNIVERSAL::isa()が呼ばれる。
package A;

sub new { bless {}, shift }
sub isa { "hoge" }

package B;

use base qw( A );

sub new { bless {}, shift }

package main;

my $b = B->new;

warn $b->isa( "B" );            # hoge
warn $b->isa( "A" );            # hoge
warn UNIVERSAL::isa( $b, "B" ); # 1
warn UNIVERSAL::isa( $b, "A" ); # 1

これに対して、以下のようにmainでUNIVERSAL::isaをuseしてやると、最後のUNIVERSAL::isa()もhogeを返す、つまりクラスAで定義されてるisa()が呼ばれている。
package A;

sub new { bless {}, shift }
sub isa { "hoge" }

package B;

use base qw( A );

sub new { bless {}, shift }

package main;

use UNIVERSAL::isa;

my $b = B->new;

warn $b->isa( "B" );            # hoge
warn $b->isa( "A" );            # hoge
warn UNIVERSAL::isa( $b, "B" ); # hoge
warn UNIVERSAL::isa( $b, "A" ); # hoge
そしてUNIVERSAL::canも同じようなことをしてくれます。

ちなみにUNIVERSAL::requireはぜんぜんこれらとは関係なく
Module->require;
って呼べたり
Module->require or die "Cannot required";
とかdieできたり、モジュールでrequireメソッドを使えるようにするものです。
useもできたりします。
仕事でアプリのボトルネックを探しているという話をしたら、hideokiさんが

「YAPC::Asia 2010 で cho45 が紹介してた Devel::KYTProf がいいよー」

って言ってたので、使ってみたらだいぶよかったのでご紹介。

Devel::KYTProfの作者はid:onishiさんで、リポジトリはhttp://github.com/onishi/perl5-devel-kytprofにあります。

このモジュール、何ができるモジュールかっていうと(まぁcho45さんの発表動画見ればわかるのですが)、モジュール名とメソッド名を指定してやると、そのメソッドの処理にかかった時間をさくっと調べられるというものです。

たとえば Foo::Controller::Bar の baz() って関数の処理時間が知りたかったら、そのアプリケーションのメインモジュールに
use Devel::KYTProf;
Devel::KYTProf->add_prof( 'Foo::Controller::Bar', 'baz' );
って書くことで、STDERRに
123.456 ms [Foo::Controller::Bar] baz() | Devel::KYTProf:100
みたいな感じで処理時間とちょっとした情報が出力されます。よっぽどトリッキーなことしてるモジュールじゃない限り、これを使うことで処理時間を調べることができるはず。

あとadd_prof() は、第3引数を渡すことができて
Devel::KYTProf->add_prof(
    'Foo::Controller::Bar',
    'baz',
    sub {
        my ( $orig, $self ) = @_;
        return $self->foo_bar;
    }
);
とやると処理時間と共に$self->foo_bar の値がSTDERRに出力されます。

それ以外にも Devel::KYTProf->threshold( 100 ) とかやると、指定したものよりも処理時間がかかったもののみを出力するようにしたりと、いくつかのオプションが用意されています。

ちなみに Devel::KYTProf は、デフォルトでIO関係でよく問題になるようなDBI、LWP::UserAgent、Cache::Memcached::Fast、MogileFS::Clientなどのモジュールの設定が最初からされていたりします。それ以外にも調べたいという場合に上記の設定を自分でしたらよいという感じになっています。

なお今回、僕の場合はTTの[% foo %]の部分の速度が調べたかったので
Devel::KYTProf->add_prof(
    'Template::Stash::XS',
    'get',
    sub {        my ($orig, $self, $ident, $args) = @_;
        return ref $ident eq 'ARRAY' ? join(",", @$ident) : $ident;
    }
);
こんな感じにしてみました。
まぁ、結局問題はそこじゃなかったんですけどね...。

ということで、このDevel::KYTProfはかなりお手軽に細かい処理時間が調べられるので興味ある方は一度使ってみてはいかがでしょうか。
仕事で学年毎の生年月日の範囲が必要になって、CPANを探したけどそれらしいのがなかったのでモジュールではないけど作った。

この辺は国によって違ったりするからモジュールにするのってけっこう難しいですよね。ニーズがあればそれらしいモジュールにして出そうかなと思うけど、まぁ、ないよね...。

タイトルの問題ですが、自分はよく以下のような関数でやります。
HTML::TreeBuilderのas_HTML()がうまいことやってくれます。
(実際にはHTML::Element::as_HTML()ですが)
sub _complement_html {
    my $broken_html = shift;
    my $html = do {
        no strict 'refs';
        no warnings 'redefine';
        local *HTML::Entities::encode_entities = sub {};
        local *HTML::Entities::decode = sub {};
        my $tree = HTML::TreeBuilder->new;
        $tree->parse( $broken_html );
        $tree->as_HTML;
    };
    $html =~ s#<html><head></head><body>##g;
    $html =~ s#</body></html>##g;
    $html =~ s#<div>(?:\&nbsp;)?</div>##ig;
    return $html;
}
この関数を使って
<div align="right">foo<font color="#000000">black text
のような閉じてないタグをもったHTMLを渡すと
<div align="right">foo<font color="#000000">black text</font></div>
こんな感じに補完してくれます。

もっと良い方法あるんですかね。
あったら教えて欲しいっす。
% ack --thpppt foo lib
_   /|
\'o.O'
=(___)=
   U    ack --thpppt!
--help みたら --thpppt ってのがあったのでなんだろうと思ったら、こんなのがでた。
それだけです。

検索

広告

月別 アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.12