トップ 最新 追記

2009-05-03 [長年日記]

_ Mechanize の parser を Hpricot にする

現状自分は Hpricot 依存のコードがいくつかあるんだけど、parser 切り換えの方法がいつも分からんくなる。

ということでメモ。この辺を見ればいい感じ。

require 'hpricot'
WWW::Mechanize.html_parser = Hpricot

して、あとはいつものように

WWW::Mechanize.new

する。


2009-05-16 [長年日記]

_ Unicode なメールの話

ちょっとしたツールでメールを送る、って処理で何回も何回も車輪を作り直してる気がするんだけど。Unicode のメールを送るってことにあまり真面目に取り組んだことがなかったのでちょっとやってみた。

そこで知ったこと。

Unicode の 8bit のデータをそのまま Content-Transer-Encoding: 8bit で送る(とりあえず UTF-8 と仮定)と、勝手に body をquoted-printable にしてしまう SMTP とそうでない SMTP がある

ということは UTF-8 のデータそのものが直接届くとは限らないわけだ。

quoted-printable body の扱い

  • Thunderbird では問題なく読める(確か Outlook Express でも大丈夫*1
  • テキストデータとしては扱いにくいので body を nkf で UTF-8 に戻せるかと思ったら、使っている nkf のバージョンの問題なのか、全部を正しく復元することはできなかった

Thunderbird でソースを表示すると quoted-printable なデータを拝むことができる。見慣れないエンコーディングなのでデータが壊れてるんじゃないかと思うが、そうではない。

ただ問題は nkf で復元できなかったこと。すべてのデータが必ず復元できないのかどうかは分からないけど、なんかこう、一抹の不安は残る。

UTF-7 は便利だけど微妙

UTF-7 に encode してしまえば 7bit データなので勝手に quoted-printable になることはない。

UTF-7 とは超乱暴に言うと base64 を使って Unicode のデータを ascii にしてしまう encoding. したがってそのまま読み書きすることはできないと言っていい。

つまり

  • body だけ取り出してメタデータがなくなってしまうとそれが UTF-7 なのかどうなのか、少なくとも人間には当たりをつけるのは難しい
    • でも base64 を使っている UTF-7 にはダメ文字が多く、body だけをちゃんと取り出さないとまず変換できない
  • nkf は対応していないので iconv で取り出してね

Unicode の中で UTF-7 はそんなに扱いのいい方ではないと思う。多くの場合で UTF-8/16/32 くらいしか見ない。iconv は……。イマドキ普通に使えると言っていいのかなぁ? Windows のことなんか知らね、でよい? というか Ruby が入ってれば iconv は入ってる、と言ってよいのかしら。それならまぁいいのかな?

まとめ

Unicode 時代のメールって、まだちょっとやっかいだなーと思った。iso-2022-jp だけで済んでた時代は簡単だったなぁ。

Tags: Mail

*1 EdMax は Unicode 版を新たに作り直してるらしい。

_ Rake 内では Exception の class 名が消える場合がある

Exception の class 名って表現で合ってるのかな。

上の Rakefile を実行すると

rake aborted!
bar

のように怒られる。FooExcept はどこいった? rake 0.8.7 で確認。それとも Rake はこういう仕様なのかな。

Tags: Ruby

2009-05-17 [長年日記]

_ pukiassist なんてのを作ってみました

wtnabe's pukiassist at master - GitHub

最近ちまちま作っていたのをようやく公開できました。

なんでこんなもの作ったの?ってのを含めてほぼ全部 README に書いてあるんですが、要するに

  • PukiWiki を使いつつ、
  • 定期、不定期に
  • その情報をメールなど Wiki 以外でも使いたい

という超個人的な要求に楽に応えられるように作りました。

最近の Wiki なら API や標準の管理ツール(trac-admin みたいなイメージ)で便利に使えると思うのですが、いかんせん PukiWiki は日本を代表する第1世代 Wiki なのでまったく楽な管理ができません。かといって PukiWiki はもうその内部構造の限界に達しているので大幅な機能強化も望めません。

そこで仕方なく

  • 外部から
  • URI の生成と
  • Mechanize でページの生成
  • URI やその内容をメールとかファイルで出力
  • ついでに(でも個人的には超重要)setext 化してしまう

なんてことをやっちゃうツールを作りました。

中身は PHP はほとんど関係なく、

  • Ruby
  • Rake
  • Mechanize
  • Hpricot

に依存しているという、最近の好みが色濃く反映されたツールになっています。

setext 化するツールだけは半年くらい前からあった*1のですが、nkf で SJIS/CRLF にするとか、ごちゃごちゃした操作がたくさんあってよく間違えていたのがとても腹立たしく、カッとなってどうにかひとまとまりにしてみました。

gem は作ってないので git clone か Web の download からどうぞ。個人的にはくだらない作業をやっつけることができてとても満足していますが、イマドキそんなに多くの人には響かないような気もします。ま、これだけじゃページ管理とかそういうのには使えませんしね。

*1 あくまで適当ですよ、適当


2009-05-18 [長年日記]

_ URI#encode, decode するのに $KCODE は要らない気がする

Ruby のリファレンスマニュアルを見ていると URI#encode のところで $KCODE をいじっている処理を見掛ける。

URI - Rubyリファレンスマニュアル

require 'uri'
$KCODE = 'EUC'
p URI.escape('http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Rubyリ ..

=> "http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Ruby%A5%E ..

これ、要るんだろうか?

Ruby 1.8.7@OSX 10.5.7 + MacPorts で試す。

$ irb
irb(main):001:0> $KCODE=''
=> ""
irb(main):002:0> require 'uri'
=> true
irb(main):003:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):004:0> $KCODE='u'
=> "u"
irb(main):005:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):006:0> $KCODE='e'
=> "e"
irb(main):007:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"

