天泣記

2004/03/01

#1

上諏訪

2004/03/02

#1

上諏訪

2004/03/03

#1

上諏訪

2004/03/04

#1

mwantenna は更新検出が早いそうで、素晴らしいことです。 五月雨は exponential backoff でアクセス間隔を伸ばしていくので、 5分間隔でアクセスする mwantenna よりも更新検出が遅れることが多いのはまずまちがいないでしょう。

また、そういうアンテナの LIRS を五月雨で参照すれば、 五月雨自身で頻繁にアクセスしなくても更新をタイムリーに検出できるので、 私としてはどちらかというと五月雨よりは mwantenna (もしくは他のアンテナでもいいので 5分間隔で更新を検査する cron の設定) に普及して欲しいように思います。

2004/03/05

#1

さて、五月雨で更新を素早く検出するには、他のアンテナからなるべく たくさん LIRS をとってくるのがコツである。 少なくともいろんなアンテナに監視されている連中については。

% cat `ls tmp/*.lirs|uniq -t_ -W1`|awk -F, '{ print $6 }'|sort|uniq -c|sort -n|tail
     14 http://www.daionet.gr.jp/~knok/diary/
     15 http://triaez.kaisei.org/~kaoru/diary/
     15 http://www.unixuser.org/~ysjj/diary/
     16 http://www.mhatta.org/diary/
     16 http://www.topstudio.co.jp/~kmuto/d/
     17 http://cvs.m17n.org/~akr/diary/
     17 http://diary.imou.to/~AoiMoe/
     17 http://kitaj.no-ip.com/tdiary/
     22 http://www.rubyist.net/~matz/
     23 http://namazu.org/~satoru/diary/

この一番多いひとをどのアンテナが監視しているかというと、

% grep -l http://namazu.org/\~satoru/diary/ `ls tmp/*.lirs|tac|uniq -t_ -W1`
tmp/af-znz.jin.gr.jp-sites_03-05_12:18.lirs
tmp/af-www14.cds.ne.jp-nantenna_03-05_12:20.lirs
tmp/af-www.yui.gr.jp-natsumican_03-05_13:00.lirs
tmp/af-www.topstudio.co.jp-natsumican_03-05_13:10.lirs
tmp/af-www.tdiary.net-tdiary_03-05_13:10.lirs
tmp/af-www.shudo.net-natsumican_03-05_13:02.lirs
tmp/af-www.nijino.com-natsumican_03-05_13:00.lirs
tmp/af-www.mhatta.org-natsumican_03-05_13:00.lirs
tmp/af-www.kimuchi.org-fm_03-05_12:50.lirs
tmp/af-www.hikita.org-natsumican_03-05_12:44.lirs
tmp/af-web.sfc.keio.ac.jp-sites_03-05_12:16.lirs
tmp/af-sugi.nemui.org-sites_02-27_11:18.lirs
tmp/af-pure.fan.gr.jp-latest_03-05_12:56.lirs
tmp/af-moonrock.jp-ruby_03-05_12:40.lirs
tmp/af-marimo.deisui.org-fm_03-05_12:16.lirs
tmp/af-ko.meadowy.net-sites_03-05_12:37.lirs
tmp/af-kitaj.no-ip.com-sites_03-05_12:56.lirs
tmp/af-furukawa.ch.kagu.tus.ac.jp-sites_03-05_12:20.lirs
tmp/af-devlog.moonwolf.com-sites_03-05_13:10.lirs
tmp/af-ayame.tkym.org-sites_03-05_12:58.lirs
tmp/af-arika.org-sites_03-05_12:54.lirs
tmp/af-a.northeye.net-natsumican_03-05_12:18.lirs
tmp/af-a.hatena.ne.jp-source_03-05_13:12.lirs

というわけで、それぞれのアンテナの更新間隔を調べると、だいたい、

znz.jin.gr.jp                毎時50分
www14.cds.ne.jp              毎時20分
www.yui.gr.jp                毎時00分
www.topstudio.co.jp          毎時00,10,20,30,40,50分
www.tdiary.net               毎時00,10,20,30,40,50分
www.shudo.net                毎時23,53分
www.nijino.com               毎時55分
www.mhatta.org               毎時00,30分
www.kimuchi.org              毎時20,50分
www.hikita.org               毎時14,44分
web.sfc.keio.ac.jp           毎時16分
sugi.nemui.org               毎時50分
pure.fan.gr.jp               毎時26,56分
moonrock.jp                  毎時36分
marimo.deisui.org            毎時11分
ko.meadowy.net               偶数時32分
kitaj.no-ip.com              毎時56分
furukawa.ch.kagu.tus.ac.jp   毎時15分
devlog.moonwolf.com          毎時00,05,10,15,20,25,30,35,40,45,50,55分
ayame.tkym.org               00,03,06,09,12,15,15,18,21時00分
arika.org                    毎時13,33,53分
a.northeye.net               毎時18分
a.hatena.ne.jp               不定?

