Tweetie を Growl に対応させる SIMBL プラグイン

By admin | 2009年4月27日

最近 Twitter client に Tweetie を使ってます。
広告がたまに表示されるけど、気にならない程度。個人的には一番自分に合う。
iphone の twitter クライアントもつかいやすいのでとても気に入っています。

いけてなかったのが growl に対応していいなかったこと。
それを差し引いても使いやすいからいいんだけど。

そのうち対応するだろうなーとと思ってたら
Tweetie を Growl に対応させる SIMBLE プラグインを発見!!!
Tweetie for MacにGrowlを追加(仮)
これ本当にほしかったから相当うれしい。
同じように Tweetie 使って Growl に表示されない!!って思ってた人は試してみては。
(一時的な急場しのぎのプラグイン(仮)とのことです)
SIMBL プラグインもちょっと試してみたい今日この頃。

Feed をパースするモジュールのベンチをとったまとめ

By admin | 2009年4月21日

Feed(RSS, Atom) 共にモジュールがいっぱいあって何を使えばいいのかいまいちわからない。
というわけで調べるついでにベンチマークをとった。
とったといっても RSSのパース速度の比較
Atomのパース速度の比較 を参考にさせてもらい(ほぼ流用です。。。)
少しだけ比較するモジュールをたして計測してみた。

さっそく結果

[RSS]
                     Rate XML::Feed XML::RSS XML::Simple Data::Feed XML::RSS::LibXML XML::FeedPP XML::LibXML regexp
  XML::Feed        1.68/s        --      -1%        -96%       -96%             -96%        -97%       -100%  -100%
  XML::RSS         1.70/s        1%       --        -96%       -96%             -96%        -96%       -100%  -100%
  XML::Simple      37.9/s     2153%    2128%          --       -18%             -20%        -22%        -89%  -100%
  Data::Feed       46.1/s     2642%    2611%         22%         --              -3%         -5%        -87%   -99%
  XML::RSS::LibXML 47.3/s     2714%    2683%         25%         3%               --         -2%        -87%   -99%
  XML::FeedPP      48.3/s     2771%    2739%         27%         5%               2%          --        -86%   -99%
  XML::LibXML       356/s    21105%   20868%        841%       673%             653%        639%          --   -96%
  regexp           7941/s   472363%  467069%      20871%     17132%           16687%      16356%       2128%     --
 
 
[Atom]
               Rate XML::FeedPP  Data::Feed   XML::Feed   XML::Atom XML::LibXML
  XML::FeedPP 108/s          --        -68%        -69%        -73%        -81%
  Data::Feed  336/s        210%          --         -4%        -15%        -41%
  XML::Feed   352/s        225%          5%          --        -12%        -38%
  XML::Atom   398/s        267%         18%         13%          --        -30%
  XML::LibXML 570/s        426%         69%         62%         43%          --

正規表現は半端なくはやかったです。
さすがって感じ。ただ作るパターンは注意しないといけない。

で、びっくりしたのが XML::RSS がものすごくおそい。。
他にも XML::RSSLite や XML::RSS::Parser も試したが CDATA セクションが入ったりすると
パースエラーを起こしてパースできなくなったりしたんで、今回の対象からははずしました。

やっぱり速いのは XML::LibXML が Atom, RSS ともに圧倒的にはやかったです。
ただ個人的に XPath を書くのはあまりすきではないのがネック。
Atom だと XML::Atom という宮川さんが書かれたモジュールが速い。
ただ名前空間に Atom ってある通り RSS を読み込ませると試した限りパースできなかった。
Atom に最適化してあるからはやいのかな。
XML::RSS::LibXML も RSS に特化してる感じ。

Data::Feed XML::FeedPP XML::Feed の3つが RSS, Atom 共にパースできる。
中でも Data::Feed は id:lestrrat さんが作られてるとのこと。
そして 4/19 にも更新されててメンテもされてる。XML::FeedPP も XML::Feed もメンテはされてる。
ただ XML::Feed は RSS のパースがあまりに遅いので、Data::Feed か XML::FeedPP がいい気がする。
両方ともインターフェースは似てて同じ感覚で使える。あとは好みの問題なんだろーなと。
XML::FeedPP の pod の方が分かりやすいから、最初はそっちで触るのがよいかも。

XML::FeedPP か Data::Feed を使ってれば変なとこではささらない気がする。
あといらない情報が少ない Atom の方がパースも全体的に速かった。
つっこみなどあればよろしくです。

Mac の Vim から Flash のパブリッシュを実行する

By admin | 2009年4月16日

内容自体はタイトルのまま。
id:Htanabee さんの Vim から Flash のパブリッシュを実行する を参考にして試した。
ただ元の記事が Windows を対象にしていたので mac で試してみた。