以上、encode については $KCODE の値はなんら影響なし。例によってこれを書いている時点では Ruby 1.8.7 で試して結果をコピペしてるけど、実際には 1.8.5 でも 1.8.6 でも試している。

irb(main):008:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "日�\234�語"
irb(main):009:0> $KCODE='u'
=> "u"
irb(main):010:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "日本語"
irb(main):011:0> $KCODE='e'
=> "e"
irb(main):012:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):013:0> $KCODE=''
=> ""
irb(main):014:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil

decode についても途中文字化けして見えるのは terminal が UTF-8 で、utf-8 の文字列を euc-jp の設定で無理矢理出力しようとしているのか、確かに化けて見えるが戻ってきた値を puts したものでは化けない。

つまり、戻り値の日本語に対して何かの操作を加えようとするなら $KCODE の値は意味があるかもしれないが、encode, decode 自体には関係ないように見えるんだけど、違うのかな?

Ruby 1.9.0@Debian lenny の場合。

$ irb
irb(main):001:0> $KCODE = 'u'
(irb):1: warning: variable $KCODE is no longer effective; ignored
=> "u"
irb(main):002:0> require 'uri'
=> true
irb(main):003:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):004:0> $KCODE = 'e'
(irb):4: warning: variable $KCODE is no longer effective; ignored
=> "e"
irb(main):005:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):006:0> $KCODE = 'u'
(irb):6: warning: variable $KCODE is no longer effective; ignored
=> "u"
irb(main):007:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"
irb(main):008:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):009:0> $KCODE = 'e'
(irb):9: warning: variable $KCODE is no longer effective; ignored
=> "e"
irb(main):010:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):011:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' ).encoding
=> #<Encoding:ASCII-8BIT>

やっといてなんだけど $KCODE の値は ignored って言われてるんだから意味がない。この場合は locale が UTF-8 だから UTF-8 で解釈されるような気がしたんだけど、中身は ASCII-8BIT だった。

まぁ言いたいことはそういうことじゃなくて、戻り値に対して操作を加える必要がないなら URI#encode, decode 自体には $KCODE は関係ないよね?ってことでした。

