青木日記

<前月 | 最新 | 次月>

2003-10-06

もう日記じゃない

おひさー。

という言葉が冗談にならないほどの時間がたってしまいました。え、五日ぶり? 六日ぶり?

ruby-dev summary

しまった、お約束どおり今週も忘れたぜ!

温泉

ふー、やれやれ。世間は温泉ですか。うらやましくなんか! うらやましくなんかないぞっ! うらやましくなんかないんだうわぁぁぁぁぁん!

開眼

わかってしまいました。

わかったんだよ。何がってそりゃあんた略語だYO! りゃ・く・ご。refactoringの略がリファクタとかリファクとかリファだとか、わたしがそんな赤子の手をひねるようなことを言っている間に時代は既に 3cm 以上も先へ進んでいたのでした! そうだ! リファクタリングに変わる新たな名称は!

ファクタリン。

これだね。単に英語の発声をそのまま日本語にしただけのような気もするが気にしちゃいけねえ。これは最近流行りの blog と同じ省略方法なんだな。もちろん「グ」は意味をなさない雑音と思われるのでデフォルトで省略している。

そういえば昔「ぐ」が大きいって言う CM あったな。一発目は面白かったけど、インパクトだけの一発ギャグをバージョン変えて流すというのはどうなのさ。どうなのよ? どうなんですか? 毎回毎回「具が大きいなあ具がー」って言わないといけないギバちゃんの身になってみたことがあるのか?! ああん?! どうなんだねキミィ! またオチ無しでおわらせようったってそうはいかないんだよ世間はそんなにあまくないんだよ! そういうことをするから「ああこいつまた徹夜でハイになってやがるな」とか思われて「青木は常に賞味期限切れの食料を食っている」とか言われるわけだよ! なにい? 馬鹿言ってんじゃないよ無関係じゃないんだよ今日のねたが焼き直しであることに関連しているんだよ世界のすべての事柄は関係しているんだよ連続しているんだよ! だよだよ! 連続! 滑らか! 「滑る」は「すべる」だが「滑らか」は「なめらか」であって「すべらか」ではなく、関数 f(x) が連続であるとは f が x=a においても定義され lim x→a f(x) = f(a) であるということなんだよ(『新微分積分』サイエンス社1979)うわやけに古いなこの教科書ってそんなことはどうでもいいんです。

寝る。

落ち着いた

一転して冷静になった。文章を読み返し、ああ、おれってば真正の馬鹿だな、と思うも結論だけは変わらず。

やっぱり寝よう。

本日のツッコミ (全4件)

ささだ [結論って、ファクタリンのことですか?]

青木 [「寝る!」が結論です。]

ま2 [「ふぁくタン」がいいのではないでしょうか。
ついでに「グが大きい」と言っていたのは,小林稔侍ではないでしょうか。]

のりつぐ [「ファクタリンであなたのソースコードも元気に回復!」]


2003-10-07

もうわたしは呆れてものも言えません

なんで魚ってこう賞味期限が短いんですかね。

具体的に言うとすぐに 3 日過ぎてしまうくらい。

ruby-dev summary

うー、めんどい。 気合いを入れすぎるとどうも長くなってしまうな。 なんでマーシャライザのまとめとか入ってるんだよ。 入門書かよ。

本日のツッコミ (全1件)

なひ [「マーシャライザ」が可愛い。一説によるとマーシャとライザの姉妹
という設定らしい。オブジェクトをめぐる旅を続けるマーシャらに忍び寄る、
シリアライザの影。]


2003-10-08

寝すぎた

寝すぎた。いくらなんでも 20 時間ぐっすりは飛ばしすぎ。

売れ筋

『CPUの創りかた』ってずいぶん売れてるんですね。 みんななんだかんだ言って好きだなあ。

と同時に必要以上に萌え系を嫌う人も多いわけだけど、 そういうのって同族嫌悪? と意地悪く思うのです。

「でぶサマリー」って書くと凄ぇ嫌な感じ

さて ruby-dev summary 投げて朝まで寝よう。(おい)


2003-10-09

追加

CPU の作りかたにしても著作権にしても UNIX ネットワーク管理にしても、 わざわざ萌え本にするのは、ようするにそのほうが売れるからでしょ。 逆に言うと、萌えを導入しないと売れない (採算が取れない) んじゃないのかな。 特に『CPUの創りかた』はその性格が強いと思う。 あれの表紙が萌え絵じゃなかったらいかにも売れなそうでしょ。 そういう「いかにも売れなそう」な状況を作った我々にも、 ある程度責任はあると思うんよ、今の状況は。

COM

「温COM知新」

Component Object Model のほうね。

本日のツッコミ (全2件)

arton [これはもしかして、魚にカビが生えていたという意味でしょうか? いや布団にか?]

あおき [いやさすがにそれはないかと]


2003-10-10

イレギュラー・エクスプレッション

http://www.sorekika.com/dame.jsp?idx=352

本日のツッコミ (全2件)

