トップ «前の日記(2007-08-04) 最新 次の日記(2007-08-06)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2007-08-05

_ プログラムの書き方(5)

(書き方(4)の続き)

N君が、Oさんが書いたプログラムを調べていると、Rさんが通りかかった。 「ふーん、Dirをopenして全ファイルなめてるけど、globしたほうがいいなぁ。それにどうせreadするんだから、Pathname使うほうがもっといいかも」と言うと、ささっと修正。

require 'pathname'
require 'fileutils'
 
Pathname.glob('*.ini').each do |file|
  File.open('tmpfile', 'w') do |d|
    d.write file.read.gsub(/d:/i, 'C:')
  end
  FileUtils.cp 'tmpfile', file.to_s
end
FileUtils.rm 'tmpfile'

そこで、ふとN君は疑問に思ったことを聞いてみた。

「一回、tmpfileっていうファイルに書き出してますが、これiniファイルの中身を全部読んでますよね。なぜ、そのまま元のファイルを削除してから書いたり、いきなり上書きしないんですか?」

「多分、Oさんは、最初、tmpfileの内容を確認させたんじゃない?」とRさん。

「ああ、そうでした。」

「いきなり、iniファイルそのものを更新する前に、確認できるようにしたんだと思うわ。あと、可能性としては、途中でプログラムが死んだ場合に、処理中のiniファイルかtmpfileのどちらか一方は残るようにしたかったんだと思う。Oさんはガチ好きだから。……もちろん、こうやってもいいんだけど」

require 'pathname'
 
Pathname.glob('*.ini').each do |file|
  contents = file.read.gsub(/d:/i, 'C:')
  file.open('w') do |d|
    d.write contents
  end
end

Rさんは、また、ささっと直して、行ってしまった。

「ふーん、僕はこっちのほうが短くて好きだな」とN君は思った。それに作業手順をプログラム化するっていうんなら、きっとこっちのほうが近いんじゃないかな、と考えた。すると待てよ……

require 'pathname'
 
Pathname.glob('*.ini').each do |file|
  file.open('w') do |d|
    d.write file.read.gsub(/d:/i, 'C:')
  end
end

「このほうが、もっと良さそうだ」と直して実行してみた。

それから、エクスプローラでF5を押して、一瞬、まっさおになったが、originalフォルダのことを思い出して胸をなでおろすのであった。

教訓:破壊的操作を伴うプログラムを作る場合には、バックアップを取って置くこと。

require 'pathname'
require 'fileutils'
  
Pathname.glob('*.ini').each do |file|
  FileUtils.cp file.to_s, "#{file.to_s}.bak"
 
  contents = file.read.gsub(/d:/i, 'C:')
  file.open('w') do |d|
    d.write contents
  end
end

_ LL魂(1)

Essentials of Constraint Programming (Cognitive Technologies)(Thom Fruehwirth/Slim Abdennadher)(メモ) declarative(追記:deしかちゃんと覚えてなかったので後で引っ張り出すとき間違ったらしい。酒井さんのところを見て修正:)denotational semanticsという言葉がまったくわからなかったのでakrさんに教えてもらう。が、そもそもどういう文脈で和田先生がその言葉を使ったのかがわからなくなってしまったので、はいそれまでよ。

_ LL魂(2)

Ioの発表がやたらめたらと面白かったのだが、RubyでああいうDSLを書けるか、という話を昼飯食う前にゆうぞうさんや、朴さん(だと思うんだけど違ったらごめんなさい)とした。

Ioの場合、パラメータリストに現れない引数は評価されないまま、メソッドに制御が渡るので、おそらく可能なんだろう、でもRubyだと評価されるよね、というところから、でも、ローカル変数に見つからなければメソッドとしてみることになるから、「,」と「 」に気をつければどうにかなるじゃん、ということになった。

で、軽く作ってみた。HTML吐く簡単なやつ。

#!ruby -Ks
# ll.rb
require 'pg'
 
module HtmlWriter
 
  Page do
 
    h1 こんにちは
    p 今日はLL魂なので、一ツ橋ホールに来ています。
 
  end
 
end

実行すると

D:\>ruby ll.rb
<html>
  <body>
    <h1>
こんにちは
    </h1>
    <p>
今日はLL魂なので、一ツ橋ホールに来ています。
    </p>
  </body>
</html>

と、与えた文字列(ではないのは、""とか''でくくられてないし、先頭に:も付いてない)が埋め込まれる。というか、pが関数とかちあうので余分なことも必要になったのだが。

# pg.rb
module HtmlWriter
  def self.Page(&p)
    @buffer = []
    puts '<html>'
    puts '  <body>'
    yield
    puts '  </body>'
    puts '</html>'
  end
 
  def self.p(*a)
    method_missing('p', a)
  end
 
  def self.method_missing(nm, *a)
    if a.size == 0
      @buffer << nm
    else
      puts "    <#{nm}>"
      @buffer.each do |x|
        puts "#{x}"
      end
      @buffer.clear
      puts "    </#{nm}>"
    end
  end
end

追記:衝撃的なオチ

なんか突然思い出したが、マクロがパワフルなのは呼び出し(というか展開時点では)評価しないからだった。いつ評価するかってのを現実世界にマップすると、なかなかおもしろいかも知れない。プロジェクト開始時点(メソッド呼び出し時)には評価せずに、作業が必要となった瞬間(プロシージャの中で)に評価する……多分、例外がスローされそうな気がする。一方、孔明の錦嚢も、必要となった時点で評価で、しかも物語はうまく進む。