Tags: Ruby

2009-05-19 [長年日記]

_ NKF.nkf( '-M' ) が Ruby 1.8.5 で壊れている

いわゆる mime B encode というのに使ったんだけど、1.8.5 では使えないことが分かった。

Ruby 1.8.7@OSX 10.5.7 + MacPorts

$ irb
irb(main):001:0> NKF.nkf( '-wM', 'abc' )
=> "abc"
irb(main):002:0> NKF.nkf( '-wM', '日本語' )
=> "=?UTF-8?B?5pel5pys6Kqe?="
irb(main):003:0> NKF.nkf( '-M', '日本語' )
=> "=?ISO-2022-JP?B?GyRCRnxLXDhsGyhC?="

Ruby 1.8.5@Debian etch

$ irb
irb(main):001:0> NKF.nkf( '-wM', 'abc' )
=> "abc"
irb(main):002:0> NKF.nkf( '-wM', '日本語' )
=> "=?UTF-8?B?5pel5pys6Kqe"
irb(main):003:0> NKF.nkf( '-M', '日本語' )
=> "=?ISO-2022-JP?B?GyRCRnxLXDhs"

見て分かる通り

Ruby 1.8.5 の nkf で -M を利用すると末尾のデータが欠落する。UTF-8 しか使っていない場合は ?= を付ければ済むように見えなくないが、ISO-2022-JP の場合はもう少し削れており、復元不能。

ここでは Debian etch を例に出したが、CentOS 5 でもパッケージで入る Ruby は 1.8.5 であり、いろいろなところで安全に使える Ruby という意味では 1.8.5 がまだまだ現役だと言っていいと思う。(開発陣からは恐らく見捨てられてると思うけど。)

そうすると選択肢は以下のような感じかな。

  1. Ruby 1.8.6 以降を使え!(上には書いてないけど 1.8.6 でも大丈夫なのは確認済み)
  2. Ruby では mime B encode には期待しない(header には日本語入れない)
  3. encode 自体は pack だけでとりあえず済まし、fold しない(当然、ちゃんと送れる保証はない)
  4. ActionMailer とか大きなライブラリを利用する

大きなアプリの中で使うなら 4 でもいいんだけど、ちょっとしたツールでは大げさだよねぇ。

