ただ、風のために。5 (2003/February)

遠い記憶
1999 [01(a,b,c) 02(a,b,c) 03(a,b,c) 04(a,b,c) 05(a,b,c) 06(a,b,c) 07(a,b,c) 08(a,b,c) 09(a,b,c) 10(a,b,c) 11(a,b,c) 12(a,b,c) ]
2000 [01(a,b,c) 02(a,b,c) 03(a,b,c) 04(a,b,c) 05(a,b,c) 06(a,b,c) 07(a,b,c) 08(a,b,c) 09(a,b,c) 10(a,b,c) 11(a,b,c) 12(a,b,c) ]
2001 [01(a,b,c) 02(a,b,c) 03(a,b,c) 04(a,b,c) 05(a,b,c) 06(a,b,c) 07(a,b,c) 08(a,b,c) 09(a,b,c) 10(a,b,c) 11(a,b,c) 12(a,b,c) ]
2002 [01(a,b,c) 02(a,b,c) 03(a,b,c) 04(a,b,c) 05(a,b,c) 06(a,b,c) 07(a,b,c) 08(a,b,c) 09(a,b,c) 10(a,b,c) 11(a,b,c) 12(a,b,c) ]
2003 [01(a,b,c) 02(a,b,c) 03(a,b,c) 04(a,b,c) 05(a,b,c) 06(a,b,c) 07(a,b,c) 08(a,b,c) 09(a,b,c) 10(a,b,c) 11(a,b,c) 12(a,b,c) ]

RETURN / TOP

2003/02/11 (Tue)

書評検出(review detection)

私はデータベースの長期的管理運用には向いてないんで、書評リンクDBよりも 書評自動検出技術の方を調査したほうがいいんでしょうかね。

と思ったら、この前のスクリプトはバグってました。すみません……というわけで 修正版です。 仕様も一部変更し、リンクのアンカー中にISBNが入っていた場合には、 リンク先に書評があることにしました。そのほか細かい修正も。

で、 一歩さんも気にされている速度ですが、 有里さんの 著者別索引 2002年を使ってみたところ、私の旧世代マシン (AMD K-6の300MHz、でもメールはこのマシンを使って読み書きしていたり)で、 ネットワーク越しにページを持ってくる時間も含めて 1.7秒くらいでparseできます。 一歩さんの1月のページ なら5秒程度。 これくらいなら実用的なのでは?

ちなみに検出結果はISBN、URL、書評者のタブ区切りテキストの 形式で出力するようにしてみました。こんな感じになります( 有里さんのページ一歩さんのページ)。 一歩さんのページには書評者名が書かれていませんが、コマンドラインで、


ruby reviewdetector.rb http://member.nifty.ne.jp/ippo/s_d200301.html ippo

と直接指定することにより、タブ区切りテキスト中に「ippo」と 入れることができます。

書評リンクのキー

みすらぼ日記より。

「著者名\t書名\tURL」というように、 著者名と書名をキーにした場合の問題はというと、

とかですか。こういうことを考えると、まだISBNの方が揺れが少ない ので扱いやすいような。

要するに、誰かが表記のルールを決め、みんながそれに完全に従い 間違えているところは自分で直す、 という形ならいいんですけど、そうじゃない場合には メンテナンスする人の労力が爆発するんですよね。

それにつけても、世界中に置かれた テキストにユニークなIDを付与できるURLという仕組みは なんとすごいのかと改めて感心します。 WWWの成功がURLに多くを負っている ことは間違いないでしょう。


2003/02/16 (Sun)

業界

今日のひとこと。

「40歳を過ぎてしまったプログラマーってみんな何になるのかしら? 自分で会社を作れなかった人達は……」

三原順『僕がすわっている場所』より。1985年の作品。37歳で、もうこの業界についていけなくなる、と感じていた男の奥さんの台詞。

民法とフリーソフトウェアのライセンス

ここのところ、民法の本を読んでました。ライセンスまわりのことが知りたかったので。

その感想というか感触ですが、 GPLやBSDライセンスの免責条項は、おそらく万能ではないように思いました。 いくらライセンス上で免責をうたっていても、それだけで訴えられなくなることは ありえない、という意味で。

