WWW::Curlを使う練習。もともとは LWP::UserAgentを使っていたんですが、
ちょっとでも早くなったらいいかなと思って書き直した。
ネットワークが一番ボトルネックになるから、そんな大差はない
気がするけど、早めにレスポンスが返るときはより早くなったかな
という気分。
まあ XML::RSSを XML::RSS::LibXMLに変えたのが一番効いていそうな
気もしますけど。
何回かベンチマークとってみたけど、結果がバラつきすぎて
いいのか悪いのかよくわからなかった。localhostのファイルを
使ってテストすると差が出るのかもしれないですね。
#!/usr/bin/env perl package Hatena::HotEntry; use Mouse; with 'MouseX::Getopt'; our $VERSION = '0.01'; use WWW::Curl::Easy; use XML::RSS::LibXML; has 'threshold' => ( is => 'rw', isa => 'Int', default => 3, documentation => "threshold of Hatena bookmark", ); has 'limit' => ( is => 'rw', isa => 'Int', default => 10, documentation => "limit of printing entries", ); has '_key' => ( accessor => 'key', isa => 'Str', ); has '_ua' => ( accessor => 'ua', isa => 'WWW::Curl::Easy', lazy_build => 1, ); has '_content' => ( accessor => 'content', isa => 'ScalarRef', ); has '_url' => ( accessor => 'url', isa => 'Str', ); sub _build__ua { my $self = shift; my $curl = WWW::Curl::Easy->new; my @attrs = ("UserAgent: " . __PACKAGE__ . "/$VERSION"); my $content; $self->content(\$content); open my $fh, ">", \$content; $curl->setopt( CURLOPT_WRITEDATA, $fh); $curl->setopt( CURLOPT_HTTPHEADER, [ @attrs ]); $self->_entry_url(); $curl->setopt( CURLOPT_URL, $self->url); $curl; } sub _entry_url { my $self = shift; my $tmpl = 'http://b.hatena.ne.jp/t/#KEY#?sort=hot&threshold=#THRESHOLD#&mode=rss'; my ($key, $threshold) = ($self->key, $self->threshold); $key = uri_escape_utf8($key); $tmpl =~ s{#KEY#}{$key}; $tmpl =~ s{#THRESHOLD#}{$threshold}; $self->url($tmpl); } has '_rss' => ( accessor => 'rss', isa => 'XML::RSS::LibXML', default => sub { XML::RSS::LibXML->new; }, ); has '_infos' => ( accessor => 'infos', isa => 'ArrayRef[HashRef]', default => sub { +[]; }, ); __PACKAGE__->meta->make_immutable; no Mouse; use Carp qw(croak); use Encode; use URI::Escape; sub run { my ($self, $key) = @_; die $self->usage unless defined $key; $self->key(decode_utf8($key)); my $content_ref = $self->_get_content_ref(); $self->_parse_rss($content_ref); $self->_print; } sub _parse_rss { my ($self, $content_ref) = @_; $self->rss->parse($$content_ref); for my $item (@{$self->rss->{'items'}}) { push @{$self->infos}, { title => $item->{'title'}, link => $item->{'link'}, description => $item->{'description'}, }; } } sub _get_content_ref { my $self = shift; my $ret = $self->ua->perform(); croak "Can't download ", $self->url, "\n" if $ret != 0; my $decoded_content = decode_utf8(${$self->content}); \$decoded_content; } sub _print { my $self = shift; my $i = 1; my $limit = $self->limit <= @{$self->infos} ? ($self->limit - 1) :(scalar @{$self->infos} - 1); for my $info (@{$self->infos}[0..$limit]) { printf "%2d: %s\n", $i++, encode_utf8($info->{'title'}); } } package main; use strict; use warnings; unless (caller) { my $app = Hatena::HotEntry->new_with_options(); $app->run(shift @{$app->extra_argv}); }
仕事中にこそこそ起動しています。サボりじゃなくて
情報収集のためです、と言っておきます。
% hotentry.pl perl 1: PlackとText::Xslateでケータイからtwitterするwebアプリを書いた - だるろぐ 2: Net::Amazon の謎 - punitanのメモ 3: split はデフォルトで後続する空フィールドを削除する - daily dayflower 4: Term::ANSIColor::Relaxで愛されモテカワ端末に大変身!? - 愛と勇気と缶ビール 5: vim-ref で perldoc その他を読む - blog.remora.cx 6: colordiffの文字単位版ccdiffを作ったid:yappo++ - ヒルズで働くholidays-lの技ログ 7: Time::Piece::MySQL とタイムゾーン - Yet Another Hackadelic 8: perlstudy 9: WWW::Curl で使えるオプション一覧 - Craftworks Tech Blog - Branch 10: Log::Minimal meets Plack. Log::Minimalを使って環境に適したログ出力を - blog.nomadscafe.jp
速さが重要にならなければ、WWW::Curlを使う必要は僕にはないかなという
印象。LWP::UserAgentでできるあの機能を使うにはって探すのに時間が
かかりすぎる。はじめは LWP::UserAgentで書いて遅かったら置き換えると
いう方針で僕には十分だと思いました。