つれづれ日記
ぶいよんブイロク?
GA | GW | G | A / amL | S | つれづれ日記 RSS: RDF Site Summary
最新 | 2010年 8月 7月 6月 5月 4月 3月 | もっと前 [ 携帯版 | IPv6版 ]
この日記はよしいまいち コメント

Fedora Schedule 14によると、リリースが1週間ずれて、11月2日の予定 とのこと

Fedora Schedule 14によると、リリースが1週間ずれて、11月2日の予定 とのこと 。F14はPerl 5.12になるので、ちょっと期待している。 Perlも含めFedora 14はインフラ系が多いので、インフラリリース、 という感じ。
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月31日(火)| はれ | 3/3 | カテゴリ: Perl Fedora 14

MIME::Toolsの取説 (perldoc MIME::Tools)には テキストで図が入っていてびっくりした 。複雑だった。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月31日(火)| はれ | 1/3 | カテゴリ: Perl

Windows版のスクリプトを書くときの注意

Windows版のスクリプトを書くときの注意 。
  • print()するにはbinmode(STDOUT)する。 こうしないと改行コードがすべてCR LFに変換されてしまう。
  • ZIPのコマンドラインはWindowsにはない。Archive::Zipを使う。
  • PerlのCGIでも、c:\perl\*をc:\usr以下にコピーしておけば、CGIスクリプトの 冒頭に#!/usr/bin/perlと書いてあるだけでそのまま動く。
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月29日(日)| はれ | 5/10 | カテゴリ: Perl

Test::Moreのlike()の正規表現判定で、 自作/他作CGIの動作テストを書いてみた

Test::Moreのlike()の正規表現判定で、 自作/他作CGIの動作テストを書いてみた 。 CGIが20本以上と多かったのと、条件に応じた動作が いくつか決まっていたので、それぞれを一気に動作確認 できるようにしてみた。

  • Test::Moreのlike()を使って、正規表現にマッチするとOK、 という判定を利用した
  • WebサーバのコンテンツをLWP::UserAgent, HTTP::Requestで取得。 HTTP::Responseのas_stringにある、HTTPヘッダを含む 応答文字列を検査した。応答文字列には画像のバイナリ データが混在することがあった。データの大きさは数MBまで。
  • リクエストにはHTTP method、URL、Content-Type、POST用データを指定した。
    このリクエスト用のデータも配列に入れておき、順に呼び出した。
      ### 初期化時に1度だけ作成する
      $ua = LWP::UserAgent->new;
      $ua->timeout($TIMEOUT_CONNECT);	## response timeoutが見たらない
      $request = HTTP::Request->new();
    
      ...
    
      ### 動作テスト先のURL、値ごとに実行
      $request->method(      $r->{method});
      $request->uri(         $r->{url});
      $request->content_type($r->{type});
      $request->content(     $r->{body});
    
      my $response = $ua->request($request);
    
      # $response->as_string;		## 検査対象のデータ
    
  • LWP::UserAgentの困ったこと:
    • LWP::UserAgentには、connectionとresponse待ちのタイムアウトの別が ないか、どちらか片方がない。
    • リクエストで送信される予定か、送信されたHTTPヘッダ、HTTPボディの 文字列を取り出すメソッドが見当たらない
  • Perlの正規表現はqr// を使ってコンパイル済み状態で配列に入れておき、 配列から取り出した正規表現をlike()に引数で渡して CGIの応答を検査するようにした。正規表現を実行するときではなく コンパイル時に文法エラーがわかるので確認しやすい。 ベンチマークはとっていないが、遅いということはなかった。
  • 1つのqr//だけでも、次のようなことができ便利だった
    • 普通に応答データの内容の一部文字列を検査できる
    • qr/(?:pattern.*?){8}/sなどのようにしてpatternが8回 現れたかどうか、という検査もできる。ここでは複数行に またがって一気に検索するため、qr//sとしている。
    • something prefix (?!pattern)のようにして、patternが「なかった」 という検査もできる。ただし(?!...)の前に何か前置きが必要。
    • qr//g オプションはない。

ますます正規表現が好きになった。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月29日(日)| はれ | 4/10 | カテゴリ: Perl Regex

Linux/FreeBSD上では、 Perlは/bin/shで書いたスクリプトはperl some.shのようにして、 そのまま実行できる 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月28日(土)| はれ | 3/5 | カテゴリ: Perl

values() というのがあったのか 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月25日(水)| はれ | 2/3 | カテゴリ: Perl

Storableが1つのファイルに保存できるシンボルは一つ 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月18日(水)| はれ | 2/2 | カテゴリ: Perl

Google, mixiなどが対応している2-legged OAuthの 練習問題でハマりつつ、PerlのOAuth::Liteがいけてることを確認した