今回改めて mime B encode というか mail header の `encoded word' 辺りを調べてみたけど、面倒くさいねぇ、これ。

Tags: Mail Ruby

2009-05-21 [長年日記]

_ Capistrano :ssh_options 再び

以前Net::SSH で明示的に password 認証にでまったく同じ現象に悩んでいたんだけど、またハマったのでもう一度書く。

ポイントは

自分の ssh_config と秘密鍵を認証に使いたくない

で、これの実現のためには

set :ssh_options, {
  :config => false,
  :keys   => []
}

と設定されていればよい。(:keys => nil はダメ)

set :ssh_options[:auth_methods], 'password'

だけでうまくいくんじゃないかと思ったけど、これはなんでかうまくいかなかった。ちゃんと内部で password 認証だけに絞られてるように見えるんだけど、そういうわけではないのかな。

Capistrano 2.5.5 で確認。

それか capistrano で使う秘密鍵の名前はデフォルトとは別な名前にしておくという方針がいいのかもしれない。

Tags: Sysadmin Ruby

_ git cvsimport -C DEST

Subversion と Git の場合、git-svn という便利なツールがあるらしい。使ってないからよく知らないけど絶賛する声をよく聞く*1

でも CVS の場合はそこまでいいものはない。一応 CVS リポジトリの import 自体は working copy 上で

git cvsimport -C DEST

って打つと DEST 上に .git/ を作って import してくれる。ただし cvsps という別なツールに依存しており、かつ普段の git のスピードからは想像がつかないくらいの時間が掛かる。

それでも git log が使えるというメリットは結構大きい。日常的に git にも CVS にも commit しますという目的に使うのは厳しいみたいだけど、コードを読むという目的には十分使える。

cf.

Tags: Git

*1 自分の場合は git と生の svn を別々に使うので特に不満はない。


2009-05-22 [長年日記]

_ PukiWiki の calendar_viewer plugin 改再び

久しぶりに何か書いたか思ったら diff を貼り付けただけというテイタラク。

2005年にも一回やってる んだけど、git と gist を使って 1.4.7_notb バージョンを出してみる。相変わらず PukiWiki 関係は一つのブロックがものすごくでかくて追うのがつらい。

特に変わったところはないんだけど、なんか行番号が合わずにどこに何を入れたか考えるのが面倒になったのでロジックだけ頭に思い出してコピペしてしまった。

これで一応リリースされた PukiWiki の最新バージョンには追いついたので PHP を 5 に上げられる。

そのうち DokuWiki 辺りにするのがよいのかねぇ。最近 Wiki で熱い人を見かけなくなったので分からなくなってしまった。

Tags: PHP PukiWiki

2009-05-25 [長年日記]

_ bind を上げてちょっとハマって反省した

bind 9.4 以降の allow-* の設定

Debian を etch から lenny に上げた関係で bind のバージョンが上がった*1。そしたら別セグメントのネットワークから forward 先の DNS を引けなくてちょっとハマったので覚え書き。

acl "allowed-hosts" {
  .. ;
  .. ;
};

options {
  allow-recursion { "allowed-hosts"; };   // <- added
  allow-query-cache { "allowed-hosts"; }; // <- added
};

こんな感じみたい。

default が localhost.localdomain なのでこの設定を明示しておかないと別セグメントのネットワークからは DNS が引けないとか forward されないといった問題が起きる。*2

allow-recursion, allow-query, allow-query-cache 辺りは互いに補完するような関係らしく、ややこしいのであまり突っ込む気なし。

今回のケースはサーバのそばにいる自分の環境からは検証できない現象なので、気づくまで時間が掛かってしまった。うーん反省反省。

bind-announce のチェック

※ ここから先は実は5月26日の話

bind のアップグレードはいつも気を使うんだけど、日常的にはちゃんと情報を追いかけてなくて、たいていちょっとトラブる。(そんな長い時間じゃないんだけど。)

なんで bind の情報に追いついていないのかなと思ったら案の定 feed を購読していないから。そもそも bind は本家がどこかもよく分かっていないような状態で、そらいかんわなと反省。

で、feed を探すが見つからず。こういう古いアプリはサイトの作りも情報の告知方法も古いのが世の常。bind-announce という ML があるのは分かったが ML にはもう入りたくない。

そこで Nabble という ML アーカイブサービスを思い出した。これは ML のアーカイブを独自に作れて、かつそれを rss にも変換してくれるサービスなのだ。sign up して…えーとオレが思い描いているのとすでに画面が違うっ。使ってないのバレバレ。

あれこれ試行錯誤したが違うサービス上ですでに bind-announce の feed が配信されているのを発見。あーじゃあこれでいいじゃん。

Gmane -- Mail To News And Back Again

ということで FLDR で subscribe 完了。よしよし。

cf.

*1 9.3.4 -> 9.5.1

*2 本当は DNS 管理者は早い段階でこの辺の設定について分かっているべき。自分があまり神経質になっていないのは内向けの運用だからなの、と言い訳しておく。


2009-05-26 [長年日記]

_ gemを作るとき、プロジェクトを作るときには結局何を使うと嬉しいのだろう

これまで gem は使うだけで作ったことがなかった。github や coderepos に上げてある自作のツールも gem 使えたらもう少し楽かなぁなんてことを思うんだけど、何を使って作るのがいいのかもよく分からないのでちょっと調べてみた。

というか何年も溜め込んでいただけのブックマークを広げてみた。

名前だけは newgem や Hoe を知っていたんだけど、なんかこういう似たようなものがいっぱいある状況はあまり好きではなく、決定版はないのかなーと思っていたところで以下のような記事を見つけた。

cutagem - Yet Another newgem っぽいなにか - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtech

こういう情報は実に嬉しい。howto は howto でありがたいんだけど、それぞれのツールの howto だけあっても、で、結局何?みたいな気持ちになるのも事実*1。ちゃんと比較というか好みを挙げてくれるものはあまり見る機会がなく、とても参考になる。

これだけじゃなんなので自分でも試してみた。

  • hoe
    • そんなにたいしたことはしない。こういう風に書きなよっていうひな形のファイルがダダっとできるだけで、確かに Manifest のメンテとかそれなりに面倒くさそう。
  • newgem
    • 依存が多い。activesupport とか hoe とか。その割にできあがる Rakefile が決め打ちでいやな感じはする。というか基本は Rails 向けかなぁ? 個人的にはあんまり用ないような?
  • cutagem
    • 決定版ぽいんだけど最近いじってないのはなんでだろう…。基本的に rubyforge しか考えてないっぽいのは 0.0.7 の話?*2 できた Rakefile はいじりやすくて、とてもいい感じ。
  • gemify
    • gem の作成に向いているのであってプロジェクトのひな形は作ってくれない。

ここに来て新事実発見。

プロジェクトのひな形を作るツールと gem を作るツールは分離しててもよい。

そうか。hoe + gemify くらいがお手軽というかスタンダードに近いと考えていいのかなぁ?

ruby-toolbox 的には jeweler らしいんだけど自分の環境は .gitconfig が link だからなのか jeweler が使えなかった。じゃあ newgem を飛ばして知名度的には bones かしら?

……。なんか余計に選択肢が増えてしまった。どうしよう。


このあとボクはどっち方面へ向かっていったらいいんでしょうか? cutagem が好みに合うならそっちまっしぐらでいんじゃね?とか、bones も悪くないよなどの情報があるととても喜びます。

Tags: RubyGems Ruby

*1 ごめんなさいごめんなさい

*2 まだ 0.0.8 は試してない


2009-05-29 [長年日記]

_ Array#map {}.compact と Enumerable#select

なんかずっと混乱していた。

一文で言うと map は加工済みの結果を返せるけど、select のブロックの中身はあくまで一つ一つの要素そのものをふるいに掛けるためのものでしかなく、加工済みのデータを返すことはできない。

map の例

irb(main):001:0> (1..5).map { |e|
                   ( e % 2 > 0 ) ? 'e' + e.to_s : nil
                 }.compact
=> ["e1", "e3", "e5"]

select の例

irb(main):002:0> (1..5).select { |e|
                   ( e % 2 > 0 ) ? 'e' + e.to_s : nil
                 }
=> [1, 3, 5]

これは以下とまったく一緒

irb(main):003:0> (1..5).select { |e|
                   e % 2 > 0
                 }
=> [1, 3, 5]

分かってしまえば当たり前なんだけど、いざ書いてみると不慣れなときは何が起きているのかよく分からない。なんか久しぶりにこの感覚味わった。

Tags: Ruby

2009-05-31 [長年日記]

_ 1万時間

なんかふと思いついて irb で計算してたときのログ。

13:06:40 1万時間がフルタイム勤務で3年半ほど。
13:08:20 いや3年半じゃないな。240日勤務として5年ちょいだ。
13:10:13 逆に1日1時間だと毎日でも27年
13:12:16 効率が60%だとして8年半。ざっくり一人前まで10年ていうのはそんな
         に間違っちゃいないか。

いやなに。よく

「一人前になるまで10年掛かる」

とか言いませんか?

一方で最近「1万時間」ていう表現をちょいちょい目にするなぁと思って、どういう数字なのかなと思ってあれこれいじっていたのです。そうするとまぁフルタイム勤務で10年(だいたい8年半前後)を1万時間と言ってもそんなに外れてないなぁと。

年単位での表現でも時間単位での表現でも、何かについて一人前と呼んでいいかどうかの判断て、そんなに大きく違わないんだなーとなんとなく思ったのでした。