AC [きみはC/Migemoのような人だ。

あと賞味期限を切らしてしまうあおきさんに朗報です。
発酵系。
http://www1.odn.ne.jp/setsuna/za_ferment.html]

青木 [こ、これを食べろと?
それとも作れと?(むり)]


2003-10-12

マーシャル

え? marshal するのは marshaller なの? しらんかった……

そうか、marshal は動詞か。

Ruby 1.4

久しぶりに Racc を ruby 1.4 で動かしてみた。

(テストに使ってる) fileutils が動かなかったので 使えるときは /bin/rm を使うことにした。

rescue c => err が使えなかったので $! に戻した。

Object#class がないと怒られたので type を alias したら SEGV した。

……どうしろと。

Racc 1.4.4 (予定)

という文面からもわかるように Racc 1.4.4 を出そうとしています。 変更点はおそらくドキュメントとパッケージ構成のみ。

リリース間際の ChangeLog

普通 ChangeLog には version x.x.x released. とか書いてあるじゃないですか。とすると

  • released と書く
  • チェックインする
  • CVS tag を打つ
  • make dist (内部で cvs export -rTAG を使う)

という手順になるはずです。というか、ぼくはそうしてるんです。

ここで make dist に失敗したりして、ファイルを変更したとします。 すると ChangeLog にログが追加されるので、 さっき書いた version x.x.x released. が嘘になります。 こういうときは毎回 version x.x.x released. を手で付けなおすものでしょうか。

それでいいならいいんですけど、 その作業の途中って一時的に不安定というか、 整合性のない状態になりますよね。

いや待て待て、CVS はもともと複数ファイルのコミットが アトミックじゃないんだから整合性もクソもないか。

やっぱり毎回地道に付けなおせばいいのかな? でもなんかめんどくさいな。まあいいか。

Racc 1.4.4

あー、やっとリリース終わった。 ドキュメントのフォーマットを直したり 文章手直ししてたらえらい時間かかってしまった。

予告通り変更は (あんまり) なし。 と言ってもファイル名変えたりしたけど、 外からは見えない変更なのでまあいいでしょう。

本日のツッコミ (全2件)

ksaito [普通は「 make dist が通るまでがリリーステスト」だから、たとえば RC1 とかを貼ってmake dist が通るまで RC を上げ、make dist が通ったら released タグを打って make dist じゃないかしら。
http://www.scmpatterns.com/book/ でいうところの"Release-Prep Codeline"。]

ksaito [いや、raccの場合はcodelineを分ける訳じゃないから、ここで"Release-Prep Codeline"を挙げるのは少しズレてる(苦笑)。失礼。]


2003-10-13

RCS

RCS を使ってみた。なんでいまさら RCS かと言うと、 NetBSD が /etc/passwd なんかを RCS でバックアップしてたから。

使うのは CVS に慣れてると簡単。 単に ci するとファイルが消えるのは何事かと思ったけど、 逆に言えば大きく違うのはそのくらいだろうか。

ところで RCS はソースコードが小さくていい感じだ。

コマンド名

rcs にしても cvs にしても sccs にしても、 コマンド名が打ちにくすぎやしないか?

ReFe / 補完 / zsh

  • ReFe はメソッド名を補完する。
  • man はエントリ名を補完しない。
  • zsh は man のエントリ名まで補完する。

zsh がインタラクティブにメソッド名を補完してくれればいいのか?

その逆に、勝手にエントリ名を推測して展開する man、てのもよさそうだな。

ディレクトリ

女房と畳は新しいほうがよく、 継承とディレクトリは浅いほうがいい。

リリース間際の ChangeLog (2)

昨日の文を読み返してみると、 結局なにがどう嫌なのか自分でもよくわからない。 もう一回おちついて心の中を整理してみる。 ChangeLog の話はちょっと置いとくとして、 どこらへんを嫌だと感じたか考えてみると、

  • いったん打った CVS tag を動かすのが嫌
  • CVS tag と ChangeLog の中身を手で同期するという作業が嫌
  • ChangeLog が単純増加でないのが嫌

の三つだな。たぶん。

最後のは気分的な問題だろうか。

二点目はそれなりに意味があるかもしれない。 cvs tag のタイミングで CVS が勝手に "version x.x.x released" を入れてくれるような仕組みがあっても罰はあたらないし、 技術的に難しくもないし、十分ありうる。たぶん実際には使わないけど。

でも手動が嫌って言うなら ChangeLog を手動で追加してるのをまず直すべきだよなあ。俺の場合。

一点目はなんで嫌なんだろ。 チェックアウトした時間によってタグの位置がずれるからかな。 cvs co -rTAG して、そのあと別の人が TAG を移動した場合、 cvs update のタイミングで更新してくれるんだっけ。

されるようだ。じゃあいいか。

あー、もしかして、タグを付けかえると参照透明でなくなるから嫌なんだろうか。 関数型言語に毒されてきたっ。

ftype, assoc

Windows 2000 では ftype と assoc というコマンドで 拡張子から実行ファイルへの関連付けができるそうな。

C:\>assoc .rb=RubyScript
C:\>ftype RubyScript=C:\ruby\bin\ruby.ext %1 %*

としとくと

C:\>hello.rb
Hello, World!

となる。へー。

本日のツッコミ (全1件)

なかだ [たしか、関連付けされてるとリダイレクトできなかったとかなんとかあったような。]


2003-10-15

コマンドの使用回数 / revised

去年の 6/27 にやったやつ。 前回はこんなだった。

     1   5163 ls
     2   3480 less
     3   2881 vi
     4   1755 cd
     5   1419 cvs
     6   1060 ruby
     7    668 grep属
     8    643 w3m
     9    574 mv
    10    534 make
    11    531 rm
    12    499 dirs
    13    491 cat
    14    483 po
    15    404 cvsdiffl
    16    303 pop
    17    238 cp
    18    236 man
    19    228 exit
    20    214 echo
    21    190 cvschk
    22    186 mkdir
    23    168 tar
    24    159 refe
    25    147 gcc
    26    147 sudo
    27    141 sh
    28    131 date
    29    131 ps
    30    117 mboxchk

一年以上たって使用回数はどう変わっただろうか。 ちなみに .zsh-history はこうなっている。

% wc ~/.zsh-history
 160348  513003 4817444 /home/aamine/.zsh-history

で、以下リスト。 括弧の中の数は前回のランキングからの順位変動。

     1  32766 ls
     2  16773 vi (+1)
     3  16436 less (-1)
     4   8759 cd
     5   8694 cvs
     6   6220 ruby
     7   5218 po (+7) -- n回popd
     8   4372 w3m
     9   3651 rm (+2)
    10   3634 dirs (+2)
    11   3478 mv (-2)
    12   3478 grep (-5)
    13   3194 cvsdiffl (+2)
    14   2995 make (-4)
    15   2031 cat (-2)
    16   1619 man (+2)
    17   1403 refe (+7)
    18   1345 cp (-1)
    19   1318 exit
    20   1301 ind -- RHG 原稿の詳細目次生成コマンド
    21   1271 tar (+2)
    22   1134 sudo (+4)
    23   1024 mkdir (-1)
    24    926 list -- RHG 原稿の章目次生成コマンド
    25    922 date (new)
    26    913 cvschk (-5)
    27    801 mboxchk (+3)
    28    746 haskell -- GHC + runhugs + hugs
    29    737 echo (new)
    30    720 ssh (new)

ここからわかることは、

  • さらに頻繁にヘルプ系を使うようになった (51 位に href も入っている)
  • 原稿を書くだけでランクはあっさり変動する (ind, list)
  • 意外と真面目に Haskell を使っていたらしい (その代わり gcc が 36 位に後退)
  • もはや CVS は基本コマンドである (関連コマンド全部の合計だと 13449 で less に迫ってる)
  • 最近パソコンを時計代わりにしているのが反映された (date)

付記

コマンドラインヒストリ関係の zsh の設定は以下の通り。

setopt append_history extended_history no_share_history hist_ignore_dups
HISTFILE=~/.zsh-history
HISTSIZE=10000
SAVEHIST=10000000

ftype, assoc (2)

http://jarp.jin.gr.jp/diary/200310b.html#200310133

    更に環境変数PATHEXTに.rbを追加すればhelloで実行可能。

にゃるほど。%PATHEXT% ってそういうものだったんだ……。

ちなみに ftype/assoc の設定はマシンを再起動しても有効なんですね。 レジストリに保存してるのか。

そしてツッコミから

■なかだ『たしか、関連付けされてるとリダイレクト
できなかったとかなんとかあったような。』

確かに、stdin がパイプだと EBADF になりますね。 なんだこれは……。

C:\aamine>type cat.rb | cat
プロセスが、存在しないパイプに書き込もうとしました。
C:/aamine/cat.rb:2:in `each': Bad file descriptor (Errno::EBADF)
        from C:/aamine/cat.rb:2
 
C:\aamine>type cat.rb | C:\ruby-vc6\bin\ruby cat.rb
#!/usr/bin/ruby
ARGF.each do |line|
  print line
end

タイミングよく ruby-talk でも同じ話が。[ruby-talk:84105]

○○占い

なんとか占いっていろいろあるけど、 「UNIX コマンド占い」ってあるかな? こんなの↓

あなたは tee タイプです。
本当は熱心に働いているのに、
「たいしたことをしていない」
「さぼってる」
などと誤解されてしまいがち。
もっと自分をアピールしていきましょう。
 
あなたは BSD ps タイプです。
他人の状態をよく把握しているようです。管理職のかたでしょうか?
ときどき舌っ足らずになることがあります。気を付けましょう。
 
あなたは find タイプです。
多芸のうえに人と協力するのも得意ですが、
細かいところまで納得しないと働きません。
あなたの上司は苦労していることでしょう。
 
あなたは awk タイプです。
事務仕事ならお手のもの。応用力もあり、
ベテランからは「使えるやつ」と見られています。
しかしその一方で若手には「考えかたが古い」と思われ
邪険にされることもありそうです。頑なにならず
理解を求めていきましょう。

2003-10-16

メソッド呼び出し括弧の省略

前はメソッド呼び出しの括弧は省略しまくっていたけど、 最近は反動のように括弧を付けるようになった。

原則は以下の通り。

  • 返り値を使うときは付ける。
  • 返り値を使わないときは付けない。

おれは return 書かない派なので、 この括弧規則で返り値のあるなしを暗黙のうちに指定したりする。 たとえば、

def parse( str )
  _parse(str)
end

このときは括弧が付いてるので、 parse は返り値が重要なメソッド。

def m
  do_something arg
end

このときは括弧が付いてないので、 m は返り値に期待してはいけないメソッド。

また以前は include? みたく「?」「!」のついたメソッドには あまり括弧を付けなかったけど、前述の基準に従った結果付けることが多くなった。 例えば File.file? などは必ず返り値を使うだろうから括弧を付けることになる。

if File.file?(path)
  ....

ただし、後述するように、引数がない場合だけは付けない。

返り値を何かに代入する場合も 当然返り値を使っているから原則通り括弧を付ける。 たとえ引数がなくても付ける。

lvar = m(arg)
lvar2 = m2()

何かをするだけの場合は付けない。 たとえ引数がなくても付けない。

def m
  do_something arg
  do_anything
end

とすると当然 require や include や private には括弧を付けなくてよい。

require 'racc/parser'
class C
  include Enumerable
  private :print
end

ただし、まずないとは思うが、require や include の返り値を使うときは やっぱり原則通り括弧を付ける。

例外

「recv.method」のように、レシーバがあり、 引数がないときは例外的に付けない。

イテレータは引数の有無のみで分ける。 引数ありなら付ける (a.inject(i) {...})。 引数なしなら付けない (a.each {...})。 そのかわり、イテレータメソッドの返り値の有無は do...end と {...} の差として出す (返り値を使うときは {...})。

引数に「*」と「&」が付く場合。 これが第一引数に来る場合は括弧を付けないと 警告が出るのでしかたなく付ける。

a.push(*values)
a.each(&block)

第一引数が括弧でくくられているとき。 これもやっぱり警告が出るのでしかたなく付ける。

p((0..3).to_a)

1.8 のパーサがちゃんと解析してくれるからと言ってそれに頼ってはいけない。 仕様はどうせすぐ変わる。

HDD の向き

http://www.tokyo-nazo.net/~tester/title.html#20031016 (もなQぽぉたる from カトゆー家断絶 )

HDD は縦置きでも横置きでも寿命は変わらないらしい。 縦だと短かくなると思ってたよ……。

そういえば AlphaServer800 は HDD が縦入れだな。 エントリサーバだからそんなもんかと思ってたけど、そうでもないのか。

Ruby / 実行速度

さて問題です。 次の二つの Ruby プログラムはどちらが早く終了するでしょうか。 なお「data」は 1 行 20 バイト × 20000 行のテキストファイルとします。

# (1)
h = {}
File.foreach('data') do |line|
  h[line.strip] = true
end
 
# (2)
h = {}
File.readlines('data').map {|line| line.strip }.each do |s|
  h[s] = true
end

答えは自分で実行して確かめてみよう!

(意訳) 環境によって結果が違ってたら嫌だから明言しないでごまかそう

などと書きつつも答えを言ってしまいますが、 家では (2) のほうが高速でした。かなり意外じゃない?

flatten ReFe

~/c/refe % refe Array inject | head                        aamine@harmony
Array < Enumerable#inject
--- inject([init]) {|result, item| ... }   ruby 1.7 feature
 
    最初に初期値 init と self の最初の要素を引数にブロック
    を実行します。2 回目以降のループでは、前のブロックの実行結果と
    self の次の要素を引数に順次ブロックを実行します。そうして最
    後の要素まで繰り返し、最後のブロックの実行結果を返します。
 
    要素が空の場合は init を返します。
 

なんて感じの機能が実装できた。

のだが、まだ何かバグがあるらしく refe String split が検索できなくなったりしている。 もうちょいだな。これが安定したら version 0.8.0 を出そう。

本日のツッコミ (全2件)

ken_u [なんか「返り値を使うときは付ける、返り値を使わないときは付けない」 Visual Basicのようです。(.Netは非知)]

あおき [あ、それ自分でも思ってました (笑)]


2003-10-17

Ruby / 実行速度 (2)

わかった。他のは全て GC が 2 回なのに対して foreach を使ったときは 4 回動いてる。たぶんこれが原因だな。

なんでだろう。統計をとってみた。

# foreach.rb
GC start
malloc_limit    = 0x007a1200
malloc_increase = 0x0007b3bd
freelist        = 0x00000000
newobj          =      14388
freed           =       4392
GC start
malloc_limit    = 0x8fca857b
malloc_increase = 0x0003ae66
freelist        = 0x00000000
newobj          =       7320
freed           =       2928
GC start
malloc_limit    = 0xdf27c882
malloc_increase = 0x0011b9d5
freelist        = 0x00000000
newobj          =      34880
freed           =      13952
GC start
malloc_limit    = 0xefab32f4
malloc_increase = 0x000bea3b
freelist        = 0x00000000
newobj          =      23252
freed           =       9298
program end
malloc_limit    = 0xfa9ba240
malloc_increase = 0x0001f36f
freelist        = 0x401fc5ec
newobj          =       3876
 
# readlines.rb
GC start
malloc_limit    = 0x007a1200
malloc_increase = 0x0010c8f7
freelist        = 0x00000000
newobj          =      10002
freed           =          8
GC start
malloc_limit    = 0xffdc70c1
malloc_increase = 0x001855fa
freelist        = 0x00000000
newobj          =      35044
freed           =          0
program end
malloc_limit    = 0x007a1200
malloc_increase = 0x0006ac72
freelist        = 0x401e78f4
newobj          =      70798

単語解説

  • malloc_limit: これを越えて malloc すると GC が発生する閾値
  • malloc_increase: GC 発生までに malloc/realloc したバイト総数 (GC 起動でリセット)
  • freelist: オブジェクト管理領域 (RVALUE) のリストへのポインタ
  • newobj: GC 発生までに作成されたオブジェクトの数 (GC 起動でリセット)
  • freed: その回の GC で回収できた RVALUE の数

ここからわかることは以下の通り。

  • すべての GC が freelist (オブジェクト管理領域) 枯渇によって起動している。 (freelist が毎回 0=NULL になっているから)
  • malloc のトータルは readlines のほうが多い。 (malloc_increase を合計すれば総 malloc 量がわかる)
  • 生成したオブジェクト総数も readlines.rb のほうが多い。
  • readlines.rb では初回の GC でほとんどオブジェクトを回収できておらず、 それに伴って malloc_limit も激増している。

つまり、readlines.rb のほうが速いのはメモリ使用量が少ないからでもなく オブジェクト生成数が少ないからでもなく、オブジェクト生成パターンが 現在の Ruby のガーベージコレクタのアルゴリズムとマッチしてしまった からだと考えられる。そのパターンとは、

  • 回収できないオブジェクト数が一気に増えて一気に減る

である。下手にちまちまとオブジェクトを回収できてしまうと GC が平坦に発生してしまう。 負荷をかけるときは容赦なく負荷をかけて、 早いうちに ruby に回収をあきらめさせたほうがよいのだ。

というのが結論だけど、どうだろう?

おまけ

今回使った GC 統計報告パッチ (CVS HEAD 用)

64bit マシンならそれくらいは積んでるかもしらん

なんか、malloc_limit がでかすぎる? これだと閾値が 3GB ってことになるな。

Ruby / 実行速度 (3)

いや待てよ、そもそも GC が原因であると特定していないじゃないか。 GC を切って測定してみるべきだな。

% time ruby -ramstd/nogc foreach.rb
0.30s user 0.04s system 101% cpu 0.335 total
% time ruby -ramstd/nogc readlines.rb
0.30s user 0.05s system 101% cpu 0.344 total

ほとんど変わらないな。やっぱ GC が原因か。


2003-10-20

時間が飛んだ

寝たのが日曜の午前 3 時で起きたのが月曜の午前 3 時。 おかしい、おかしいぞっ!

ボスにスタンド攻撃されてる? (血の雫の数で判別)

そういえばスタンド占いはフーファイターズだった。 後半は FF と略されてしまう憐れなやつ。

ところで「アリアリアリ」ときたら「アリーヴェデルチ!」まで書いてほしかったと思うわたしは第五部好きです。

さらに時間が飛んだ

そしてまた寝るやつ。

ReFe

http://yowaken.dip.jp/tdiary/20031017.html#p03

バグですな……。なんか、最初考えたときには インスタンスメソッドだけ継承すればいいや、とか思ってたんですが、 よくよく考えると特異メソッドも継承するべきなのでした。

しまった! すると今度はモジュールの特異メソッドを継承してしまっている予感!

Alpha

http://slashdot.jp/article.pl?sid=03/10/18/2148233&topic=25

Alpha が終わったか……。あーあ。

RHG 読書会 reloaded #3

今回はやたらと方向性がかっとんでたな。 記録はいつも通り RWiki にあります。

http://rwiki.jin.gr.jp/cgi-bin/rw-cgi.rb?cmd=view;name=RHG%C6%C9%BD%F1%B2%F1%3A%3A%C5%EC%B5%FE+Reloaded

そういえば、次は Ruby のプログラムをみんなで読んでみたらどうだろう、 という話が出てました。話に出てたのは Rucheme だっけ? まあなんでもいいんですけど、とにかく何か一つ爼上にあげて、 みんなで文句をつけまくるのが主眼です。

窓使いの憂鬱

http://mayu.sourceforge.net/ja/index.html

いつのまにか XP 対応したんですね。 これでいつ XP にしても安心だ。

(from 裏・kdoo )

ruby-dev summary index

自分で作っておきながら存在を忘れていたのですが、 ruby-dev summary の目次を作りました。

半自動更新で、今後も随時アップデートされる予定です。


2003-10-22

Linux / USB タブレットを使う (1) 準備

どうしても Linux でタブレットが使いたくなった。 ところが手持ちのタブレットは USB 接続なので、 USB タブレットを使う方法を調べた。

まず基礎情報から。持っているタブレットは Wacom の FAVO F510 というやつ。型番は ET-0507-U (描画領域 B6 サイズ、シルバー) である。 あとで正確に調べたところによると ET-0507-UV2.01 というらしい。 V2.01 の部分はハードウェアのリビジョンだ。

とりあえず「Linux USB タブレット Wacom FAVO」で Google すると 次のページが見付かった。

家のソフトウェア的な条件はと言うと、

  • Linux カーネルは 2.4.22
  • wacom.o はコンパイル済
  • XFree86 4.3.0

で、まず問題ないであろう部類に入る。

Linux / USB タブレットを使う (2) 特殊事情を解決する

問題ないであろう部類なのだが事情により X の Wacom ドライバがない。 /usr/include/linux にまだ Linux 2.2 のヘッダファイルがあるため、 Wacom ドライバは make できなかったのだ。 そのときは Makefile を書き換えて wacom ドライバをスキップすることで make を通してしまったので、どうにかしなければならない。

そこで、とりあえず /usr/include/{asm,linux} を一瞬だけ Linux 2.4 のものに差し替えて Wacom ドライバだけコンパイルしてみることにする。 それでいいのどうかは知らない。 libc から何から全部リコンパイルするなんて面倒だからしかたがない (?)。

やってみたらコンパイルは通った。できた wacom_drv.o を /usr/X11R6/lib/modules/input にコピーしておく。

Linux / USB タブレットを使う (3) カーネルレベルで認識させる

まずデバイスドライバをロードする。

# modprobe wacom

dmesg などを見てエラーが起きていないか確認。

次にデバイスファイルを確認して、なければ作る。

# mkdir /dev/usb
# mknod /dev/usb/ttyUSB0 c 188 0
# mknod /dev/usb/ttyUSB1 c 188 1
# mknod /dev/usb/ttyUSB2 c 188 2
# mknod /dev/usb/ttyUSB3 c 188 3
 
# mkdir /dev/input
# mknod /dev/input/event0 c 13 64
# mknod /dev/input/event1 c 13 65
# mknod /dev/input/event2 c 13 66
# mknod /dev/input/event3 c 13 67
# mknod /dev/input/mice c 13 63
# mknod /dev/input/mouse0 c 13 32

うちには /dev/usb/* はあったが /dev/input/* がなかった。

さらに詳しく USB の動作を確認するには、 カーネルの「USB verbose なんたら」ってオプションをオンにして

# modprobe usbdevfs
# mount -t usbdevfs none /proc/bus/usb

を実行し、cat /proc/bus/usb/devises してみる。 USB デバイスの情報がどかどか出てくるから、その中に目的のデバイスがあるか見る。

Linux / USB タブレットを使う (4) X レベルで認識させる

次に X を設定する。/etc/X11/XF86Config に InputDevice セクションを増やして、ServerLayout にそのデバイスを追加する。

# Wacom tablet FAVO2
Section "InputDevice"
   Identifier  "FavoStylus"
   Driver      "wacom"
   Option      "Device" "/dev/input/event0"
   Option      "Type" "stylus"
   Option      "Mode" "Absolute"
   Option      "USB" "on"
EndSection
Section "InputDevice"
   Identifier  "FavoEraser"
   Driver      "wacom"
   Option      "Device" "/dev/input/event0"
   Option      "Type" "eraser"
   Option      "Mode" "Absolute"
   Option      "AlwaysCore"
   Option      "USB" "on"
EndSection
Section "InputDevice"
   Identifier  "FavoMouse"
   Driver      "wacom"
   Option      "Device" "/dev/input/event0"
   Option      "Type" "cursor"
   Option      "Mode" "Relative"
   Option      "AlwaysCore"
   Option      "USB" "on"
EndSection
 
Section "ServerLayout"
    Identifier	"Main Layout"
    Screen	"MainScreen"
    InputDevice "MainKeyboard" "CoreKeyboard"
    InputDevice	"MainMouse" "CorePointer"
    # ここの三行を追加した
    InputDevice "FavoStylus" "AlwaysCore"
    InputDevice "FavoEraser" "AlwaysCore"
    InputDevice "FavoMouse" "AlwaysCore"
EndSection

X は起動中にタブレットが増えても認識してくれないので、 USB タブレットをつないだあと X を再起動しなければならない。ださい。

再起動する。だめだ。タブレットが全然動作してない。

Linux / USB タブレットを使う (5) 雲行きが怪しくなってきた

状態は以下の通り。

  • タブレットのランプは点灯している
  • dmesg も X のログも異常なし
  • 他のデバイスの動作もおかしくはなってない
  • cat /dev/input/event0 してペンを動かすといろいろ出てくるので信号は来てるっぽい
  • しかしペンを動かしてもカーソルは動かない

さらに Google してみると、 タブレットが rev1.2 だとカーネルドライバにパッチが必要らしいことがわかった。 ハードウェアのリビジョンは前述の /proc/bus/usb/devices で調べられる。 メッセージはいろいろ出るけど FAVO に関係するのは次の部分だけのようだ。

T:  Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
D:  Ver= 1.01 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=056a ProdID=0012 Rev= 2.03
S:  Manufacturer=WACOM
S:  Product=ET-0507-UV2.0-3
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr= 40mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=wacom
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms

Rev 2.03 だとお?! うわあ、1.2 でもだめらしいのに、 さらにメジャーバージョンアップしてやがる。これはまずいな。

しかしそれでもまだめげない。 まず X の Wacom ドライバ開発元の人のところから最新のソースコードを持ってきてみる。

ファイルのリビジョンは Linux 2.4.22 とも XFree 4.3 とも同じだ。 しかし diff してみると微妙にネットにあるやつのほうが新しいような気がする。 とりあえずこれでいこう。

~/src/xfree86-4.3.0/programs/Xserver/hw/drivers/input/wacom % cp ~/xf86Wacom.c .
~/src/xfree86-4.3.0/programs/Xserver/hw/drivers/input/wacom % make
~/src/xfree86-4.3.0/programs/Xserver/hw/drivers/input/wacom % sudo cp wacom_drv.o /usr/X11R6/lib/modules/input

さらにもう一度 X を再起動。Windows かよ。

まだだめだ。状況変わらず。

Linux / USB タブレットを使う (6) 光明が見えた

次は別の X ドライバ (graphireUSB) を使ってみる。 graphire とは、あちらの国での FAVO の商品名らしい。

ドライバを make。ファイルを xf86Wacom.c に上書きして make すればいい。

~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % cp ~/graphireUSB.c xf86Wacom.c
~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % make
~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % sudo cp wacom_drv.o /usr/X11R6/lib/modules/input/graphireUSB_drv.o

そして XF86Config を次のように直す。

Section "InputDevice"
   Identifier	"FavoStylus"
   Driver	"graphireUSB"
   Option	"Device" "/dev/input/event0"
   Option	"Type" "gstylus"
   Option	"Mode" "Absolute"
   Option	"USB" "on"
EndSection
Section "InputDevice"
   Identifier	"FavoEraser"
   Driver	"graphireUSB"
   Option	"Device" "/dev/input/event0"
   Option	"Type" "geraser"
   Option	"Mode" "Absolute"
   Option	"AlwaysCore"
   Option	"USB" "on"
EndSection
Section "InputDevice"
   Identifier	"FavoMouse"
   Driver	"graphireUSB"
   Option	"Device" "/dev/input/event0"
   Option	"Type" "gmouse"
   Option	"Mode" "Relative"
   Option	"AlwaysCore"
   Option	"USB" "on"
EndSection

Driver と Type が変わってる。 そしたら X を再起動。

よし! カーソル動いたー!

Linux / USB タブレットを使う (7) 問題はまだ続く

と思ったらまだ問題があった。 タブレットのペン領域が狭く認識されているらしく、 右と下の 1/3 くらいにペンを置くと画面からはみだしてしまう。 いくらなんでもこれはだめだ。

しかし今回はそのためのドライバオプションがある (っぽい)。 /etc/X11/XF86Config の Section InputDevice で以下のように MaxX, MaxY オプションを追加する。

Section "InputDevice"
   Identifier	"FavoStylus"
   Driver	"graphireUSB"
   Option	"Device" "/dev/input/event0"
   Option	"Type" "gstylus"
   Option	"Mode" "Absolute"
   Option	"USB" "on"
   Option	"MaxX" "14175"
   Option	"MaxY" "10106"
EndSection

ちなみにここの MaxX と MaxY は物理的にものさしで計測した数値から計算している。 ドライバが MaxX=10206, MaxY=7422 と認識していたので、 「実際の長さ(175mm) / 認識している長さ(126mm) * 10206」てな感じで弾き出した。

これでもう一度 X を再起動。本当に Windows ぽいな。

……だめだ、まだ直らないよパトラッシュ……

Linux / USB タブレットを使う (8) ぶちきれ、そして解決

くそう、俺に逆らうとはいい度胸だな。 パラメータをハードコーディングしてやる!

~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % diff xf86Wacom.c.graphireusb{.org,}
--- xf86Wacom.c.graphireusb.org 2003-10-22 01:34:44.000000000 +0900
+++ xf86Wacom.c.graphireusb     2003-10-22 01:49:42.000000000 +0900
@@ -1566,6 +1566,12 @@ xf86GraphireUSBOpen(LocalDevicePtr       local
     common->graphireUSBMaxZ = 511; /* FIXME: 31 for mice */
     common->graphireUSBResolX = 1270; /* default value */
     common->graphireUSBResolY = 1270; /* default value */
+#if 1 /* aamine */
+    common->graphireUSBMaxX = 14050;
+    common->graphireUSBMaxY = 10140;
+    common->graphireUSBResolX = 1270;
+    common->graphireUSBResolY = 1270;
+#endif
 
     DBG(2, ErrorF("setup is max X=%d max Y=%d resol X=%d resol Y=%d\n",
                  common->graphireUSBMaxX, common->graphireUSBMaxY, common->graphireUSBResolX,
 
~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % ln -sf xf86Wacom.c.graphireUSB xf86Wacom.c
~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % make
~/src/xfree86-4.3.0/programs/Xserver/hw/xfree86/input/wacom % sudo cp wacom_drv.o /usr/X11R6/lib/modules/input/graphireUSB_drv.o

再起動! 動作確認! おっけー!

かくして最新の USB タブレットも Linux で動作することが確認されたのであった。(完)


2003-10-23

URL 変わりました

この日記をサーバー内で移動しました。 新しい URL は

です。旧 URL は全部リダイレクトしているので Not Found になることはないと思います。 もしなにか問題があればツッコミ入れてください。

あー、やっとこれで URL が短くなった。 そもそもなんでホームディレクトリに置いたのか覚えてないんだよなあ……。

Ripper

うあ、FreeRIDE の人からも Ripper 新版の催促が来てしまった。 いっちょ気合い入れて作るかな。

でも今日は眠いから夜食食べて寝る。

(10:00)

起きた

昼に寝て夜に起きる。見事なダメ人間っぷりだ。

あー、そうかぁ。URL 変えるとアンテナが更新時刻を取れなくなるんだな。 せっかくだからしばらく潜伏してみよう。いつバレるかなあ。


2003-10-24

Ripper

Ripper 新版作成中。 Ruby の parse.y をそのまま使えるようにしつつ Ripper のコードを埋め込んでみようと思う。

……超後悔した。

Ripper (2)

引き続き後悔中。

ちょっと思ったんだけど、クラス名は Ripper より Ruby::Parser のほうがよいのではなかろうか?

Ripper (3)

パーサアクションだけであと 1500 行もあるのか……。 急激に眠くなってきた。

ところでパーサつながりで Racc を改造する話を思い出した。 なんか net/http の要望とかパッチもたくさんもらってるし、 非常にあれだね。忙しいみたいだね (他人事)。

まあ文明開闢以来このかた、 なにかしらやることがあるほうが無職ひきこもり生活よりは三百倍いいと決まってますが、 そんなこと言って元がマイナスだったらどうするんだょとか思ったりもするわけですが、 でもマイナスの人生ってなんだろうとか考え出すとそれはそれで ヤバげな境地に到達してしまいそうですので、 現代日本社会の病理を反映した軽薄で殺那的な認識でお茶を濁そうと思います。

という文章を見て睡眠時間が不足していると喝破できるようであれば あなたはかなりの日記まにあです。まにあっくです。 えにあっくではありません。

おお! マニアックと ENIAC って似てるね!

そんなのどうでもいいんです。

Ripper (4)

また寝て、起きた。(17:00)

わたしが発作的に自宅のベランダからダイヴしたり餓死したりした場合に備えて (状況設定が微妙にリアルだな)、Ripper の作りかたを書いておきます。

  • parse.y をコピーしてくる
  • extern 関数を #ifndef RIPPER で消す
  • NODE・シンボル・lvar・dvar 関連の関数も必要ないので #ifndef RIPPER で消す
  • まだ必要なグローバル変数 (extern/static とも) を全部構造体に移し、 そっちを参照するようマクロを書きまくる
  • ripper 独自の関数をちょっと追加 (主に入力系統)
  • dispatch / sdispatch しまくる

そうそう、最後のが問題なんだった。この段階は自動判別が難しく、 アクションから残すコードと残さないコードを人力で選ばないといけない。 例えば NODE 関連のコードは全て消すか置き換えるかしないといけないが、 lex_state などは残さないとならない。

これまではアクションを完全に書き換えていたのだが、 それだと parse.y が共有できないので、今回はこんなふうにしてみた。

program         :  {
                        lex_state = EXPR_BEG;
                        top_local_init();
                        class_nest = !toplevel_p();
                    /*%
                        lex_state = EXPR_BEG;
                        class_nest = !toplevel_p();
                        $$ = Qnil;
                    %*/
                    }

コメント外が Ruby 用で /*%〜%*/ が Ripper 用。 #ifdef RIPPER だと読みにくすぎることが判明したのでこうしてみました。 どうせ Ruby があるのは前提なので、プリプロセスしまくります。

dispatch* (イベント生成マクロ) を使う例はこんな感じ。

stmt            : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
                    {
                        $$ = NEW_ALIAS($2, $4);
                    /*%
                        $$ = dispatch2(alias, $2, $4);
                    %*/
                    }

引数の数によって名前が変わるのはちょっとダサいな。

可変長引数マクロ

C の可変長引数マクロって C99 だっけ。 こういうの↓

#define m(fmt, ...) vprintf(fmt, __VA_ARGS__)

やっぱ C99 か。ちょい新しすぎるな。

どっちにしても va_list を使うには どこかで引数の数を指定する必要があるのね。 あきらめよう。

Ripper (5)

やっとアクションの変更が終わった。 今日はここまで。

本日のツッコミ (全3件)

ただただし [えっ。賞味期限切れ食品が不足してるのかと……]

きしもと%薀蓄・昔話系 [MANIAC です → http://www.lanl.gov/worldview/welcome/history/22_computers.html

ほんっとーにどうでもいいですね.]

あおき [賞味期限切れ食物は常時補給しているので問題ありません]


2003-10-25

Ripper 0.1 (1)

まだ書いてる。 早くコンパイラくらい通るようになってくれないと モチベーションが続かないよー。

ちなみに今度のバージョンは 0.1 で、互換性はまったくない。

代わりと言っちゃなんだが、これまでよりも高級な API を用意して、 今後はそっちで互換性を保っていこうと思う。 例えば

  • Ruby::Parser.parse(string) 一発で構文木生成とか
  • 特定の予約語からそれに対応する end までを取り出すとか
  • 特定のトークンを囲む最小のブロックを検出するとか
  • rdoc を抜きだすとか

妄想するだけならタダだからなっ!


2003-10-26

Apache 入れ換え

急に i.loveruby.net にアクセスできなくなったから何かと思ったら、 Apache が止まっていた。わかってみると非常なアホな理由であった。

  • Apache を Debian のから独自ビルドにしようと思ってコンパイルした。
  • それを /usr/local 以下に入れた。
  • httpd.conf をそれに合わせて書き換えた。
  • 新しい Apache を起動しようかと思ったが、もうちょっと人の少ない時間帯にやることにした。
  • そのまま忘れた。
  • ログのローテーションのときに SIGHUP を食らって止まった。
  • しかし httpd.conf が既に新しい Apache に合わせて変更されていたためライブラリが合わず、起動できないままになる

重要デーモンが止まったらメールしてくれるような仕掛けが必要だなあ……。

Ripper 0.1 (2)

  • コンパイルが通った。
  • SEGV せずにパースできるようになった。

あとはスキャナイベントをディスパッチしまくればなんとか復帰できそうだ。

……それがいちばん大変なんだけどね。

Ripper 0.1 (3)

SEGV しないなんて大嘘じゃん。 ID だの NODE* だのが露出しまくり (笑)

信じらんない……

あのさー、Rubyで

m = 9
def m(a) a end
p(m +1)

def m(a) a end
p(m +1)

の結果が違うって知ってた?

多少 Ripper 0.1っぽいもの

なんとなく動いているような気がする。 今日は脳を酷使して疲れたからもう寝よう。 見てみたい人は

% cvs -d :pserver:anonymous@cvs.loveruby.net:/src co ripper

でどうぞ。 バグはたくさんありすぎるのであんまり真面目に報告しなくていいです。

前回は地道にスキャナイベントを全部手で書いてたんだけど、 今回はオートマティックなアイデアが浮かんでしまったので手ぇ抜いた。 一言で言うならば、yylex() する前と後では入力バッファにスペース+ トークン一個分の文字列が残ってるに違いない作戦。

ちなみに -DRIPPER 付けずにコンパイルすると そのまま ruby の parse.y になります、 そのはずです、そうなるといいね (謎の三段活用)

本日のツッコミ (全4件)

向井 [1.6.8 では同じ結果(1を表示)でした。でも1.6.8では、前者を p(m + 1) にす
ると、10を表示してくれます。そっちの方が居心地悪いので、最新はましになっ
たような。
ってそれで気付いたんですが、Rubyの入門書によくある a + b と a +b は違
う、っていう話は必ずしも成立しなくなってるんですね。]

kawaji [http://www.cman.jp/network/
とか]

あおき [いやー、そこまでは。お金ないですし。
一時間ごとに ps ax | grep httpd してメール、
てのを cron に仕込むだけにしときました。]

kawaji [あ、いや、無料なんですけどね。
でも他に依存しない管理法があれば、それが最適ですね。]


2003-10-27

寝すぎた

いつものことですが今日は特に寝すぎました。 01:00 に寝て起きたのが 17:00 ってなんだそりゃ。 もうこんなんじゃ何もやる気が起きない (言いわけ)

m +1

あ、そうなんです、「m +1」が二項演算になるのは 1.8 からです。 細かく言うと 2002-11-14 の parse.y:1.227 からですね。 以下簡単に挙動をまとめました。

1.6.x
m+1       # 二項演算
m  +  1   # 二項演算
m  +1     # メソッド
 
1.8
m+1       # 二項演算
m  +  1   # 二項演算
m  +1     # ローカル変数 m がある   → 二項演算
m  +1     # ローカル変数 m が未定義 → メソッド

今日発見した拡張ライブラリ開発の小技

  • ruby extconf.rb 直後から CFLAGS = -g -Wall にする

rbconfig.rb をカレントディレクトリにコピーして書き換えておけばいい。

本日のツッコミ (全1件)

あおき [この日のツッコミは違法なファイルのURLを含むため削除しました。]


<前月 | 最新 | 次月>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|