最近 Twitter client に Tweetie を使ってます。
広告がたまに表示されるけど、気にならない程度。個人的には一番自分に合う。
iphone の twitter クライアントもつかいやすいのでとても気に入っています。
いけてなかったのが growl に対応していいなかったこと。
それを差し引いても使いやすいからいいんだけど。
そのうち対応するだろうなーとと思ってたら
Tweetie を Growl に対応させる SIMBLE プラグインを発見!!!
Tweetie for MacにGrowlを追加(仮)
これ本当にほしかったから相当うれしい。
同じように Tweetie 使って Growl に表示されない!!って思ってた人は試してみては。
(一時的な急場しのぎのプラグイン(仮)とのことです)
SIMBL プラグインもちょっと試してみたい今日この頃。
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 の方がパースも全体的に速かった。
つっこみなどあればよろしくです。
内容自体はタイトルのまま。
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: 端末の関係上やが使用できない場合があります。そのような環境で
> はと-をそれぞれ代わりに利用できます。
これかな??
ま、これで相当快適になった。
id:dann さんの記事 「snipMateのsnippetが書きやすい件」で snipMate.vim が紹介されてて試してみた。
snipettsEmu.vim は snippets の追加がめんどくさかったってのもあるし
入力がタイポしてたりすると編集後に次の場所に移動できなかったりとか
(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
h1.snippet
この2つの構造は全く同じ意味です。
つまりは filetype ベースで trigger を作成しておけば良いということですね。
少しだけ .snippets の書き方の説明をしておきます。
${1} : 最初に入力する単語。デフォルトのままだと <tab> を入力すると ${2} に移動します。
${1:hoge} : デフォルトで hoge という単語が入力されている状態になります。
$1 : ${1} で入力された値と同期されます。
このように最初のインデントが必須。
trigger.snippets の場合は
このように実際に補完される文字をファイルに書いておけばいいから分かりよい。
ただ、ファイルが増えまくるのもどうかとも思うが。
自分の好きな方で 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
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 でシリアライズの方法が色々あるのでちょっとベンチマークをとってみた。
ちなみに試したのは 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 をシリアライズできないみたい。
ってエラーがでた。