たとえばソフトに欠陥があって、それが 重大な問題を引き起こすことをソフトの作者が知っていた場合(いわゆる「悪意」)、 それを明示しないで誰かユーザに使わせてそのユーザに損害を与えたとしましょう。 この場合、信義則やら権利濫用の法理やら条文解釈やらを駆使して、 その作者に責任を負わせるようにしそうです。 まあ、倫理的にはそういうスタンスは正しいようにも思いますし。

あと、日本でパブリックドメインソフトウェアのような考え方を 確立するのに、契約各論でいうところの贈与(民法第549条)を 使ったりすることはできないんでしょうか。

贈与の場合、 「瑕疵又は欠缺」があっても、既知のものについて明示的に説明して いれば、責任を負わなくてすみます(同第551条)。また、 口頭による契約ではなく書面による契約であれば、 当事者が贈与を取り消すことができません(同第550条。 この「書面」というのは確か広く解釈されるはずで、 ユーザが読んでいることを期待できる電子化テキストでも いけそうな雰囲気だったんですがどうなんでしょ)。そのため ユーザは安心して使いつづけることができます。 こうすれば、私が期待する「パブリックドメイン」に かなり近いものになりそうです。

問題は、ソフトウェアについて、 このような契約を非排他的な形で行えるのかどうかですが…… るびべんさんにでも聞くべきですかね。

セカイ系プログラミング言語

