メール → tDiary ブリッジのテストです。
うまくいったらしい。えらく時間がかかってしまった。
いやね、これまでもずっとメール経由で更新してきたんですが、 間にプリプロセッサを狭むために公式の posttdiary.rb とは 違うプログラムを使ってるんですよ。それをちゃんと直さないと 日記が更新できないという罠にはまってました。
と言ったそばからまた改造をはじめるわたしであった。まる。
えーっと、何だっけ。短期 ToDo
ungets したくない?
うーむ、知らない間にかなり中身が変わっている……。 しかもテストに通らない。extend かそれとも define_method が悪いのか。
原因判明。define_method の中で super するとスーパークラスの別のメソッドを呼べなくなる。 普通に def すると呼べるので、define_method がなんらかのきっかけになっているようだ。
module Super def test m() # define_method を使っているとここで失敗する end def m puts 'OK' end end module M include Super #def test # こっちだとOK define_method(:test) do # こっちだとNG super end end class C include M end C.new.test
とりあえず module_eval に戻しておくとしよう。
しかし、おれって凄い確率で Ruby の秘孔を突いてるような気がするなあ。 ここまで運がいいとちょっと考えてしまうね。
あー、そういえば RHG 書いてる途中で ARGF が EOF に ならなくなるバグを見付けたんだった。条件を追ってみよう。
やっぱりまだあるじゃん……
改修と言えば setup.rb も酷いのでどうにかしたいな。 どう見ても継承使いすぎだ。
ファイナルファンタジーのシステムはシリーズごとに スクラッチから書き直してるそうですよ。
かなり Solaris が欲しくなってきた。 もちろん Sparc 込みで。 Ultra1 なら 2 万もしないので余裕だ。
どうせなら Alpha にも Digital UNIX を入れたいな。 FreeBSD なら x86 でも動くじゃない。
一日寝てみた。
ありゃ、[ruby-dev:19544] FileUtils.pwd に返事してなかったか。 でも今日は半年ぶりに遊びに行くのでまた後で返事しまーす。
煮たててしまった……しょんぼり。
ぐおっ、/usr/lib/ruby/1.8 のパーミッションが 777 になってるー。 もしかしてこれが噂の ftools → fileutils の副作用かっ。 これはヤバいな。なんとかしよう。
あれ? なんで instruby.rb で umask(0) してるんだろう。 うーむ。
とりあえず fileutils 側では mkdir にモードを渡せるようにすればいいだろうか。 うーん、こうなるとオプションにはハッシュを使ったほうがいいように思える。 まだ間に合うから今のうちに思い切って変えるべきか。
21 時間も寝てしまった……。後悔を通り越して驚愕してしまうね。
メールの反応などなど各種遅れまくっております。すみません。 原稿書きは終わったんですが、個人的な事情でちょっと混乱してるもので、 全体的に処理が遅くなってます。
行ってきました。参加者の皆さん、御苦労様でした。 とても面白かったです。また次回も行きますよー。
しかし、自分の書いた本で読書会まで開かれてしまうというのは ちょっと想像してなかったですね。ははあ、そういうこともあるか、 と思うだけであんまり感動とかはしないんですが (嘘がつけないやつ)。
ただまあ、RHG の場合は元の ruby のパワーがかなり大きいですよね。 RHG はあくまで ruby を読むきっかけを作ること、読む敷居を下げることとの二点に 存在意義があるんであって、元の ruby がダメだったらたぶん全然売れないし 読まれないでしょう。そういう意味でも「やっぱり ruby はすごかった」 (みんな読みたがっていた) ということじゃないでしょうか。
あ、これは別に卑下してるわけでも謙遜してるわけでもありません。 敷居を下げるというのはまた別に重要なことですから、それはそれでいいんです。 特に間違いがいっぱいあるから叩きまくって考えるにはいい素材じゃないかな? (汗)
あ、そうだ、読書会の内容はここ↓にあります。
田中哲さんが今回分のメモを書いてくださったのでそこに少し足しました。
Ruby に関係ないものでは Haskell 関連が一番興味深かったです。 ML、Prolog ともども気になってるんですが、 何から手を付けたらいいのかよくわからない……。
ちなみにこないだまで反応が遅かったのは本を書いてたからです。 もう書き終わったからいいと思うんで言っちゃうと、Java を使ったプログラミング入門本です。 題名は「Java入門本を買う前に読む本」とかなんとか、そんな感じだったかな。
いちおう Java 自体の解説もしてるんですが、本題はプログラミング全体の概説です。 たとえば「機械語ってのがあるんだ」とか「プログラム書いたらデバッグする」とか 「きれいなプログラムは大切だ」とか。でも秘かに第一部からテストファーストで コードを書いてたりするあたり、かなりイッちゃってます。
そういえば昨日は「最近は JSP でプログラム入門するらしい」 という話がありましたけど、マジなんですかね。ていうかそれでいいんですかね。 前提が増えるとバグが出たときに困らないかなあ?
「アスキー文字」+「バレンタイン」って……何?
■
表題は [『Javaを独習する前に読む本』だだだ
→http://www.ascii.co.jp/books/detail/4-7561/4-7561-4252-4.html
-- SugHimsi]
反応が遅れます。
とか言いつつ Lisp の歴史に関する論文なんて読んでるし。 バカですかわたしは。
RHG 読書会で「Lisp には最初から GC があったわけじゃないだろう」という話が 出たので、それを調べようと思ったんですが、ちょと深入りしすぎました。 結論だけ言うと、アイデアはあったものの、Lisp 1 の実装には GC は 入っていなかったようです。
あああ、欲望のままに Haskell の本を注文してしまった……。がくり。 ついでに有名な GC 本も頼んだ。てゆーかまだ買ってなかったのかおまえは! (だって金がなかったんだもん)
あーもう、なんで知らないうちに Haskell echo とか Haskell cat とか 書き始めてんだよっ! つーか Haskell わかんねえ! ぜんっぜんわかんねえ! RWiki の RHG 読書会ページ経由で教えてもらった山下さんのページ↓を見ながら やってるんだけども、これは強烈にムズいわ。
んでもいきますよー。 とりあえず Hello, World! は基本ってことで。
module Main (main) where main :: IO () main = putStrLn "Hello, World!"
次に Haskell echo。
module Main where import System main :: IO () main = do { args <- getArgs ; mapM_ (\a -> putStrLn a) args }
このあたりで「args はいらないんじゃないかなー」と思い込んで 「<-」を消し、ハマる罠。getArgs が最初からリストを返すから、 それじゃだめなんですね……。ちなみに mapM_ の「M_」もまだ謎なんだけど。
んで三つめは Haskell cat。もう何がなんだかわからない。 屋下屋を架す、みたいな。元々ない知識を総動員してみました。
module Main where import System import IO main :: IO () main = do args <- getArgs case args of [] -> catFile stdin args -> mapM_ (\a -> do f <- openFile a ReadMode catFile f hClose f) args catFile :: Handle -> IO () catFile f = do eof <- hIsEOF f if eof then return () else do c <- hGetChar f hPutChar stdout c catFile f
特に catFile の型が何なのかさっぱりわからんかった。 省略すれば推測してくれるんだけど、なんか負けた気分になるし……。 しかしエラーメッセージが不親切でデバッグが非常にやりづらい。 Ruby みたくスタックトレースが出るのって楽だなあ、とつくづく思う。
あ、このへんで気付いたんだけど、Haskell って indent sensitive なのね。 インデント消すとエラーになる。しかもコーディングルールが謎。 特に else の位置がかなり気持ち悪い。 (ちなみに if よりネストを深くすれば次の行にも置けるようだ)
うーん、でもなんかわかってきたような気がする。 catFile ならファイルハンドルを無「()」のストリーム (IO) に変換するから 「IO ()」になるということだな。文字 (Char) のストリーム (IO) なら IO Char で、 行 (String) のストリーム (IO) なら IO String になるんだ。きっと。
ぐあ…… Haskell cat、端末が stdin だと Ctrl-D が効かない。
% cat file | ./cat.hs
だと OK。
% ./cat.hs aaaa ^D
だと NG。なんでだろう。
RWiki に適当に書いておいた Haskell の疑問に答えが! どなたか存じませんがありがとうございます。
リファレンスとかは揃ってるんですね。量は多いですが、 ここからたどれるものを読んでいけば一通り理解できそうです。
しかしモナドとかはやっぱりどうも……。 きっと、なんでそういうものが必要なのかわからないとダメなんでしょうね。 んで、そういうことがわかるにはプログラムを書かなきゃいけないと。
■ とおりすがり [昔C++のSTLプログラミングが流行ってた頃、関数型言語を研究している先輩が「手続き型言語ではmapのことをイテレータと呼ぶのか〜。」と言っていたのを思い出しました。]
■ Tosh [Monad はあくまで抽象化の手段としてあるのであって「必要」ではないんじゃないかと思います。IO使うならストリームとか他に手段はあるし。Haskell のチュートリアルとかには Monad の例は大抵 IO Monad になっているので Monad は非正格な言語で IO を扱うためのものだと誤解しがちだけど、そのためのものではないです。しかもIO Monadは特別わかりづらい (IO Monad の定義が Haskell 自身では書けないため) ので State Transformer Monad とかを例に見た方がよいと思います。 たぶん青木さんなら ST Monad をちょっと調べてから Monadic parser combinator とかを見るとかなり感動できるでしょう。]
■ Tosh [あ、Toshは別にHaskell使いでもなんでもないので上のは鵜呑みにしないでください。]
■ のりつぐ [有名な GC 本の題名 教えて下さい…(AmazonとかでTopに出る奴?)]
■
kjana [The Haskell Bookshelf
http://haskell.org/bookshelf/
より....
A Gentle Introduction to Haskell
http://haskell.org/tutorial/
What the hell are Monads?
http://www.dcs.gla.ac.uk/~nww/Monad.html
とか読むとなんとなくわかった気になれます.で,後で
語ろうとすると全然わかってないのに気づく,と :-P]
ああああ、また 20 時間も寝てしまった。 どうしてこういうことになるんだ。 おれのバカバカバカ〜。
そうです、Amazon で一番上に来るやつです。
"Garbage Collection: Algorithms for Automatic Dynamic Memory Management" Richard Jones / Rafael Lins, John Wiley & Sons, 1996
ちなみに Haskell のほうは 「やさしい Haskell 入門」 のお勧めにあった "Introduction to Functional Programming using Haskell" を 買ってみました。
http://i.loveruby.net/ja/haskell/head.hs
module Main where import System import IO main :: IO () main = do args <- getArgs case args of [] -> headFile stdin 10 args -> mapM_ (\a -> do f <- openFile a ReadMode headFile f 10 hClose f) args headFile :: Handle -> Integer -> IO () headFile f n = if n == 0 then return () else do eof <- hIsEOF f if eof then return () else do line <- hGetLine f putStrLn line headFile f (n-1)
cat を応用すればすぐだろうと思ったら 2 引数関数ではまる罠。 自動的にカリー化 (※) されるなんて、そりゃー予測できないよ……。
※ 関数が複数の引数を持つとき、それを一引数の関数のネストに分解すること。
(lambda (a b) ....) ↓ (lambda (a) (lambda (b) ....)
という感じ。
しかもまたもや eof <- hIsEOF を消そうとしてはまるバカ……。 だってさー、いかにも
eof <- hIsEOF f if eof then .... ↓ if hIsEOF f then ....
ってできそうじゃない?! できると思うでしょ?! でもできないんだよなー。
なんでいきなり UNIX コマンドかというと、 自分で実際に使えるものが一番インセンティブが働くからです。 つまらん計算したって全然面白くないっす!
そういうわけでとりあえずの目標を rd2html のサブセットと決めました。
うーん、8 時間悩んだあげく Monad はなんとなくわかってきた。 ようするに「次の世界ジェネレータ」みたいなもんか。 Y コンビネータをやっておいたのがよかったな。 あれの連想でなんとなくわかる。 あっちは関数を連続生成してたのに対して、 こっちはプログラム実行環境を連続生成してるわけだ。
ただ、現実的にそれを外す方法がわかんないんだよー! IO から読むと全部「IO x」の型になってるから、 普通の関数が全く適用できない。なんとか IO を外したいんだけどなあ。
ででででで、できたーーー! 12 時間もかかってしまった……。
http://i.loveruby.net/ja/haskell/tail.hs
module Main where import System import IO main :: IO () main = do args <- getArgs case args of [] -> doTailFile stdin args -> mapM_ (\a -> do f <- openFile a ReadMode doTailFile f hClose f) args doTailFile :: Handle -> IO () doTailFile f = do all <- hGetContents f rows <- return (lines all) mapM_ (\line -> putStrLn line) (tailFile rows (replicate 10 "")) tailFile :: [String] -> [String] -> [String] tailFile [] buf = buf tailFile (x:xs) buf = tailFile xs (concat [(tail buf),[x]])
10 行以下のファイルを tail すると空行で埋められちゃうんだけど、 そこは勘弁してくだせい。あいかわらず端末が stdin だとうまく動かない。
さ、これでスッキリしたから朝ごはん食べて、 今度こそ fileutils と setup.rb をいじるかな。
14 時だけどね。
あ、ちなみにさっきの「IO が付くからどーたらこーたら」ってのは 勘違いですね。do と <- を使って束縛すればあとは普通に処理できるみたい。
■ tosh [(???) IO ??????????????????????????]
■
tosh [すいません、失敗しました。
たぶん IO は外せません。外せたら実行順序が保てなくなるはずです。]
■
あおき [ああ、やっぱりそうなんですね。なんか変だなーとは思ったんですが。
しかし、一回 IO が付いたら二度と外れないってことは、
ずーっとひきずってまわらないといけないのか。]
■
nobsun [一度でもこの世ならぬものを覗いたらずっとそれをひきずるのが
掟なのだ。だが、とっておきの呪文をさずけよう。
unsafePerformIO :: IO a -> a
ただし、これをつかったことを純粋Functioalistに知られてはならぬ。もし、知られてしまったら。。。あなおそろしや]
■
nobsun [ghc --make tail.lhs -o hstail
とかして、コンパイルしてバイナリ hstail をつくれば、標準入力もうまく動作するかも。
runhugsではうまく動作しませんねぇ。知らんかった。^^;]
http://www.rubycolor.org/maki/d/200302b.html#19_t1
あ、高橋さん版の head が。 Haskell の遅延評価ってカッコいいですよね。 hGetContents とかも、ファイルの中身を全部読んでいるように見せかけて、 実はアクセスしたときに初めて読んでくれるという……。 mmap とちょっと似てるかな。
あ、コンパイルしたら端末からの入力でも動きました。 ということは runhugs が原因なのか。なんでだろうなあ。 もしかして raw モードになってるとかそういう話か? (それはそれで嫌だな)
うっ……なんか名前からしてヤヴァそうな…… ^^;;;
そういえば Gentle ... にもちょこっとだけ 存在がほのめかしてありましたね。 デバッグ用として、ルール外で IO する裏技が。
をを! 山下さん版 tail カコイイ! コードのコア部分はこんなかんじ。
doTail :: IO String -> IO () doTail ios = do { cs <- ios ; putStr $ unlines $ reverse $ take 10 $ reverse $ lines cs }
文法まわりは設定次第で他にもいろいろ書きかたがあるらしい。
うーむ、慣れるとずいぶんきれいに書けるんだなあ。 というより今回はアルゴリズムの発想が悪かったか。 全部オンメモリにしない点に無駄にこだわりすぎた。
ちなみに
... $ take 10 $ ...
というふうに関数を 1 引数分だけ適用できるとこもなかなか凄い。 第 2 引数だけ後から与えて返り値を取れる。
■ nobsun [拙のtailコードなども御観賞ください(って、そんな大したもんじゃないけど、らしくは書いてます)。http://www.sampou.org/nobsun/journal/?20030220]
■
arton [出たみたい。
http://www.ascii.co.jp/books/detail/4-7561/4-7561-4252-4.html
#parameterとargumentの違いをこの本で知ったというのは内緒だ]
■
きた [http://www.loveruby.net/~aamine/ja/tdiary/20030221.html#p04
の</a>がおかしなことになってますよ.]
■
あおき [ありがとうございます。今直しました。
どうやらプリプロセッサが狂ってたみたいです。]
わかってはいたことだけど、確定してみると結構ショックなのだった。 一度に一つのことしかできない性格が仇になったか。
Amazon に頼んでいた "Garbage Collection" と "Introduction to Functional Programming using Haskell" 2nd が届いた。 意外と早かった。
GC 本ファーストインプレッション。表紙が厚い (なんじゃそりゃ)。 ぐおっ、LISP 2 の GC とか出てるー。
Haskell 本ファーストインプレッション。 …… non-strict 恐るべし。
テキストとかリスト処理の実例がたくさん出てるのはいいなあ。 数学の定理とかの学問ちっくなところを適当にすっとばせば 即物的に役に立ってくれそうだ。
れぐえくすぷ。
れぐえくす。
り。
『バカが征く』の IDC の調査の話ですけど。
「C# の順位があまりに低かったが、 下のほうに出てると体裁が悪いので C/C++ と一緒にして 1 位にしてみた」 ということじゃないでしょうか。
まあ、C# はちゃんと処理系が出てからたいして時間たってないんだから 順位が低いのは当然だと思うんですけどね。 処理系がまともかどうかもわからないのに普及してたらそっちのほうが恐いわ。
秘かに hackingguide.org をわたしが所有していることを知る人は 誰もいないとまでは言えないがあまりいないことは確実となった情勢です。
hackingguide.com を取られていることをついこの前知って、 あせって取得したんですけどね。そんなわけで、使ってはいません。
setup.rb のパッケージのインストール順序を指定できるようにした…… まではよかったが、それだけでは意味がないことに気付いてしまった。
そもそも順序を指定したいというのは「ライブラリ A と B を一緒に パッケージングする、ただし B は A に依存している」という状況を 解決するためなんだけども、この場合、ライブラリ A をちゃんと最後 までインストールしないと B の config を始められないわけだ。 でも今の setup.rb ってのは
という順序で進むので、どうやっても B の config が失敗する。 依存関係のあるライブラリをインストールできるようにするには
としないといけないのだが、これだと setup.rb の使いかたが完璧に 変わってしまう。config のパラメータをとっておいて B は後から config する、 などの方法もあるけども、4. の config が非同期で失敗する可能性があるので 嬉しくない。
ということは、config setup install の三段構えをやめるしかないか……。 うう、root で make するのは嫌いなのになあ。
あまりに変更がでかいし、いったんパッチレベルだけ上げるか……。
■ shiro [>ゲーム開発
複数チームでローテーションしてて一周する頃にはゲーム機の世代が代わってて再利用しにくいとか、毎回ゲームシステムに合わせてかりかりチューンかけるのでシステムが変わると書き直した方が速いとか、人のコード使うより自分で書いてみたいとか、ソースがどっかいっちゃったとか、まあ色々訳があるのでしょう。たぶん。
(個人レベルでは部分的に使い回しているコードはかなりあると思いますよ)。]
■ あおき [ゲーム機は本当に世代交代が激しいですもんねえ。
それに速度要求もやたら厳しいし。言語 (アセンブリ) 自体が
コロコロ変わるんじゃ、たしかにライブラリをためる余裕も
ないかも……。プレステ以降は C になったらしいですけどね。]
■ あおき [あ、でも N64 は確かアセンブリが標準だったような気がします。
その敷居の高さでソフトの本数をかなり減らしたとかなんとか。]
■ 戯 [それって、Cの非万能性をそれだけ雄弁に物語る証拠だったりするわけですよね?
ゲーム機に継続が必要かどうか(笑)は知らないけど、
それ以外の多くの場面できっと、Cじゃすっきり記述できない個所が多い、んだろうなあ…
#高級低級とはまた違う話として。]