Google, mixiなどが対応している2-legged OAuthの 練習問題でハマりつつ、PerlのOAuth::Liteがいけてることを確認した 。

Google Developers Conference参加申し込みで 出題された問題。OAuthの公開鍵を使った3-legged認証ではなく、 共有鍵を使って鍵つきダイジェスト認証をする、著者不在の 2-legged(足)な認証をする。devquizという比較的簡単な問題 なのだけれども、いままで使ったことがないので練習のつもりでやってみた。 自分でGoogle Apps premierを使っていれば、利用したかもしれないが、 そうでもないし。3-legged OAuthを見て、あーめんど、と思って 敬遠していたのもある。

自分の理解のために、手でseed作成とHMAC-SHA1ダイジェスト作成を コーディングしていたが、どうもうまくいかない。しかたなく PythonのコードやPHPのコードを探してみると、いくつかあるが 今回のGoogleのdevquizのようにPOSTで、realmをつけて、Authorization ヘッダで認証する、というコードがない。Pythonのマニュアルの 読み方を調べる直前で、PerlのOAuth::Liteがいい、というのを見て やってみると、関数に引数を与えるだけであっさり認証が完了した。

#!/usr/bin/perl 

use 5.0.8;
use strict;
use warnings;

use Data::Dumper;
use OAuth::Lite;
use OAuth::Lite::Consumer;

my $consumer = OAuth::Lite::Consumer->new(
  consumer_key		=> 'YOUR_CONSUMER_KEY',
  consumer_secret	=> 'YOUR_CONSUMER_SECRET',
  realm			=> 'devquiz',
);

my $response = $consumer->request(
    method  => 'POST',
    url     => 'http://gdd-2010-quiz-japan.appspot.com/oauth/YOUR_CONSUMER_KEY',
    params  => {
        hello => 'world'
    });

if ($response->is_success) {
    print Dumper($response->decoded_content);
} else {
    warn $response->status_line;
}

PerlのOAuth::Liteは、nonceを自動的に生成し、time()も自動的につけてくれる。 デフォルトはPOSTのAuthorization:ヘッダの、HMAC_SHA1でそろっている。

というわけで、手でコーディングしていたダイジェストの問題は以下のとおりだった。

  • seedにはPOSTの送信データであるhello=worldを含めること
  • Digest::HMA_SHA1のb64digest()メソッドは、Base64エンコードらしきことを するが、文字列の末尾のパディングをしないため、認証が通らない。
  • MIME::Base64のencode_base64()メソッドは、Base64エンコードをするが、 より大きなデータの処理を想定しているため、デフォルトで文字列の 末尾に改行コードを追加する。末尾の改行が不要なときは encode_base64($digest, "")のようにしなければならない。
  • realmはoath_なんとかのseedには入れない

mixiの説明は、Googleの説明資料の日本語訳になっていてわかりやすい。 が、PerlのOAuth::Liteを使えば、seedに関連する半分以上の説明は理解しなくてもよい。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月17日(火)| はれ | 2/2 | カテゴリ: Web Security Perl

IANAのipv4-address-spaceというページをXMLでパースするのに、 TreePPを使ってみた

IANAのipv4-address-spaceというページをXMLでパースするのに、 TreePPを使ってみた 。自分の非力なマシンのせいか、以下のコードを実行すると 550msかかる(Celeron M 900MHz, 512MB memory, 130MB free)。重い。

#!/usr/bin/perl 

use strict;
use warnings;

use XML::TreePP;
my $treepp = XML::TreePP->new();
my $hash = $treepp->parsefile( "ipv4-address-space" );

my @i = grep {
	  $_->{status} eq 'UNALLOCATED' && $_->{designation} eq 'IANA'
	}
	@{$hash->{registry}->{record}};

print scalar(@i) . "\n";
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月08日(日)| くもり | 4/5 | カテゴリ: Perl IPv4

JSONの配列をperlのJSON.pmで読み込ませてみた

JSONの配列をperlのJSON.pmで読み込ませてみた 。 配列の最後の要素にカンマ(,)があると、読み込めない。 C言語と同じだが、ほんとに不便。UTF-8の文字をHexでしか表示 できないData::Dumperも困る。

PerlのJSON.pmはutf8(1)とutf8(0)を使い分けないと文字化けするとの指摘あり。 このへんもPHPやPythonではどうなのか?という疑問あり。 "json utf8"でGoogle検索すると、トップにこの指摘ページの候補が 表示されるところに問題が。以下のように指摘されている。

JSON->new->utf8(0)->decode($string) ⇒ OK!
JSON->new->utf8(1)->decode($string) ⇒ エラー!
JSON->new->utf8(1)->decode($octets) ⇒ OK!