昨日のRHG読書会(おつかれさまでした>参加者のみなさま)の後の飲み会で、 akrさんかやましたさんの話を聞いて「Haskellはセカイ系」という ネタを思いついたのですが、 どういう意味・文脈だったのかさっぱり思い出せません。 というか、Haskellがどんな言語なのかもまだよくわかってないし(汗


2003/02/18 (Tue)

Haskellで二項分布(その1)

のださんの遺伝子話で、 林譲治さん(2003/02/13-14)がRubyを使って二項分布を計算しています。 そこでHaskellで書いてみましょう。まずは階乗計算と順列組み合わせ。


fact x | x == 0  = 1
       | x >  0  = x * fact (x-1)
perm x y = fact x/(fact (x-y))
comb x y = fact x/((fact (x-y))*(fact y))

しかし、階乗(fact)は、


fact n = product [1..n]

みたいにも書けるらしいです。さすがだ。

ところでHaskellでグラフを書くにはどうするのがいいんでしょ?

Mercuryで二項分布

Mercuryでも書こうとしたんですが、 ダウンロードに時間がかかった(10MBもあるので)挙句、 いつまでたってもコンパイルが終わりませんでした……。

MercuryにしろCurryにしろ、いまどきの論理型言語は関数型言語の一種みたいに なっちゃってるんですね。確かにPrologの核をユニフィケーション& バックトラックと考えるなら、ユニフィケーションは遅延評価の親戚みたいな 感じですし(嘘かも)、バックトラック自体はPrologの問題点でもあったため、 resolutionの戦略を別途与えるようにする、というのは合理的に感じます。


2003/02/19 (Wed)

Haskellでhead

あおきさんのHaskellで書いたheadですけど、Haskellだったら 遅延評価で書けますよね? しかし文字列を行ごとに取り出す方法が わからない……。


module Main where
 
import System
import IO
 
lineNum = 10
 
main :: IO ()
main = do
         args <- getArgs
         case args of
           []   ->  do
                        str <- getContents
                        putLines str lineNum
           args -> mapM_ (\file -> do
                                     fstr <- readFile file
                                     putLines fstr lineNum
                          ) args
 
putLines :: String -> Integer -> IO ()
putLines [] _ = return()
putLines _  0 = return()
putLines ('\n':xs) n = do
                           putChar '\n'
                           putLines xs (n-1)
                           return()
putLines (x:xs) n = do
                       putChar x
                       putLines xs n

こんな感じでいいんでしょうか? ちょっと力技かも。

RubyでURI

一歩さんのところより。

URIの処理なら、 このへんにあるURIライブラリを使いましょう。最近のRubyなら 標準添付です。

ついでに、bibid->isbnの変換はbk1でしかできない→bk1へのアクセス集中、 というのがありそうなので悩ましいですね。


2003/02/20 (Thu)

40歳を過ぎたプログラマ

今日のひとこと。

「オレは…”もうおまえはいらない”と言われたらさっさと退きたい! その時どこに座っていようとも…」

同じく三原順『僕が座っている場所』より。そうそう、この作品は『ムーン・ライティング』【 bk1 / amazon / Yahoo! / 旭屋 / Jbook / 紀伊國屋 / eS! / 楽天 / 富士山 】 に入ってます。ミステリ読みにも(なんせ殺人事件の話だし)セキュリティに関心のある方にも(詳しくはネタバレになるので書けません)おすすめ。 しかしなんでこんなプロット思いついたのやら。

40歳になってもプログラマ、というのはもちろんありだと思います。 でも、やっぱり「もうこの業界についていけなくなる」、と感じる人は 少なくなさそうだと思うんですよ。それこそ「毎年ひとつ新しい言語を おぼえる」くらいの努力と覚悟がないと、若者に比べて体力もなければ 新しい知識も学習できない「厄介者」になってしまうような。

SEマネジャになる、というのはとってもよくありそうな路線です。 でも、多くのプログラマにとって、それは理想的なこと、 幸せなことなんでしょうか。いや、ちゃんとマネジメントができる プログラマ・元プログラマが増えることは、ソフトウェア産業全体にとって とても重要なことだとは思いますが、単に「ついていけなくなったから マネジメント」というスタンスでマネジメントするようではまずすぎますし。

たのしいHaskell

おお。なるほど。そうか、takeはそう使うんですね。

うーん、Haskellの関数のリファレンスってどこにあるんだろう……。

[Ruby] URIクラスの使い方

一歩さんのぶっちゃけ目的」のために(あー、リンクには他意はないです>にじむさん一歩さん。でも、お二人の文章を読んでちょっと考えてしまったことは事実なのですけど)。 コードで説明したほうが早そうなのでサンプルコードを見てくださいませ。 テストで説明するのも美しそうですが、1.6.5では標準じゃないですしねえ。


require 'uri'
 
#「このURLのファイルからこのLOCALにリンクがあるとそれはこのURLになる」
 
uri_diary = URI.parse("http://www.rubycolor.org/maki/d/")
uri_link  = uri_diary.merge("../../m/")
p uri_link.to_s  #=> "http://www.rubycolor.org/m/"
 
 
#「このURLとこのURLは実質同じである(〜と%7E)(hogeとhoge/とhoge/index.htm)」
 
uri_tilde = URI.parse("http://www.example.jp/~hoge/")
uri_tilde2 = URI.parse("http://www.example.jp/%7ehoge/")
 
p URI.unescape(uri_tilde.to_s) == URI.unescape(uri_tilde2.to_s) #=> true
 
 
module MyURIUtils
  @@directory_index = ["index.html","index.php","index.erb"]
  
  # "/foo/bar/" =>  "/foo/bar/"
  def canonicalize_path(path, dir_indexes=nil)
    dir_indexes ||= @@directory_index
    basename = File.basename(path)
    dirname = File.dirname(path)
    if dir_indexes.member?(basename)
      return dirname+"/"
    end
    return path
  end
  module_function :canonicalize_path
  
  # "/foo/bar/" =>  "/foo/bar"
  def canonicalize_path2(path, dir_indexes=nil)
    dir_indexes ||= @@directory_index
    basename = File.basename(path)
    dirname = File.dirname(path)
    if dir_indexes.member?(basename)
      return dirname
    end
    if path[-1] == ?/ && path.length > 1
      return path[0..-2]
    end
    return path
  end
  module_function :canonicalize_path2
end
 
p MyURIUtils.canonicalize_path("/hoge/funi")             #=> "/hoge/funi"
p MyURIUtils.canonicalize_path("/hoge/funi/")            #=> "/hoge/funi/"
p MyURIUtils.canonicalize_path("/hoge/funi/index.html")  #=> "/hoge/funi/"
 
p MyURIUtils.canonicalize_path2("/hoge/funi")            #=> "/hoge/funi"
p MyURIUtils.canonicalize_path2("/hoge/funi/")           #=> "/hoge/funi"
p MyURIUtils.canonicalize_path2("/hoge/funi/index.html") #=> "/hoge/funi"
 
 
#「このURLはこのURLと同じフォルダの下にある(つまり最新日記と過去ログの相関である可能性が高い)」
 
uri_d = URI.parse("http://www.example.jp/~hoge/d/newdiary.html")
uri_d2 = URI.parse("http://www.example.jp/~hoge/d/200203a.html")
 
d_path = File.dirname(uri_d.path)
d2_path = File.dirname(uri_d2.path)
p d_path == d2_path   #=> true




written by TAKAHASHI 'Maki' Masayoshi (maki@rubycolor.org)
RETURN / TOP