という感じである。

というわけで、1時間毎よりも高頻度で動くアンテナで、

00 00 00 00 00 05
10 10 10 11 13 14 15 15 16 18
20 20 20 20 20 23 25 26
30 30 30 30 33 35 36
40 40 40 44 45
50 50 50 50 50 50 53 53 55 55 56 56

というくらいの更新検出が行われている。 ただ、これらのアンテナの中には毎回はアクセスしないもの (五月雨はそうだし他のアンテナでもそういう挙動をするものがある) があるので、実際にはもう少し減る。

ともあれ、五月雨は定期的に更新される対象に関してはその更新のタイミングを 見計らって取りにいけるので、 普通のアンテナの LIRS は更新されるときに取りにいける。 それで、LIRS の中身を見て興味のあるページが更新されていたら 実際に確かめて更新を検出する、というわけである。 というわけで、LIRS をたくさん使えばそれなりに素早く検出できたりするのである。 いろんなアンテナに監視されている連中に限っていえば、だけど。

#2
% google-count {中国,支那,シナ}の百科事典
35      中国の百科事典
4       支那の百科事典
5       シナの百科事典
#3

Borges' Encyclopedia

2004/03/08

#1

あるオブジェクト内部にフラグ x があり、それを外部から設定するインターフェースを設計するとしよう。

まず思いつくのは

obj.x = true
obj.x = false

である。

さて、べつに上記の方法が悪いわけではないが、他の方法も考えられる。 たとえば、

obj.toggle_x

というようにフラグを反転させる(トグルする)というのがある。

elisp ではトグルをよく見かける。 ただし、トグルは人間用であって、プログラムは使うべきでないとされている。

さて、プログラムにはトグルはなぜ良くないのだろう?

たぶん、 フラグを反転したいケースよりもフラグを直接設定したいケースのほうが多いから、 というのがあるのだろうが、なぜそうなのだろう?

#2
% google-count api-usability
279     api-usability
#3

Lambda the Ultimate: Evaluating API usability at Microsoft

ひっかかったので読んでみる。 なかなか面白い。

2004/03/11

#1

ThinkPad X31 以降の DtoD は Phoenix FirstWare Recover というのを使っているのか。

ThinkPad X31 メモ

2003年バージョン.Disk To Disk

ThinkPad T41のハードディスクのリカバリ

2004/03/12

#1

XML Namespaces Support in Python Tools, Part 1

2004/03/15

#1

ある attr だけ書き出したくない場合、 marshal_dump でそれ以外の全てをまとめて返せばいいわけですが、 「それ以外の全て」を指定するのが面倒な場合、

class C
  def attr
    class << self
      class << self
        self
      end
    end.instance_variable_get(:@attr)
  end

  def attr=(val)
    class << self
      class << self
        self
      end
    end.instance_variable_set(:@attr, val)
  end
end
c = C.new
c.attr = 1
p c.attr
d = Marshal.load(Marshal.dump(c))
p d.attr

というように attr を定義することにより、 dump されない属性を定義することも出来ます。

いや、べつにこういう書き方を勧めているわけではありませんよ?

#2

3月に入ってから、五月雨は core を吐かないし、 undefined method `queue' というのも出ない。 すこぶる快調である。

先月の末に Hash に手が入ってバグが直った結果、 快調になったということが期待されるのだが、 これは本当にバグが直ったということを意味するのだろうか?

最近 10日間、先月までと同様に五月雨を動かしていたにもかかわらず トラブルが起きていないという事実を、 システムの信頼性というページを眺めつつ、考えてみる。

undefined method `queue' というのは 以前まとめたように 2003-07-08T11:45:53 から 2004-02-26T15:18:20 までに 69回発生している。 ということは、

% irb -r time
irb(main):001:0> l=68/((Time.parse("2004-02-26T15:18:20") - Time.parse("2003-07-08T11:45:53")) / (24*3600))
=> 0.291660815032923

というように、故障率λ≒0.3回/日 ということになる。

これが 10日間故障しない確率は、

irb(main):002:0> Math.exp(-l*10)
=> 0.0541169328548749

というわけで、約5% しかない。

ところが現実には故障していない。 つまりバグが直っている確率は 95% くらいということか?