「エラー」というのは、JSONのdecode()を呼び出すと、 decode()の内部でエラーになり、Perlスクリプトが終了してしまう。 utf8 フラグがある文字列$stringをdecode()したとき、 結果として返るハッシュ内の文字列はutf8フラグがあった。 utf8フラグがない$octetsのdecode()は試していない。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年08月06日(金)| はれ | 2/2 | カテゴリ: Perl Web

Perlのコマンドライン引数にUTF-8文字を入れたいときは Perlのコマンドラインオプションに-CAを使う

Perlのコマンドライン引数にUTF-8文字を入れたいときは Perlのコマンドラインオプションに-CAを使う 。

って、細かいというか、面倒というか。しかし、 -CAオプションなしで、$ARGV[0] = Encode::encode("utf-8", $ARGV[0]) すると、文字化けするのは何なんだ。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年07月26日(月)| くもり | 2/4 | カテゴリ: Perl

Perlのヘキサダンプ(16進数ダンプ, HexDump)は unpack()を使うものだと思う

Perlのヘキサダンプ(16進数ダンプ, HexDump)は unpack()を使うものだと思う 。コマンドライン引数を ヘキサダンプする場合に一行で書けば、こう。

% perl -e 'map { printf("%#02x ",$_) } unpack("C*", $ARGV[0]);
print "\n"' はれ
0xe3 0x81 0xaf 0xe3 0x82 0x8c

上記の例はコマンドライン環境はUTF-8の場合の実行例(Perl 5.10.0)。 "はれ"というコマンドライン引数をヘキサダンプした。 もっと長い場合は改行したりしなければならないが。

上記の例でわかるのは、素のコマンドライン引数は CUI端末のプロセス実行用の文字コードをそのままひきついでいること。 この場合はUTF-8。一方、Perlの内部の文字コードはUnicode (UCS-2) なので、変換する必要がある。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年07月26日(月)| くもり | 1/4 | カテゴリ: Perl

perl の Storableで保存した、perlの実行中のデータイメージの かな漢字部分の文字列はUCS-2だった

perl の Storableで保存した、perlの実行中のデータイメージの かな漢字部分の文字列はUCS-2だった 。Data::Dumper で一括して 表示しようとすると、UCS-2のバイナリ文字列が16進数の数値で 表示されてしまって意味がわからなかった。UTF-8のコンソール上で、 echo 文字 | iconv -f UTF-8 -t UCS-2 | od -t x1cとすると、 同じヘキサ文字列が表示されるていた。結局、Storableで 作ったデータの読込み確認を以下のようにした。

use Encode;
use Storable;

my $hashRef = retrieve "index.storable";

binmode(STDOUT, ":encoding(utf-8)");

foreach my $k (keys(%{$hashRef})) {
  print "$k => {\n\t"
        . join(",\n\t", @{$$hashRef{$k}})
        . "\n\t}\n\n";
}

けっこうめんどくさい。 Perl内部でUTF-8フラグがついた文字列データを Data::Dumperでエスケープさせない方法に、 Data::Dumperのqquote()メソッドの中身を捨てる方法があった。 Useperlという変数を1にするところがまためんどう。

YAML::Dumperがいいですよ、という指摘を受け、 Data::Dumper とYAML モジュールでデータをダンプするを見ると、 Data::Dumperではなく、YAMLを使えば一行にできることがやっとわかった。

perl -MStorable -MYAML -e 'print(Dump(retrieve "index.storable"))'

Fedora 12の場合、YAMLはRPMになっているので、sudo yum -y install YAML でインストールできる。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年07月22日(木)| はれ | 15/17 | カテゴリ: Perl

perlではライブラリのほうでもuse utf8;しないと、 かな漢字の正規表現が効かない 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年05月12日(水)| あめのちくもり/ | 3/4 | カテゴリ: Perl

Perl 5.12.0リリースとのこと 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年04月14日(水)| はれ | 4/4 | カテゴリ: Perl Software

数字にカンマを入れる、Perl正規表現での文字列置き換え

数字にカンマを入れる、Perl正規表現での文字列置き換え 。

1 while $numeric =~ s/(\d)(\d\d\d)(?!\d)/$1,$2/g;

(sub, Comma, comma, perl, regex)

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年04月06日(火)| はれ | 5/5 | カテゴリ: Perl Regex

Perlで配列の積集合(intersection)を求めるベンチマークがおもしろかったので自分でもやってみた

Perlで配列の積集合(intersection)を求めるベンチマーク がおもしろかったので自分でもやってみた 。 List::などのクラスは遅いそうなので、除外して、 連想配列(hash)を使った方法だけに絞った。

use strict;
use warnings;

use Benchmark;

my @l1 = map { int rand 1000 } 1..1000;
my @l2 = map { int rand 1000 } 1..1000;