publish.jsfl はそのまま拝借します。
これだとテストムービの再生。

fl.getDocumentDOM().testMovie();

こっちだとパブリッシュを行います

fl.getDocumentDOM().publish();

あとはこれを .vimrc にかけばおk。
気になるようであればファイルタイプ指定すればおk

nnoremap <buffer> <c-W><cr> :!open -a "Adobe Flash CS4" "/パス/publish.jsfl"<cr>

でパブリッシュの実行をさせたいのだけどなぜか反応しない。
他のキーならちゃんと動くのにorz
原因がわからない。

引用元(http://unkar.jp/read/pc11.2ch.net/software/1106153307#l238)

:h chalice-usage
> NOTE: 端末の関係上が使用できない場合があります。そのような環境で
> はと-をそれぞれ代わりに利用できます。

これかな??

ま、これで相当快適になった。

snippetsEmu から snipMate に移行したまとめ

By admin | 2009年4月14日

id:dann さんの記事 「snipMateのsnippetが書きやすい件」snipMate.vim が紹介されてて試してみた。
snipettsEmu.vim は snippets の追加がめんどくさかったってのもあるし
入力がタイポしてたりすると編集後に次の場所に移動できなかったりとか

<h1>(1)</h1>
(2)

(1)入力後 => (2)に移動といったことをしようとすると html_snippets.vim を書き直す必要があった。
snipMate は sunppets の追加が簡単そうだったので乗り換えてみた。

インストール

snipMate.vim をダウンロードしてきて
.vim ディレクトリ以下で解凍すれば終了。
使い方は snipettsEmu と同じです。

snippetsの構造

$ tree html
snippets
|-- html.snippet <- filetype
 
$ tree html
snippets
|-- html <- filetype
    |-- body.snippet <- trigger
    `-- h1.snippet

html.snippets

snippet body <- trigger
    <body>
        ${1}
    </body>
snippet h1 <- trigger
    <h1>${1}</h1>
    ${2}

body.snippet

<body>
${1}
</body>

h1.snippet

<h1>${1}</h1>
${2}

この2つの構造は全く同じ意味です。
つまりは filetype ベースで trigger を作成しておけば良いということですね。
少しだけ .snippets の書き方の説明をしておきます。

${1} : 最初に入力する単語。デフォルトのままだと <tab> を入力すると ${2} に移動します。
${1:hoge} : デフォルトで hoge という単語が入力されている状態になります。
$1 : ${1} で入力された値と同期されます。

このように最初のインデントが必須。

trigger.snippets の場合は

<h1>${1}</h1>
${2}

このように実際に補完される文字をファイルに書いておけばいいから分かりよい。
ただ、ファイルが増えまくるのもどうかとも思うが。
自分の好きな方で filetype.sunippet もしくはディレクトリ構造に分ければいいと思う。

snippetが複数マッチする場合

この機能がかなり便利。

[dealforest@imac-local] tree html
snippets
|– html
|– doctype
|– HTML.snippet
`– XHTML.snippet

といった構造だとする。
この場合に hoge.html を開き doctype を入力し を実行すると

1. HTML
2. XHTML
Type number and <enter> or click with mouse (empty cancels):

とう画面が表示されるので 2 と入力すると XHTML の snippet が補完される。
ちなみにこれは html.snippets でいうと

snippets doctype HTML
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
    "http://www.w3.org/TR/html4/loose.dtd">
snippets doctype XHTML
     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
     "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

と同じこと。

補完を tab から c-b に変更

.vim/after/plugin/snipMate.vim

-ino <silent> <tab> <c-r>=TriggerSnippet()<cr>
-snor <silent> <tab> <esc>i<right><c-r>=TriggerSnippet()<cr>
+ino <silent> <c-b> <c-r>=TriggerSnippet()<cr>
+snor <silent> <c-b> <esc>i<right><c-r>=TriggerSnippet()<cr>

.vim/plugin/snipMate.vim

s/<tab>/<c-b>/

document には.vim/after/plugin/snipMate.vim だけ変更するといけるって書いてるけどそれだけじゃ駄目。
.vim/plugin/snipMate.vim の方も変更してやらないとたまに動かなくなるので注意。
<tab> ってハードコードされてた。。。。

tips

コマンド実行

snippet date
    `system("date +%Y-%m-%d")`

ファイル名に変換

snippet constructor
    public `Filename()`() {
    }

こんなことも可能。おほー

TT, perl の snippet を移行した

snippetsEmu で使わせてもらってた snippet を、せっかくなんでそのまま snipMate に移行しました。
ちなみに使用していた snippet は CatalystとTT用snippetsEmu.vim設定 です。
id:spiritloose さんのスニペットには本当にいつも助けられていました。感謝感謝。

tt2.snippet

snippet class
	[% USE ${1:class} = Class('${2:ClassName}') %]
	${3}
snippet url
	[% USE ${1:name} = url('${2:path}') %]
	${3}
snippet linkto
	<a href="[% c.uri_for('${1:path}', ${2:param}) %]¥">${3:label}</a>
	${4}
snippet if
	[% IF ${1:condition} -%]"
	${2}
	[% END -%]
	${3}
snippet ife
	[% IF ${1:condition} -%]
	${2}
	[% ELSE -%]
	${3}
	[% END -%]
	${4}
snippet ifee
	[% IF ${1:condition1} -%]
	${2}
	[% ELSIF ${3:condition2} -%]
	${4}
	[% ELSE -%]
	${5}
	[% END -%]
	${6}
snippet unless
	[% UNLESS ${1:condition} -%]
	${2}
	[% END -%]
	${3}
snippet for
	[% FOR ${1:var} = ${2:list} %]
	${3}
	[% END -%]
	${4}
snippet foreach
	[% FOREACH ${1:var} = ${2:list} %]
	${3}
	[% END -%]
	${4}
snippet while
	[% WHILE (${1:var} = ${2:rs}.next) -%]
	${3}
	[% END -%]
	${4}
snippet switch
	[% SWITCH ${1:var} -%]
	${2}
	[% END -%]
	${3}
snippet case
	[% CASE ${1:var} -%]
	${2}
snippet include
	[% INCLUDE '${1:file}' %]
	${2}
snippet process
	[% PROCESS '${1:file}' %]
	${2}
snippet macro
	[% MACRO ${1:name}(${2:arg}) BLOCK %]
	${3}
	[% END %]
	${4}
snippet var
	[% ${1:var} %]
	${2}
snippet hvar
	[% ${1:var} | html %]
	${2}
snippet hlvar
	[% ${1:var} | html | html_line_break %]
	${2}
snippet null
	[%- FILTER null -%]
	${1}
	[%- END -%]
	${2}

perl.snippet

#perl
snippet dump
	use Data::Dumper; warn Dumper ${1:$var};
	${2}
snippet say
	print ${1:$var}, "¥n";
	${2}
snippet self
	my $self = shift;
	${2}
snippet data
	my $data = do {
		local $/;
		<data>
	};
	${1}
snippet argf
	while (<>) {
		chomp;
		${1}
	}
	${2}
snippet isa
	if (blessed ${1:$var} and ${2:$var}->isa('${3:Class}')) {
		${4}
	}
	${5}
snippet readcsv
	use IO::File;
	use Text::CSV_XS;
 
	my $fh = IO::File->new('${1:filename}') or die 'cannot open file.';
	my $csv = Text::CSV_XS->new({ sep_char => "¥t", binary => 1 });
	until ($fh->eof) {
		my $cols = $csv->getline($fh);
		unless ($cols) {
			warn $csv->error_diag;
			next;
		}
		my (${2}) = @$cols;
	}
	$fh->close;
	${3}
 
#class-C3
snippet next
	$self->next::method(@_);
	${1}
snippet maybe
	$self->maybe::next::method(@_);
	${1}
 
#Catalyst
snippet debug
	$c->log->debug('${1:[ debug ]}: '. ${2:$var});
	${3}
snippet warn
	$c->log->warn('${1:[ warn ]}: '. ${2:$var});
	${3}
snippet dumper
	$c->log->dumper('${1:[ dumper ]}: '. ${2:$var});
	${3}
snippet model
	$c->model('${1:model}')
	${2}
snippet view
	$c->view('${1:view}')
	${2}
snippet template
	$c->view('View::TT')->template('${1:name}');
	${2}
snippet config
	$c->config->{${1:name}}
	${2}
snippet controller
	sub ${1:func} : ${2:Attribute} {
		my ($self, $c) = @_;
		${3}
	}
	${4}
snippet begin
	sub begin : Private {
		my ($self, $c) = @_;
		${1}
		1;
	}
	${2}
snippet auto
	sub auto : Private {
		my ($self, $c) = @_;
		${1}
		1;
	}
	${2}
snippet detach
	$c->detach('${1:name}');
	${2}
snippet forward
	$c->forward('${1:name}');
	${2}
snippet stash
	$c->stash->{${1:var}}${2}
snippet flash
	$c->flash->{${1:var}}${2}
snippet session
	$c->session->{${1:var}}${2}
snippet sstash
	$c->stash->{${1:var}} = ${2};
	${3}
snippet sflash
	$c->flash->{${1:var}} = ${2};
	${3}
snippet ssession
	$c->session->{${1:var}} = ${2};
	${3}
snippet rs
	$c->model('DBIC::${1:Source}')
	${2}
snippet redirect
	$c->res->redirect($c->uri_for('${1:uri}'));
	${2}
snippet param
	$c->req->param('${1:param}')
	${2}

snippetsEmu の不便だったとこがなくなったー
相当快適になった。
ただどうしても分からなかったのが外部で定義した snippet を include するやり方がわからなかった。
そのため .tt の場合には filetype を tt2.html とすることで回避した。

perl でシリアライズのベンチマークをとってみた

By admin | 2009年4月10日

Perl でシリアライズの方法が色々あるのでちょっとベンチマークをとってみた。
ちなみに試したのは Storable, FreezeThaw, Data::Dumper, XML::Dumper の4つ。
結果だけを先にいうと一番のおすすめは Data::Dumper でファイルに出力し、eval するのが一番よさげ。

ベンチマークをとったコード(シリアライズ)

#!/usr/bin/perl
 
use strict;
use warnings;
use Benchmark qw/cmpthese/;
 
use Storable;
use FreezeThaw;
use Data::Dumper;
use XML::Dumper;
 
$| = 1;
 
package Human;
use base qw/Class::Accessor::Fast/;
__PACKAGE__->mk_accessors( qw/name email key/ );
 
package main;
 
my $human = new Human();
$human->name('dealforest');
$human->email('dealforest.net@gmail.com');
 
open my $store, '>', 'store';
open my $dumper, '>', 'dumper';
open my $freezethaw, '>', 'freezethaw';
open my $xml, '>', 'xmldumper.xml';
 
my $dump = new XML::Dumper;
 
cmpthese(50000000 ,{
        dumper => &data_dumper,
        store_fd => &storable_store,
        freeze => &freezethaw_freeze,
        pl2xml => &xmldumper_pl2xml,
});
 
close $store;
close $xml;
close $dumper;
close $freezethaw;
 
sub storable_store {
    Storable::store_fd $human, $store;
}
 
sub data_dumper {
    print $dumper Dumper $human;
}
 
sub freezethaw_freeze {
    print $freezethaw FreezeThaw::freeze $human;
}
 
sub xmldumper_pl2xml {
    print $xml $dump->pl2xml($human);
}
 
1;

ベンチマークの結果(シリアライズ)

                Rate   pl2xml   freeze   dumper store_fd
pl2xml    68493151/s       --     -29%     -41%     -51%
freeze    96153846/s      40%       --     -17%     -31%
dumper   116279070/s      70%      21%       --     -16%
store_fd 138888889/s     103%      44%      19%       --
 
(※)ベンチの結果はカオスなくらい毎回かわりますw
そのためどらが一概にはやいのか良くわからいです。。。
平均的にみたらこれかなってのをだしてます。

ベンチマークをとったコード(デシリアライズ)

#!/usr/bin/perl
 
use strict;
use warnings;
use Benchmark qw/cmpthese/;
 
use Storable;
use FreezeThaw;
use Data::Dumper;
use XML::Dumper;
 
$| = 1;
 
my $xmldump = new XML::Dumper;
 
cmpthese(100000, {
        dumper => sub {
            open my $fh, '<', 'dumper';
            my @a = <$fh>;
            my $VAR1;
            eval(join '', @a);
            close $fh;
        },
        fd_retrieve => sub {
            open my $fh, '<', 'store';
            Storable::fd_retrieve($fh);
        },
        freeze => sub {
            open my $fh, '<', 'freezethaw';
            my $a = <$fh>;
            FreezeThaw::thaw($a);
            close $fh;
        },
        pl2xml => sub {
            open my $fh, '<', 'xmldumper.xml';
            my @a = <$fh>;
            $xmldump->xml2pl(join '', @a);
            close $fh;
        },
    }
);
 
1;

ベンチマークの結果(デシリアライズ)

               Rate      pl2xml      freeze      dumper fd_retrieve
pl2xml       2703/s          --        -71%        -81%        -90%
freeze       9183/s        240%          --        -35%        -66%
dumper      14025/s        419%         53%          --        -47%
fd_retrieve 26667/s        886%        190%         90%          --

まとめ

シリアライズするコストはどれも似たような感じ。
デシリアライズのコストは意外に XML::Dumper がはやかった。
Storable がおそかったのは少しびっくりした。

デシリアライズのコストは Storable が一番。その次に Data::Dumper がはやかった。
ただ XML::Dumper は文字データしか扱えない。バイナリ絡むと無理。
FreezeThaw も若干微妙。

その辺で一番便利だったのが Data::Dumper だった。
swfをパースしたインスタンスでも復元できた。
つまりは Data::Dumepr を選んどくとが一番幸せになれそう。

追記: 2009-04-10T03:18:27+00:00
Storable は GLOB をシリアライズできないみたい。

Can't store GLOB items

ってエラーがでた。

WordPress Themes