#3

5% ならたまにはそんなこともあるかもしれないと感じなくもない。

では、0.1% になるにはあと何日必要か?

irb(main):005:0> -Math.log(0.001)/l
=> 23.6842075552809

24日ということは、(すでに 10日経ってるから) あと 2週間くらいか。

#4

勧めないなら使いやすくなくてもいいんじゃないかと思いつつ書いてしまった。

% ruby -e '
class Module
  private
  def volatile_attr_accessor(name)
    vname = "@#{name}"
    define_method(name) {
      class << self
        class << self
          self
        end
      end.instance_variable_get vname
    }
    define_method("#{name}=") {|v|
      class << self
        class << self
          self
        end
      end.instance_variable_set vname, v
    }
  end
end
class C
  volatile_attr_accessor :attr
end
c = C.new
c.attr = 1
p c.attr
d = Marshal.load(Marshal.dump(c))
p d.attr
'
1
nil
#5

「まぐろ丼や」という店がある。

感想: google で探すのが難しい。

2004/03/17

#1

高解像度なもの

#2

xmlmine というプログラムを公開した。

知っている人は知っている FREQT というアルゴリズムを使ったデータマイニングツールで、

% cat sample.xml         
<a>
  <a>
    <b/>
    <a>
      <b/>
      <a/>
      <b/>
    </a>
  </a>
  <a>
    <a/>
    <b/>
  </a>
  <b/>
</a>

というような XML ファイルがあったとすると、 次のようにしてデータマイニングできる。

% ./xmlmine.sh sample.xml

patternset-0 rootocc:4 maxsize:2
[
a
 a
]
/sample.xml/a
/sample.xml/a/a[1]
/sample.xml/a/a[1]/a
/sample.xml/a/a[2]

...中略...

patternset-5 rootocc:2 maxsize:4
[
a
 a
  a
  b
]
/sample.xml/a
/sample.xml/a/a[1]

FREQT finished. 6 patternsets reported. (0.271s)

うぅむ。求まったパターンので木構造をインデントで表現しているのだが、 あまり木のように見えないな。

2004/03/19

#1

DELL のでっかいノートが来る。

電源を入れると、EULA を読めと出て来るので、 箱の中を探し回ったのだが見つからない。

しょうがなくて電話したら、ついてないのでそのまますすめとのこと。 うぅむ。

2004/03/20

#1

「読まずにいられなかった 2冊」が何かと問われる。

ひとつは「ハイウイング・ストロール」と答えられたのだが、 もうひとつが思い出せなかった。 帰ってから確認してみると「彩雲国物語 黄金の約束」であった。

しかし、その 2冊以降でも「吉永さん家のガーゴイル2」が それらに近い感覚だったし、 「我が家のお稲荷様。」「先輩とぼく」も続きが出れば そういう感覚になりそうな気がするわけで、 こう見直してみるとけっこう頻繁にそういう感覚になっているなぁ。

2004/03/24

#1

Regexp のキャプチャの構文についてですが、 具体的な構文は言及されなかったと思います。

私としては、named group の記法を利用するのはどうだろうかと思っていて、 次のような感じです。

if /xxx(?<foo>....)xxx(?<bar>....)/ =~ str
  p foo   # マッチすると代入されている
  p bar
end

また、これも読書会では言わなかった気がしますが、 おそらく、$1 よりも長くなる記法は受け入れられないと思います。

if /xxx(...)xxx(...)/ =~ str
  foo = $1
  bar = $2
  p foo
  p bar
end

というのに比べて、

if /xxx(?<foo>....)xxx(?<bar>....)/ =~ str
  p foo   # マッチすると代入されている
  p bar
end

というのは(少しですが)短いため、 ユーザは自然とこちらの形式に移行する可能性があります。 そして、もし自然な移行が起きるのであれば、 $1 に警告をつけて追い出すのも現実的になるかも知れないと思っています。

しかし、

if m = /xxx(?k=foo:....)xxx(?k=bar:....)/.match(str)
  foo, bar = *m.select(:foo, :bar)
  p foo
  p bar
end

とか

if /xxx(?k=foo:....)xxx(?k=bar:....)/.match(str, binding())
  p foo
  p bar
end

というようなの記法は $1 を使う形式よりも長いため自然な移行は起こらず、 $1 とかに警告をつけてユーザを追い出すのは、 あまりにたくさん文句が出て非現実的なのではないかと感じます。

#2

しかし、警告というのは地上げに似ている。

2004/03/25

#1

利点があるんだから長くなってもいい」わけではありません。