timethese(10000, {
  q/hash-map-grep-exists/ => sub {
    my (%in_l1);
    map { $in_l1{$_}++ } @l1;
    grep { exists $in_l1{$_} } @l2;
  },

  q/hash-map+keys/ => sub {
    my (%union, %isect);
    map { $union{$_}++ && $isect{$_}++ } @l1, @l2;
    keys(%isect);
  },

  q/hash-foreach-keys/ => sub {
    my (%union, %isect);
    foreach my $e (@l1, @l2) { $union{$e}++ && $isect{$e}++ }
    keys(%isect);
  },

  q/hash-grep/ => sub {
    my %in_l1 = map { $_ => 1 } @l1;    ### こういう書き方は遅い
    grep { $in_l1{$_} } @l2;
  },

  q/hash-grep-exists/ => sub {
    my %in_l1 = map { $_ => undef } @l1;
    grep { exists $in_l1{$_} } @l2;
  },
});

processtime
hash-map-grep-exists 33 wallclock secs (28.93 usr + 0.01 sys = 28.94 CPU) @ 345.54/s (n=10000)
hash-foreach-keys 53 wallclock secs (48.90 usr + 0.01 sys = 48.91 CPU) @ 204.46/s (n=10000)
hash-grep-exists 54 wallclock secs (43.32 usr + 0.05 sys = 43.37 CPU) @ 230.57/s (n=10000)
hash-grep 55 wallclock secs (46.70 usr + 0.02 sys = 46.72 CPU) @ 214.04/s (n=10000)
hash-map+keys 61 wallclock secs (50.56 usr + 0.04 sys = 50.60 CPU) @ 197.63/s (n=10000)

hash を利用しているので、hashの作り方の違いで速さが 変わった。hash-map-grep-exists(33 secs)と hash-grep-exists(54 secs) の違いは、連想配列 %in_l1 への 値の代入方法にある。hashを作るときに、 my %hash = map { $_ => 1 } @array;という ような書き方をすると、hash を作ってから、別の変数に 代入しなおす処理があるらしく、hash を作るだけの処理時間 として比較すると倍くらい遅いらしい。書き方は1行で済むのでかっこいい 感じがするが。$in_l1{$_}++のように 個別に代入を1回づつ行えば、もう一度 %in_l1 へのコピー代入は 不要になるためらしい。

また、hash の中の特定のメンバの値を取り出すよりも、 存在を確認するだけなら exists のほうがほんの少し速い。

遅いのは、hash-map-keysで、map {} の処理ブロック内で 条件分岐をしているところのもよう。

また、= 1 と = undef は速度変わらず。=1 よりも ++ のほうが速い。

というわけで、2つの配列の間で積集合を求めるのにいちばん速かったコードを 関数にするとこうなる。

sub array_intersection($$) {
  my (%_u);
  map { $_u{$_}++ } @{$_[0]};
  grep { exists $_u{$_} } @{$_[1]};
}

一方、python で配列の積集合を求めるときは、setsというのを 使って抽象的に書ける。こういうところはPerlにはない、教育系でも 使われているpythonにメリットがある。教育系で使われるから、 卒業してもpythonを使う、ということなのだろう。 速さは調べていないが、python の配列・ 行列機能は数値計算処理にも使われているので、けっこう速い のではないか?

import sets
a_set = sets.Set([3, 2])
b_set = sets.Set([4, 3])
print a_set & b_set   # or a_set.intersection(b_set) 
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2010年03月03日(水)| はれ | 1/1 | カテゴリ: Perl

Effective Perl のメモは、たいへんよい 。

  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2009年06月06日(土)| あめのちくもり/ | 5/6 | カテゴリ: Perl

正規表現のコメント文は //x;のように すれば、// の間に改行できて、# の後ろにコメントが書ける

正規表現のコメント文は //x; のように すれば、// の間に改行できて、# の後ろにコメントが書ける 。 (?# ... ) でもコメント文になる。しかし、やはり、コメント文の 中に / が入ると、文法エラーになる。

perl -e '$a="abc";$a=~/(a)(?# comment / )bc/;'
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2009年05月11日(月)| はれ | 4/5 | カテゴリ: Perl

use utf8のとき、split()は全角スペースも分割に使う

use utf8のとき、split()は全角スペースも分割に使う 。

#!/usr/bin/perl
use utf8;
binmode STDOUT => ":utf8";	# これがないと警告される
my $str ="全角 ス ペ ー ス が入った テキ\tス\nト";
print join(",", split(/\s/, $str), "\n");

実行結果:

全角,ス,ペ,ー,ス,が入った,テキ,ス,ト,
  • Twitter
  • はてなブックマークに追加
  • Google
  • Yahooブックマーク
  • Facebook
| 2008年12月19日(金)| はれ | 2/2 | カテゴリ: Perl
Perlカテゴリ
1ページ >>

お便りはこちらへ (sshida@gmail.com)
見出し一覧は RSS で つれづれ日記 RSS: RDF Site Summary