_ LL魂(3)

プレゼント当たった。というか、こぼれ球を拾えた!

で、当たったのは、これ。

入門Common Lisp―関数型4つの特徴とλ(ラムダ)計算(新納 浩幸)

目つきの悪い鳥が3羽そろったよ。

_ LL魂(4)

ふと思ったのだが、shinhさん(おもしろい)や、lethevertさん(正統派でうまい)が、COBOLとかBASICとかをLLでございますと(というか、VBじゃなくて単なるBASICはLLで良いのか)発表すると、あっというまに人気の言語になりそうな予感。

_ LL魂(5)

なんかLINQみたいなコードを見たが、あれなんだったっけな? (思い出した。JavaFXだ)

_ LL魂(6)

JRubyのマルチVM対応の仕組みを見て思ったが、絶対どこかで誰かがCILを吐く4番目のを作りそうだな。意味があるかどうかはわかんないけど。

_ LL魂(7)

もしかしてコンパイラー。

variable or method not found : prnt もしかして print ? (y/n/a/c)

y……直してくれる(ソースも)

n……EDITOR環境変数の内容が起動されるだろうな。

a……abortする。

c……エラーはエラーとして続行(commonな動作)

ちょっと待てよ? VB8って既にもしかしてコンパイラーの実装になってるような。

_ LL魂(8)

Mac率はそれほど高くなく、意外とVista率が高かったように見えた。(DirectXが実はMacってのもあったな)

_ LL魂(9)

フォボナッチ数列ミュージックがすごく気に入る。あれも+40とか手を入れてるわけで、多分、クセナキスとか知らずにクセナキスしてるんだろうなぁ。

#偶然性を音にする過程で人間によって修正を入れる。人の意思が含まれなければそれは音楽ではない。

音楽と建築(ヤニス・クセナキス/高橋 悠治)(考えたら、おれのバイブルの1つだな)

Eonta / Metastasis / Pithoprakta(Iannis Xenakis/Konstantin Simonovic/Maurice Le Roux/Paris Contemporary Music Instrumental Ensemble/French Radio National Orchestra)

メタスタシスとかまた聴きたくなったので(LPしか持ってない)買う。指揮のル・ルーは、トリュフォーの映画に音楽を提供したりもしてるね。

_ LL魂(10)

ちなみに私にとってのベストはid:amachangのHTML+JavaScriptプレゼンだなぁ。

その一方で、たださん(らしい)の質問はおもしろい点を突いていると思った。というか、わき道にそれることができるプレゼン(RubyKaigiのときのサイロスさんの)とか、keisukenさんの3D空間を(多分)移動できるプレゼン(可能性の提示のみ)と同じように、Googleマップのようなプレゼン(2次元だけど動き回れる。リンクをうまくそこら中に残しておく。すごろくみたいなもので、ある程度までは事前に仕込んでおいても良いかも。反応がよければ3N4E進むとか、1S2Wへ進むとか、3移動前に戻るとか)とかも簡単にできそうだなぁとか。

というような後から考えたことより前に、amachangのプレゼンのインデックス画面がものすごく衝撃的だった(なぜだろうか? おそらく機能的なものではなく視覚的なものらしい)。和田先生のポストスクリプトファイル群もそうだけど。というか、akrさんとかが普通ポストスクリプトを手で書くのは当たり前みたいな話をしてるのを聞いて、まあ、そういう文化圏もあるんだろうなぁとか思ったり。

_ LL魂(11)

シーモアパパートは聴衆のハートを鷲掴みを読んで、Xtalのid:xtalcoさんがあのプレゼンのリズムの取り方を前日に練習している姿を想像して、やはりそれは無理ではないか、と打ち消してみたり。まじで、ノリから外国の人かと思った。たとえば、ジェームズブラウンとか。

ベンチマークが勝つと嬉しそうで負けると悔しそうなのが、見てていい感じだった。

本日のツッコミ(全4件) [ツッコミを入れる]
_ ただただし (2007-08-05 13:10)

keisukenさんのヤツは、プレゼンターが3D空間の中にいるべきだよな、とさっき思いました。って本人に言おう。

_ arton (2007-08-05 14:52)

それなんてアバターと脊髄反射したものの、プレゼンというものがプレゼンテーターの発見をオーディエンスに追体験させるものだとしたら、いい考えかもしれませんね。<br>そのうち、オーディエンスが3D空間の中に入れるプレゼンができるかも。聞き逃したところとか念入りに見たいところは、その人はプレゼンの流れからは時間的過去であるけれど、空間的には同時に存在している場所を見ていることもできるとか。これが単にパワポで3ページ前を眺めているというのとは違って、時間は共有できるようにするというところが、一番の工夫のしどころ。(というようなことを考えても自分で実装したいと思わないのはなぜなんだろう?)

_ あろは (2007-08-06 02:03)

declarative semantics (宣言的意味論) は,わりと Logic Programming の方面の意味論 (論理式の最小エルブランモデル) で出てくる用語なので,どんな文脈で出てきたのだろうと不思議に思っていました :-)

_ arton (2007-08-06 02:12)

それ違うんじゃない? って指摘して欲しかったです。(operational semanticsとakrさんが対比させてたってことと、deで始まるってことしか覚えてなかったので、とりあえずoperational semanticsで検索かけて引っかかったdeで始まる言葉を書いたんだけど、どうも違うように感じたので、あとでチェックしようと同時にひっかかった本をメモしておいたりしたわけでした)


2003|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|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|

ジェズイットを見習え