短いけれど順番の変化に弱い書き方と、 長いけれど順番の変化に強い書き方がある場合、 プログラマはどちらの書き方を選ぶかで短さと順番の変化に対する強さの どちらか「だけ」を選ばなければなりません。

この選択のどちらが適切かは状況によって異なります。 one-liner なら短さを選ぶでしょうし、 頻繁に順番が変わるならその変化に強い書き方を選ぶでしょう。 しかし、ひとつのコードに対してもこの状況は変わるものです。 最初は簡単に書ける短いほうを選んだとしても、 後から順番が変わって面倒臭い作業(番号を振り直すか、名前を使うように変える)を するはめになることは十分に考えられます。

ここで、もし両方の利点を持つ書き方があれば、 この面倒臭い作業の発生を避けることができます。 つまり、短くて順番の変化に強い書き方があれば、 プログラマはどちらかの利点を選択する必要がなく、 つねにひとつの書き方をすれば両方の利点を得られます。 また、これはスタイルを統一する方向に誘導するという意味でもいいことです。

理想は、いちばん短い書き方がいちばん良い書き方であることです。 もちろん、それが常に可能なわけではありませんが、 それが可能な場合には追求すべきだと考えています。 したがって「利点があるんだから長くなってもいい」という考え方には強く反対します。

さて、「メソッドを呼ぶと知らないうちにローカル変数に代入されてる」のが想像しにくい、というほうは考慮の余地があります。 実際、知らないうちに代入されるのを避けるために #{} で展開した中では ローカル変数へは代入しないと制約したわけです。 この制約のため、ローカル変数への代入はそのローカル変数の名前を書いたところにしか起こりません。 したがって、これはブロックと似ています。 (Regexp がクロージャだと考えればブロックと似ているのは当り前ですが)

meth { a = 1 }

と記述した場合、meth を呼ぶと meth が yield するときには a に代入されるわけですが、 これをもって知らないうちに代入されているという人はあまりいません。

したがって、/(?<a>...)/ に対するマッチで a に対する代入が起こるのが想像しにくいとしたら、 それはこれが通常の代入の構文と似ていないという理由しか思い当たりません。

とすれば、構文を代入に似せることによって代入が起こることが想像しやすいようにできる可能性があります。 例えば、Perl6 の記法では普通の代入の構文を使うので想像しやすいでしょう。

また、Perl6 のような drastic な変更をしないとすれば、とりあえず = という記号を使うということが考えられます。 /(?<a=>...)/ とかするのはどうでしょうね。

#2

Groovy を試す。

1> x = []
2> t = "x = ${x}"
3> println t
4> go
x = []

1> x << 1
2> println t
3> go
x = [1]

なるほど。

2004/03/26

#1

メソッド呼び出しで、というのは [ruby-dev:20689] で小迫さんが触れてますね。 実装は method_missing を想定しているようですが。

それはそれとして、 まず「他のメソッド内でローカル変数に代入させるという操作」といいますが、 Regexp がクロージャであると解釈すれば、 代入しているのは他のメソッドではなく、 そのメソッドの中のコードであると解釈できます。 このように解釈できるのは lexical scope なためであり、 lexical scope にこだわっているのは他のメソッド内で任意のローカル変数に代入されることを防ぐためで、 他のメソッド内でローカル変数に代入させることの危険性は十分に分かった上でデザインしているつもりです。

あと「Ruby 的でない」からだめ、というのはこの場合あまり説得力が感じられません。 まぁ、まつもとさんとかもそういう言い方をすることがある (例: RCR229) わけですが、 まつもとさんがそういう言い方をするケースに比べるとこれはかなり小さい変更で、 Ruby を Ruby でなくしてしまうほどではないように思います。 もちろん、あおきさんの Ruby 的という感覚から外れるのはそうなんでしょうが、 私の感覚がそれに一致するとは限らないわけで、具体的な欠点を述べると説得力が出ると思います。 もし、そういう言葉では述べられない感覚について述べているのであれば... それでもやっぱり言葉にしないと議論できないのでがんばって言葉にしてくださいとしかいえませんけど。

「正規表現を複数のパーツに分割したり定数に入れたりするのをやめてしまう」可能性はあるかもしれません。 それを解決するには、yacc みたいに、個々のパーツごとに action を書けるのがいいかもしれません。 クロージャだと考えれば、任意のコードが実行できてもいいですよね。

#2

そういえば、昨日読んだときは、まつもとさんを説得できないだろうとか書いてあった気がする...

ふむ。五月雨での保存期間を伸ばそう。

2004/03/27

#1

http://i.loveruby.net/d/20040326.html#p01

現在の Ruby でクロージャを作る構文から外れるのは事実です。 それを解決するとすると、例えば /...(?{a=}...).../ というように {} を使うのはどうでしょうね。 いっそ /...(?{|a|}...).../ とか? いや、これはブロックローカルになる構文だからまずいか。

また、スコープに関しては、 Ruby2 では普通のクロージャについてもそういうスコープになる見込みが高いわけで、 Ruby 的にはそういうのも有り得るのでしょう。

アクションについては... 強力な記法を導入したとして、 一番簡単なケースにおける記述量をいかに抑えられるか、 というところがデザイン上の問題ですかね。 強力な記法は長くなりがちなのですが、 最初の目標は $1 よりも短い(そして良い)記法を導入するというところにあって、 その目標を達成できなければ本末転倒なので。

#2

思ったのだが、議論に勝てる仕様が良い仕様とは限らないよなぁ。

すくなくとも、相手の要求をどんどん受け入れていくというのは仕様が膨らんで危険で、そしてクロージャというのはなんでも受け入れられるし。

委員会言語の問題というのはそういうところにあるのかもしれない。

やはり、他の人の要求は自分自身で気に入ったもの以外ことごとく reject して、 自分が一番頻繁に使うところに最適化した最小の記法を提案したほうがいいのかも。

2004/03/28

#1

いや、委員会言語的な問題を避けつつ議論をする方法を考えるほうが建設的か?

でも、それが難しいから委員会言語なんて話になるのではないだろうか。

#2

うぅむ。今月の「少年魔法士」ならぬ「あんまり少年じゃない人もいる魔法士」は、 なんというか、妙にツボにはまってしまった。

#3

コーセルテルはゼロサム行きか。

2004/03/29

#1
% google-count read_partial read_available read_buffered read_buffer read_chunk read_block
0       read_partial
0       read_available
0       read_buffered
0       read_buffer
0       read_chunk
0       read_block

え? あぁ、微妙に形式が変わったのか。

まぁ、HTML から取り出す限り許容すべきトラブルだな。 直しておく。

% google-count read_partial read_available read_buffered read_buffer read_chunk read_block
80      read_partial
279     read_available
138     read_buffered
3940    read_buffer
517     read_chunk
1560    read_block

2004/03/30

#1

テンプレートの API をやっと決めて、ちょっと実装する。

とりあえず rss2html を試しに実装してみる。

#!/usr/bin/env ruby

require 'htree'

RSS = '{http://purl.org/rss/1.0/}'
DC = '{http://purl.org/dc/elements/1.1/}'

rss = HTree.parse(ARGF.read)

HTree.expand_template{<<'End'}
<?xml version="1.0"?>
<html>
  <head>
    <title _text="rss.title">dummy title</title>
  </head>
  <body>
    <h1><a _attr_href='rss.find_element("#{RSS}link").extract_text'
           _text="rss.title">dummy title</a></h1>
    <dl _iter_children='rss.traverse_element("#{RSS}item")//item'>
      <dt _text='item.find_element("#{DC}date").extract_text'
      >dummy-date</dt>
      <dt><a _attr_href='item.find_element("#{RSS}link").extract_text'
             _text='item.find_element("#{RSS}title").extract_text'
          >dummy title</a></dt>
      <dd _text='item.find_element("#{RSS}description").extract_text'
      >dummy description</dd>
    </dl>
    <hr/>
    <p>generated by rss2html</p>
  </body>
</html>
End

うぅむ。 traverse 系のメソッドが甘いのは以前からの懸案だからいいとして、 入力側の encoding の扱いも甘いな。 mconv も htree に移して、auto-detection を組み込むべきか。

#2
% ruby -I. -rhtree <<'EE'
uri = "http://xxx"
pp HTree{'<a _attr_href=uri>yyy</a>'}
EE
#<HTree::Doc
 {elem
  <{http://www.w3.org/1999/xhtml}a
   href="http://xxx"
   xmlns="http://www.w3.org/1999/xhtml">
  {text "yyy"}
  </a>}>

なんて出来たりして、外側のローカル変数がへーきで見えるのがなんとも非常識。

#3

いや、eval 内のローカル変数の仕様は変わるという話を聞いたような...

「eval内で新規に登場したローカル変数はeval終了後消える」か。 新規じゃないから問題ない、だろう。たぶん。

2004/03/31

#1

うぅむ。もしかして POSIX は 2001 から閏秒を許容する?

英語をちゃんと解釈できたという自信がいまひとつ持てないのだが。


[latest]


田中哲