K.Sasada's Home Page

Diary - 2006 January

研究日記

睦月

_31(Tue)

ガーン、Ruby枠潰されてしまった。枠の意味ねー。

_30(Mon)

初でぶさみ.つまり、初でぶ。


席が少ない,ということで,あわてて ruby-list に案内を投げる.あわてていたので,間違いがあったかもしれないが,細かいことは知らない.

_29(Sun)

timeoutが遅いのはtimeout用スレッド生成が遅いんだろうから、timeout thread 用スレッドを一個ずっと走らせておけば、という話につながったりするんだろうか。そんなに難しそうでも無さそうだしな。


研究は趣味か,と聞かれると,圧倒的に趣味なんだろうなぁ.


MapReduceの話を聞いてきたけど,モデルは非常に単純というか.うまくいくのは当たり前.

で,その当たり前を数千,数万のクラスタ上で実用に耐え得るものに仕上げたのがすばらしい.

  • 計算機環境
  • サンプルアプリケーション
  • それを実装する人たち

が居て,はじめてここまできちんとしたものが出来たんだろうね.

でも,やっぱり適用できる問題は(全ての問題数と比べると)あまり多くは無いそうで.当たり前かな.

ちなみに,keyという存在がよくわからなかったのだよな.分散のために必要なのね.


久しぶりにSICP.

しかし,目的は内職.



def main *args
  yield
end
def void *args
end
def int *args
end

####

#include <stdin.h>

int main(){
  printf("Hello World!");
}

久々にgmailに入ったら招待数が100通と出た.そんなに知り合いいねー.

10000.times{
  Thread.new{a=1}.join
}

とかで,実行速度が一桁違う.うーむ.


あー,スレッドの生成はむちゃくちゃ遅くなってるなー.当たり前だけど.

_しゅ(Sun Jan 29 13:07:37 JST 2006)

 タイムアウトを起こしたい、と思ったその時点で時刻を取得しておいて、そこから起算してタイムアウト時刻を求めるとか。

_ささだ(Sun Jan 29 13:52:05 JST 2006)

 はい,そうなると思います.

_28(Sat)

#
#
#

class AutoLoggedFile < File
  def self.open *args
    file = self.new(*args)
    if block_given?
      begin
        r = yield file
      ensure
        file.close
      end
      r
    else
      file
    end
  end
  
  def initialize repository, path, *args
    @alf_backbone = check_backbone(repository, path)
    super(@alf_backbone.open_path, *args)
  end
  
  def close
    super
    @alf_backbone.commit
  end

  ALFBackbone_Systems = []
  
  def check_backbone repository, path
    ALFBackbone_Systems.each{|klass|
      if klass.supported?(repository, path)
        return klass.new(repository, path)
      end
    }
    raise "Unsupported repository: #{repository}"
  end

  ####################################

  class ALFBackbone
    def self.supported? repository, path
      raise "Implement it"
    end
    
    def initialize repository, path
      @repository = repository
      @path = path
    end

    def open_path
      raise "Overload it"
    end
    
    def commit
      raise "Overload it"
    end

    def self.inherited klass
      ALFBackbone_Systems << klass
    end
  end

  ####################################

  class ALFBSvnCommand < ALFBackbone
    def self.supported? repository, path
      svncd = File.join(repository, '.svn')
      FileTest.directory?(svncd)
    end
    
    def initialize repository, path
      super
      @path = File.join(repository, path)
    end

    def open_path
      @path
    end
    
    def add
      if FileTest.directory?(File.join(File.basedir(@path), '.svn'))
        path = @path
      else
        path = File.basedir(@path)
        while !FileTest.directory?(File.join(File.basedir(path), '.svn'))
          path = File.basedir(@path)
        end
      end
      svn_command("add #{@path}")
    end
    
    def changed?
      case svn_command("stat #{@path}")[0]
      when ??
        add
      when ?M
        true
      else
        false
      end
    end
    
    def commit
      if changed?
        svn_command("ci #{@path} -m 'commited by AutoLoggedFile'")
      end
    end

    def svn_command args
      r = `svn #{args}`
      if $? != 0
        raise "Subversion command exit with error (#{$?})"
      end
      r
    end
  end
end

少し整理してみた.

10.times{
  AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
    f.puts Time.now.to_s
  }
}

これで10秒(on cygwin)かかるというのは,使い物にならないか....

でも,まぁこんなもん,と思えばこんなもんかなぁ,という気はする.気だけ.


あんまり需要はないのかなぁ.


なんでこんなのを考えているかと言うと,前も書いたような気がするが,この日記,バージョン管理していないので,管理したいのだ.

_27(Fri)

うは、新しいT4は軽量バッテリー付ですか。すげえ欲しい。

軽量バッテリーだけ買っちゃおうかな。


Intel のプロセッサの違いがさっぱりわからないので調べていたら、比較表があった(http://www.intel.com/products/processor_number/proc_info_table.pdf)。大変わかりやすい。しかし、Dual Core、EMT64、HyperThreading、VT に対応しているのは Pentium XE 955 だけか...。どうやって手に入れよう。

まぁ、こんなん揃えたい人なんて居ないんだろうなあ。

あれ、Xeonが書いてないぞ?


Pentium XE 955 は Dell で普通に買えるか。


DDRでダイエット、という話を見て、ちょっと買おうかと思ってしまった。それよりも剣神ドラゴンクエストかなぁ、と思ってネットで探してみたら、ほとんど売り切れ。ガーン。

誰か余ってませんか。


びびるびるびるびびるびー

というネタは、どこかで使えるんだろうか。


げんしけん7巻.なんか凄い展開だな.こみぱ?


やはりなんか熱ぽい.

_IKeJI(Fri Jan 27 10:11:59 JST 2006)

 それだと生き返らないのでは?

_むらまさ(Fri Jan 27 12:07:36 JST 2006)

 近所のトイザらすとかにうなるほど積んであったような気がします。もう無いのだろうか。

_26(Thu)

なんというか,物欲大爆発って感じ.


x86用仮想化技術はもてはやされているが,では他のプロセッサに対してはどうなんだろう.

Xenはx86用って書いてあるな.

たとえばMIPSで必要なのは,

(a) user
-----------
(b) kernel
-----------
(c) VMM (Virtual Machine Monitor)

があったとき,例外で (a) -> (c) へ飛ぶ,(b) でのCP0関連命令をフック,(b)でのI/Oアクセスをフック,というところか?

フックしなくて大丈夫か? きちんと CP0のコンテキストが保存できていれば.うーん,どうなんだろうな.

TLBの差し替えとかをフック出来ればメモリはなんとかなりそうかな.なんとかするには命令書き換えしか思いつかないけど(CPUに手を入れなければ).

しかし,あんまり,需要無さそうだしなぁ.

サン、仮想化技術をSparcサーバに搭載へ を見て,つらつら考えてみた.

sparcだと,何をどうするんだろう.CPUに特殊なfeatureは要らないんだろうか.

_25(Wed)

寝まくり。


昨日は SHININGだった。興味深かったような興味深くなかったような。

全然、何も研究について、それ以外についても聞けなかったなあ。吸収する能力の欠如。欝だ。今後これじゃまずいだろう。

徹夜明けで途中何度も寝てしまったのも、失礼な話だなぁ。


COINSで x86_64 の TMDが作りたくなった。


で、家に初めてFAXが来た。ブラザー|薄型デジタル複合機 MyMio(マイミーオ)|MFC-620CLN

ADFが素敵。しかし、相手が居ないんでFAXはまだ試していない。


ところで、平成17年度上期未踏ソフトウェア創造事業 千葉PM 成果報告会が告知されました。

こんなに大事にしてもいいんだろうか...。SDCで告知するから、もしかしたらすぐ売り切れるかも、だって。どうみても未踏発表じゃなくて、ひがさん、まつもとさん、千葉先生の講演目当てです。ありがとうございました。

なにやら、数名分優先枠をもらっているようので、興味のある方は声をかけてください。2/6 に枠が解除、ということです。

Rubyな人はほとんど居ないんだろうなあ...。


風邪.喉が痛いのが治ったと思ったら,気持ち悪くなってきた.


言葉の誤用 - 間違って使っていませんか?

大変面白いサイトで,時間がさくさくと過ぎていく....


あかん,猫裁判読みきってしまった orz

_酒井(Sun Jan 29 10:01:53 JST 2006)

 興味あります>未踏成果報告会

_ささだ(Sun Jan 29 10:30:13 JST 2006)

 俺にメールしてー.

_酒井(Mon Jan 30 18:21:52 JST 2006)

 って、定員枠にまだ空きがあったので、普通に申し込んじゃいました。すいません。

_24(Tue)

母親と,「いただきます」についての話をしていたら,じゃぁ「ごちそうさま」はどうなんだろうね,という話になった.

どうなんだろうね.


http://www.ipab.org/Presentation/sem05/05-03-tkyo.pdf

不勉強ながら,計算加速器という言葉を初めて知る.なるほどー.

p53 なんで,システムソフトウェアをNAREGIがやるの? GRID技術が役に立つ?(たたないとは思わないが...) 略称だけを見ると,大型計算機のために何か作っても間違いはないとは思うが.

それとも,京速計算機自体について誤解してる?

p58.

2. 世界的にベクトルは衰退(ハイエンドでは)。

ローエンドでベクトル使ってるって...SIMD?

p62 の「上位の資源」とはなんだろう? ハイエンドマシンを政府の責任に?

最後の,応用から,と言う言葉は至言なんだが,今まで一度も応用を元に何かを作ったことが無い orz どーやるもんなんだろうな.自分自身が応用する側であれば,いいんだろうけど.


色々大変なので,るびまをさぼろうと思ったら次回予告にエントリーしちゃってるじゃん.うーんどうしよう.


  • "an x86" の検索結果 約 347,000 件
  • "a x86" の検索結果 約 123,000 件

んー、an か?

  • "an x86 processor" の検索結果 約 19,600 件
  • "a x86 processor" の検索結果 約 1,980 件

文句なく an か。


今日はSHININGだから早く寝ないと7時に起きれないー,と思っていても眠れない4:30.


で,なんかスゲーことを思いついたような気がして,ちょっと実装してみようかな,という気になっている.主観ではスゲーんだけど,簡単にできそうなので,すでに誰かがやっていそうではある.

いや,単純な話なんだけどさ,Ruby上だけで考えれば,簡単にファイルシステムをでっちあげられるんだよね.open-uriがやってるような.で,それはもっと拡張できるなぁ,と思ったという話.

たとえば,Ruby レベルに限れば jail みたいなのはスグできたりする?


というわけで,

class AutoLoggedFile < File
  def self.open *args
    file = self.new(*args)
    if block_given?
      begin
        r = yield file
      ensure
        file.close
      end
      r
    else
      file
    end
  end

  def initialize wc, path, *args
    @wc = wc
    check_working_copy
    @path = encode_to_wc_path(path)
    super(@path, *args)
  end
  
  def close
    super
    al_commit
  end

  ####################################

  def encode_to_wc_path path
    File.join(@wc, path.tr('/', '_'))
  end

  def check_working_copy
    `svn stat -q #{@wc}`
    if $? != 0
      raise "#{@wc} is not repository"
    end
  end

  def al_add
    `svn add #{@path}`
  end
  
  def al_commit
    al_add if `svn info #{@path}` =~ /Not a versioned resource/
    `svn ci #{@path} -m 'commited by AutoLoggedFile'`
  end
end

こんなのを作ってみた.open するファイルが全部勝手に svn の working directory でバージョン管理される,という.

AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
  f.puts 'foo'
}

AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
  f.puts 'foo'
  f.puts 'bar'
}

AutoLoggedFile.open('workdir', 'a.txt', 'w'){|f|
  f.puts 'foo'
  f.puts 'bar'
  f.puts 'baz'
}

こんな感じで,3回書き込みを行うと,

$ svn annotate a.txt
     4        ko1 foo
     5        ko1 bar
     6        ko1 baz

こんなふうに,ちゃんとログ付けされていることがわかる.


いや,きっともうあるんだろうけど.これを使えば簡単にウェブアプリケーションが作るファイルがバージョン管理下におけるな,と.

で,問題はすげー遅いってことなんだな.svn 起動しまくり.そこでRubyでSubversion直呼びデスヨ! と思ったんだけど,なんだかわからんぽんなんで保留.須藤さん,わかりやすいドキュメント書いて.


open-uri のように,openを差し替える.al// で始まってるファイル名だったら,自動バージョン管理,ということにしておく.

alias orig_open open

def open path, *args, &bl
  if path =~ /al\/\/(.+)/
    path = $1
    AutoLoggedFile.open($al_workdir, path, *args, &bl)
  else
    open path, *args, &bl
  end
end

$al_workdir = './workdir'

open('al//b.txt', 'w'){|f|
  f.puts '111'
}
open('al//b.txt', 'a'){|f|
  f.puts '222'
}
open('al//b.txt', 'a'){|f|
  f.puts '333'
}

結果:

$ svn annotate b.txt
     7        ko1 111
     8        ko1 222
     9        ko1 333

openのファイルの指定方法がちょっとアレかな.


はて,windows用のsubversionだけど,workingcopy が workdir だったとき,svn ci workdir/foo とやっても現在のカレントディレクトリは working copy じゃない,というエラーが出る.はて,どうしたもんか.

他のサブコマンドは動くのになあ.add とか.

そして,もうひとつ不思議なのが,cygwinで実行すると動く,という.

Linuxでも動くようだなあ.まぁ,それならいっか?


というわけで,改訂.

class AutoLoggedFile < File
  def self.open *args
    file = self.new(*args)
    if block_given?
      begin
        r = yield file
      ensure
        file.close
      end
      r
    else
      file
    end
  end

  DefaultWorkingCopyPattern = nil
  DefaultWorkingCopy = nil
  
  def self.default_working_copy=(path)
    path = File.expand_path(path)
    self.instance_eval{
      remove_const :DefaultWorkingCopyPattern
      remove_const :DefaultWorkingCopy
    }
    self.const_set(:DefaultWorkingCopyPattern, /#{path}\/(.+)/)
    self.const_set(:DefaultWorkingCopy, path)
  end
  
  #
  
  def initialize wc, path, *args
    @wc = wc
    check_working_copy
    @path = encode_to_wc_path(path)
    super(@path, *args)
  end
  
  def close
    super
    al_commit
  end

  ####################################

  def encode_to_wc_path path
    File.join(@wc, path.tr('/', '_'))
  end

  def check_working_copy
    `svn stat -q #{@wc}`
    if $? != 0
      raise "#{@wc} is not a workingcopy"
    end
  end

  def al_add
    `svn add #{@path}`
  end
  
  def al_commit
    al_add if `svn info #{@path}` =~ /Not a versioned resource/
    cmd = "svn ci #{@path} -m 'commited by AutoLoggedFile'"
    p cmd
    # `#{cmd}`
    system("svn ci workdir\\b.txt -m 'commited by AutoLoggedFile'")
  end
end

require 'uri'

alias orig_open open

def open path, *args, &bl
  path = File.expand_path(path)
  if path =~ AutoLoggedFile::DefaultWorkingCopyPattern
    path = $1
    AutoLoggedFile.open(AutoLoggedFile::DefaultWorkingCopy, path, *args, &bl)
  else
    orig_open path, *args, &bl
  end
end

使い方:

AutoLoggedFile.default_working_copy = 'workdir'

open('workdir/b.txt', 'w'){|f|
  f.puts Time.now
}
open('workdir/b.txt', 'a'){|f|
  f.puts Time.now
}
open('workdir/b.txt', 'a'){|f|
  f.puts Time.now
}

欠点は著しく削除,移動,コピーなどが制限されることなんだろうなぁ.FileUtilsを全部変えるのは面倒だしな.

_6(Wed Jan 25 15:22:54 JST 2006)

 プレステ2かも>ローエンドでベクトル使ってるって...SIMD?

_23(Mon)

skype のビデオチャットって、

  • skype 1.x とのビデオチャットはできるのか
  • skype 2.x on (windows xp以外)とのビデオチャットはできるのか

という疑問があるんですが、どうなんでしょうか。

そもそも、まだビデオ自体試してないんだが。


ちょっと話題になっている「いただきます」の話だけど、前も話題にならなかったっけ?

で、そのときにも書いたかもしれないけど書かなかったかもしれないので書いてみる。

高校のころ、ある人と一緒にCD屋に行って買い物をしたとき、その人は店員さんに「ありがとう」とか言っていたような気がする。で、私は金払ってるんだから当然だし、言う必要ないんでは? と聞いた。そしたら、そのある人は困ったような顔をして、でも、言われたほうが嬉しいし、みたいなことを言っていた様な気がする。それ以来、なるべく声に出してお礼を言うようにしている。


考えてみると、俺は今その人のそのときの年齢なんだな。比べてみると、俺は一体何やってんだろう、って思う。

その人は大切な恩人なんだが、何も恩返しが出来ないままだ。また一度一緒に酒を飲みたい。切に、切に、そう思う。


感謝は祈りなんだよねぇ。


少年少女の物語が、ハッピーエンドで、終わった。

この人は何が書きたかったのかなぁ。


あぁ,もう駄目駄目.駄目すぎる.自分駄目すぎ.ごめんなさいごめんなさいごめんなさい orz


まず,戦略を間違えた.圧倒的に間違えた.TeXは駄目って言われても,見積もりのために絶対に最初はTeXで書くべきだった.自分にそんな能力が無いってさっさとわからなかったのが,駄目すぎる.


うーん,最近 comment spam が増えてきたな.


とてもうれしい知らせが.


おー.許してもらえた.どうもありがとうございます.今度から買います(何を).

_IKeJI(Mon Jan 23 20:09:28 JST 2006)

>skype 1.x とのビデオチャット skype 2.x on (windows xp以外)とのビデオチャット

 残念ながら、どちらも動きません。

_ささだ(Mon Jan 23 21:16:17 JST 2006)

 なるほどー.家族マシンがwin2kなので,残念です orz

_22(Sun)

電車で iPod nanoで何か聞こうと思ったら、曲が何も入ってない!

一体何があったんだ。

リセットしたら、なんか見えるようになった。謎杉。


家族のPCが起動後数分で動かなくなっているらしい.以前HDDを交換してからの症状で,メモリを交換しても同じだった.これはマザボかなぁ,ということで,私の古いマシンと交換.ミドルタワーだから,リビングに置きたくなかったんだが.

今度キューブ形のを買うか.


で,HDDを入れ替えただけだと,マザボが違うので起動時にブルースクリーンが出るwin2k.さて,どう対処するんだっけな.

_21(Sat)

生まれて初めてVBプログラムを書いたような気がする.


なんでこんなことになったかというと:

  1. 今までlaptopのネットワークは全部 putty (ssh) を通していたんだけれど,wireless接続が切れるとputtyは落ちる.その再接続が鬱陶しいのでなんとかしたい.
  2. 久々に portforwarder(以下pf)を使ってみるか(puttyをpfみたいにするパッチ,というのもあるようだけど,なんとなく敬遠)
  3. pf は接続が切れても再接続してくれない
  4. 久々にRuby以外のソースをいじるか(現実逃避)ということで,pfのソースをとってくる
  5. opensslやzlibが必要らしい.面倒だったけど,親切なinstruction通りにやったらできた(PortForwarder ビルドの仕方
  6. 再接続のときの処理をどこに挟むかはすぐわかった.
  7. 現状ではダイアログを出して終了するようになっていた.
  8. ダイアログを reconnect 確認ダイアログに変えて,再接続するようにしてみたら,ssh 内部の cleanup がうまく動いていないようで,できない.ssh のほうを探すのは大変なので,諦める.
  9. reconnect? ダイアログで yes と答えたら exit(100) で終了させる.
  10. で,pf を外から起動して,errorlevelを見て100だったらまたpfを起動させればいいやー,と考える.
  11. バッチファイルで書く.すぐにできる.機能は満足した.
  12. しかし,DOS窓がずーっとあるのは美しくない(タスクバーに残る).
  13. バッチファイルレベルでこれが回避できないか探してみるけど,わからず.
  14. rubyw でもいいかー,と思ったけどなんか負けた気がするのでWindows標準だけでできないか検討してみる.
  15. wshかー,という安直な解にしておく.
  16. とりあえず vbs を書く.生まれて初めて exit do という単語の列を書いた気がする.
  17. 動かない.不等号を != にしていたかららしい.
  18. 直して,動いた.

pf 変更点:PortForwarderDlg.cpp を以下のように変更.

LRESULT CPortForwarderDlg::OnThreadEnd(WPARAM info, LPARAM lParam)
{
  if (GetStatus() == PF_STAT_CONNECTED) {
    /* server must disconnect cleanly (not fatally).
     * could this happen?
     */
    OnPfShow();
    if (MessageBox("Connection closed by server. Reconnect?", APP_NAME,
                   MB_YESNO | MB_ICONEXCLAMATION) == IDNO) {
      if (sshThread) {
        delete sshThread;
        sshThread = NULL;
      }
      EndDialog(0);
    }
    else {
      exit(100);
    }
  }
  else if (GetStatus() == PF_STAT_DISCONNECTING) {
    /* client requested to disconnect. */
    SetStatus(PF_STAT_NOT_CONNECTED);
    GetDlgItem(IDC_PF_STATUSSTATIC)->SetWindowText(PF_STRING_NOT_CONNECTED);
  }
  else {
    /* never happens */
  }
  return 0;
}

vbs:

Dim WSHShell
Set WSHShell = WScript.CreateObject("WScript.Shell")

Do
  err = WSHShell.Run("PortForwarder.exe atdot.net", 1, True)
  If err <> 100 Then Exit Do
Loop

JS にしなかったのは,なんとなく.


まぁ,こんなもんでしょう.なんとなく,cygwin の ssh と shellscript だけで全然問題ないような気がするが,細かいことは気にしない方向で.

cygwin/shellscriptでDOS窓を起動しないでなんかさせるのは簡単なんだろうか.


eさんがmixiで過去を見て未来の趨勢(趨のほう)を予測、みたいな内容を書いているのを見て「な、なんだって(略」という言葉の語源を知らない世代がくるのだよなぁと思った。50年後に2chに(2chはいつまで続くんだろう)「な、なんだってー(略」と書いているんだろうか。


さすがに雪の中RHG読書会に来ている人は少ない.10人以下,というのは久々だ.

_20(Fri)

かっこいいならCool Rubyかぁ。となると、その次は Warm Rubyだなぁ、とか思った最近。


さて、珍しく自宅でプリンタが必要になったんだがインクが無いらしい。ちょうど複合機を買おうと思っていたので、今からインクを買うのはアレだ。 そして、学校はちょうどセンター試験で入れない。なんともはや。

さて、どうしよう。


デブサミ,OSSコミュニティもいくつか参加されてるんですね.Rubyの会もなんかやったほうがよかったのかしらん.というか,こういうのってどうやって話が進むんだろう.

_babie(Fri Jan 20 02:08:51 JST 2006)

 『Warm Ruby』邦題>『うわぁ・・・Ruby の中・・・すごくあたたかいナリ・・・』

_ささだ(Fri Jan 20 02:18:57 JST 2006)

 なんかよくわかんないけど嫌だなぁ。

_こーのいけ(Fri Jan 20 07:06:07 JST 2006)

 今日はOKでしょ?17時まで。

_ささだ(Fri Jan 20 14:47:53 JST 2006)

 おお,17時までOKだったのですか.

_まつもと(Sat Jan 21 10:58:23 JST 2006)

 日本Rubyの会、デブサミに参加してますよ。リストに入ってました

_ささだ(Sat Jan 21 11:06:52 JST 2006)

 あり? うわ、ほんとだ。[ruby:975] デブサミ2005。すっかりスルーしてたんですが、何するんだろ。

_19(Thu)

http://d.hatena.ne.jp/seiunsky/20060118/1137606585

MSDNやSunが書いているjavadocなどと比較するのはなぁ、と一瞬思ったけど、利用者は比較して当然なのかも(というか、比較しない理由は無い)。全部ボランティアベースだとか、そんなのは(利用者的には)まったく関係ないんだから。

そして、そういう比較をすると、「Rubyのドキュメントダメダメ」と思うのは当然なのかも。

perlはよく知らないんですが、そんなにドキュメント充実しているんですか。

さて、どうするべきなのかね。自分は基本部分のドキュメントが不足しているとは思ってないんだけど。なんか、イメージ戦略か何かが必要なのかも。逆に「ボランティアなのにこんなに充実していて凄い!」みたいなことを思わせる何か。

ちなみに、不足をマイナスにしたり、割り算の優先順位とかどうなんだろう、とどうでもいいことを思ってみる。


技術情報、特に雑誌で金を取るのは、難しいなあ(C magazine休刊を見て)。 これも、どうあるべきなんですかねぇ。

るびまも、どうしたもんなんだか。

_babie(Thu Jan 19 09:59:44 JST 2006)

 リファレンスマニュアルをオサレな色に変えて字を小さくすればいいんじゃないかな? 字を小さくするのは冗談として、見映えはあんまり良くないですね。

_なかむら(う)(Thu Jan 19 14:01:10 JST 2006)

 充実度はともかく、見え方というか操作性に関しては、MSDNのサイトは最悪だと思ってるんですが、それは私だけなのかしら

_seiunsky(Thu Jan 19 20:39:37 JST 2006)

 どうも初めまして。リンクありがとうございますー。 ちょっと急ぎ足で書いた文章なので言葉足らずなところもあったのですが、カンタンに言ってしまえば「かんたん・わかりやすい」と言ったキャッチコピーと情報を集める時のギャップがあるなぁ、と。 あと、Perlの公式のドキュメントって知らないですけど(ぇ)、歴史がある分Webで調べるのは結構できますよね。まー、そんなとこの愚痴でした。 MSDNに関しては操作性はロクでもないですけど(Firefoxだと文字化けするし!)、VSのF1キー(ヘルプ)と連動してますからねぇ。あの変なブラウザに我慢すれば大体なんとかなるような気がします。 ……っと、ちょっと長くなってしまってすいません。それでは。 http://d.hatena.ne.jp/seiunsky/

_seiunsky(Thu Jan 19 20:41:38 JST 2006)

 わわ、改行が……。みにくくてすいません_| ̄|○

_ささだ(Thu Jan 19 21:15:22 JST 2006)

MSDNが特別最悪だとは思わないんですけど、俺の感覚が変なのかな。今のリファレンスマニュアルのデザインもかっこ悪いと思っていない俺は、やっぱり感覚が変なのかもしれない(というわけで、カッコイイRubyは無理ぽ)。

「Rubyは簡単」というのは、「情報もそろってて簡単、ばっちり」ということを連想させるから、現在のドキュメントを探し出すとっつきにくさのギャップが逆に目立つ、ということなんでしょうか。興味深いですね。となると、そもそもRubyは使いづらいと吹聴しておけばそもそも問題ないのか(違)。いや、そうしておいたほうが、隠し技になってくれてうれしいのかも。一部には。Rubyの普及を推進したい人たちの団体はできないものかな。日本Rubyの会はそういうものではないし。それとも、日本Rubyの会の中にも、普及を目的とした何かを作る必要があるのかも。

Perlの情報ってどうやって調べるんでしょうか。perldoc? ri と比較してどうなんだろ。日本語でまとまった情報はどうやって調べるんだろう。私がPerlが苦手な理由はドキュメントの調べ方がわからなかったことなんだけど。

Pythonは充実してると思う。でも、関数ばかりなのがどうにも苦手。

_yanagi(Thu Jan 19 22:00:55 JST 2006)

高橋会長と前に少しお話ししたのですが、 標準ライブラリのマニュアルが一箇所 (= ruby-lang) にまとまっていない (-> refe で出てこない) のが問題の一つではないかと思っています。

例えば、外部サイトにマニュアルがあって、ruby-lang のページにはそのサイトへのリンクだけがあるようなケースです。 例: http://www.ruby-lang.org/ja/man/?cmd=view;name=rss

とりあえず、全項目が refe で出るようにするところまでは持っていきたいと思っているのですが……

_ささだ(Fri Jan 20 01:15:50 JST 2006)

 うーん、refeはどれくらい使われているんだろう。

_こーのいけ(Fri Jan 20 07:05:36 JST 2006)

このエントリを読んで考えて,いつぞやの「RAAじゃダメなんですか」という質問への答が出たので,まとめてみました。 でも,考えてみたら元の記事は言語の入門のときの壁のような・・・ こっちはモジュール(特にThird Party Module)のドキュメントについての話です。 まあ,合わせていつぞやの報復とばかりにPerlの良いところをアピールして反撃! を兼ねて,「Perl/CPANユーザから見たRAAがイマイチに思える点の指摘」ということで聞き流してください。

大雑把に言うと,二つの点でモジュールのドキュメントを探しにくい・読みにくいと感じました。 まずは上で指摘のある通り,モジュールのドキュメントが集まっていないこと。 PerlはCPANに集まっている→それを前提としたツールができて使いやすくなる→魅力的なツールがあるからCPANにアップロードしたくなるという好循環が出来ているのだと思います。Rubyはこれが逆に回っているのでは?

この辺の話を一つ目のエントリに書いてみました。ちょっとタイトルは煽ってますけど。 CPANにはツールが色々あるんですよ,という話です。 Perl/CPANの良いところ〜なぜCPANにはモジュールが集まるのか

二つ目はモジュールのドキュメントの文書構造です。 各モジュールのドキュメントの質・量は作者さん次第というところも多いので単純に比較するものでも無いと思うのですが,今回RAAからいくつかのモジュールのドキュメントを見て,どうもPerlのモジュールの方が読みやすいように思いました。

なんでだろうと考えてみたところ,Perlの場合たいていのモジュールのドキュメントはUNIX manを踏襲した文書構造で書かれていて(確かどこかでこれを推奨していたはずです),欲しい情報を最初に提示してくれているのに対し,Rubyのモジュールは順序がモジュールごとにばらばらで,欲しい情報がなかなか出てこないと思いました。

この辺を二つ目のエントリに書いてみました。 CPANモジュールのドキュメントの良いところ〜読みやすいドキュメント 概略を言うと,Perlのモジュールのドキュメントは「このモジュールではこんなことができるよ」というのを何よりも先に提示しているのです。文章ではなく,SYNOPSISというコードで。そしてSYNOPSISはその後に続くリファレンスをどこから読み始めれば良いかという情報も提供しています。こうして,モジュールのユーザの興味を最初から惹きつける(あるいは「あ,違う」とさくっとあきらめさせる)文書構造になっています。

このエントリの最後で「この順番が逆だったら?」と書いていますが,これは実はruby-dbiのドキュメントがほぼその順で非常に読みにくいと感じたからです。他にも似たようなパターンがあったように思います。

「このモジュールで何ができるの?」と思ってドキュメントを見たユーザが最初に目にするのがライセンスで,次に何人もの(ユーザにとっては初めて目にする・あるいは興味が無かったりする)名前が続き,その後も色々とあったあげく,最後の最後でExampleが出てくる,しかも実際のドキュメントは別のページだよ,と出てくる訳です。 そこまで辛抱強く読み進めるユーザがどれだけいるでしょうか?

PerlではCPAN SearchかKobesearchなりという,「共通のデザイン・同じ場所」で,(たいていのモジュールで)NAME VERSION SYNOPSIS DESCRIPTION (詳細) SEE ALSO AUTHORS LISENCEという「共通の文書構造」で読めるので,100個のモジュールの中から自分の欲しいモジュールを探すのも容易であるのに対し,Rubyではあちこちページをたどってどうにかドキュメントを見つけ・・・10個くらいで飽きてきます。

この2点がいつぞやの「RAAじゃダメ」の答えです。>ささだくん ちなみに「Perlの情報の調べ方」も書こうとしていたのですけど,いつの間にか「CPANモジュールネタの仕入れ方」になっていたので割愛させていただきます。 Ruby, Perlともども今後とも発展していくことを祈って。

・・・文体が変だね。>自分 さすがにここでこの手の話題なので。

_18(Wed)

某fate、OPダメダメ。妥協の産物。


closureって、環境をcloseするもの、でいいと思うんだけど、足りないのかしらん。定義、無いのかなぁ。


「Effective Ruby」という書籍はどうだろうなぁ、と思う今日この頃。誰か書かないかな。

_かくたに(Wed Jan 18 19:19:01 JST 2006)

 「Effective」よりも、"たのしい","おいしい"(レシピブック)に続くシリーズ(?)として、"かっこいいRuby"がいいね、という話を以前babieさんとしてました。

_babie(Wed Jan 18 20:19:29 JST 2006)

 表紙はかっこよくしてね>「Effective Ruby」。「カコイイRuby」って呼ぶから。

_m(Wed Jan 18 23:26:41 JST 2006)

 http://en.wikipedia.org/wiki/Closure_%28computer_science%29

_17(Tue)

ああ,もう半分過ぎてるよ....


むぅ,test/unit が動かなくなってる orz


プロシンの感想を書いていなかった.ので書いておこう.


■1/9 成人式

前日入り.会場設営など.夜の10時までかかった.夕飯前には終わらせたいものである.

■1/10 一日目

前日の疲れとか,バイトの仕事とかで,なかなか発表が聞けなかった.悲しい.

□オブジェクトの局所的位置関係を利用したトポロジー推定システムの開発

さっぱり聞けなかった.まぁ,聞かなかった,ともいえる.

□アラビヤ語形態素解析エンジンの開発と、学習者向け辞書システムへの応用

これもあんまり聞けなかったけど,プレゼンうまかったなぁ.

□俺デスク:ユーザ操作履歴に基づく情報想起支援ツール

よくわかんなかったけど,評価がとても難しそうだ.

□CD/DVDから起動するLinuxの起動高速化

阿部君頑張ってるねえ.

この話は,KNOPPIXとか,起動CDに限らない話だと思うんだけれど(CDなど遅いメディアへのアクセス高速化が可能になるんじゃないかと思う),その辺はどうなんだろう.あと,これを作るためのセットって公開してくれるんだろうか.

□HTTPプロトコルを用いる広域ストレージとそれを用いて起動するLinux

これは何回か聞いた話だったのでだいたいわかった.P2Pまでいったとき,どうなるんだか興味深い.

□災害時情報共有インタフェースおよびSDGミドルウエアの開発

災害情報,という話と,マウスを複数同時利用できる,という話が混ざって残念な感じに.どちらかに統一して話したほうがよかったんじゃないかと思うんだけれど.

災害情報の取り扱いについては,評価大変だろうけど,もうちょっとほしかった.

後ほど,竹内先生から,あれは他のプロジェクトと組み合わせると凄いんだ,と教えてもらった.

□ポスターセッション

ウダー大人気だったね.やっぱ音は強い.

他のポスターも人だかりで,なかなか話が聞けなかった.

□宴会

和田先生の話はさっぱりわからんかった.

Simpeiはもう解けたんだっけ.

■1/11 二日目

□君を感じるインターネット -超次元コラボレーションブラウザ「Antwave」という提案

あんまりあったかそうじゃないなあ.

□ビスケットランドの実装

さっぱりわからんかった.

Visual languageについての話(利点欠点,オフィスができない理由など)は興味深かったので,宴会で原田さんに少し伺った.

□Kuriltai: 局所性を考慮したID空間を持つDHT

よくわからんかった(知識不足).あまり聞いてなかったというのも.

□セキュアかつ高性能なウェブサーバの設計と実装

評価プログラムが恣意的だとか,なんとか.殺すために一度起きなきゃいけないが,そこではスラッシングは発生しないか?

□バイオ医療を進化させる新原理マイクロナノマシンとバイオロボティクス

大変面白かった.10年後くらいには,学研が「化学ブロック」を出さないだろうか.

最後の「研究者から学者へ」は私も質問しようと思ってたんだけど,さすが竹内先生.いいなぁ,この言葉.

□ロボカップサッカーシミュレーションエージェント開発体験キットOZED

Rubyで作ってあるらしい.るびま寄稿をお願いしてしまった.

□少人数・個人開発者向けオンラインゲームフレームワークの提供〜オンラインゲーム開発「3つの壁」に立ち向かう〜

発表者不在のため流れた.予稿を読んでもようわからんけど,タイトルはキャッチーだから,聞きたかったんだけどな.

□Javaへの限定された継続の実装と、その応用

継続と永続化の話がごちゃごちゃに.

継続のキャプチャはやっとわかったけど,しかし,どうやって継続の復帰を行うのかが未だにわからない.

スレッドの永続化じゃ,なんで駄目なんだっけ.

今読み直してみてもやっぱりわからない.うーむー.わからないのはスタックフレームの復元なんだけど.

□ActiveBasicを取り巻く言語市場の今後

大変斬新な発表だった.

原田さんが「計算機科学の敗北」と言っていたのが印象深い.

□報告等

俺これのためにプロシン行ったんだけどなあ.うけ取れなかったな・・・.

□自由討論

伊知地さんの芸術〜 というのに行った(教育のアレは覗いてみたら怖かったんだもん).

□宴会

和田先生の話,なんとなくわかった.

後藤さんがとても壊れていて面白かった.

すぐに時間が過ぎてしまうな.ああいう場は.

■1/12

□隠伏サーバを実現するTCP認証方式

よくわからなかった(知識不足)

ssh で暗号化でいいじゃん,と思ったけど,そのsshサービス自体を隠したい,という話だったんだろうか.どっかのフィールドになんか情報を押し込むとか何とか.ステガノグラフィみたいなの?

□サンプリング計測におけるトラフィック傾向把握手法の提案

やりたいことがよくわからなかった.

□Preccs:インターネットのための通信プロトコル記述言語

聞くのは2度目.やっぱりFPGAとの連動が面白そうなんだけどなあ.

□PrologによるMakeの実装

Makefileの実装,という言葉が面白かった.

□片付け

片付け.腰が痛かった.

□ビール蔵

多田先生,田中先生はビール蔵へ行くらしかったんだけど,登山電車で目が覚めたら終点で,誰も居なかった.

きょろきょろしてたら,前田さんと水島君が居たのでビール蔵へ連れてってもらった.色々,和田研の話を伺った.

電車に乗って帰ったら8時だった.ロマンスカーに乗ろうと思ってたけど,ぼーっとしてたら小田原過ぎて新宿だった.


プロシンバイトは,発表をなかなか聞けないからもう嫌だなあ.発表なんてどうでもいい,箱根で温泉入ってうまい飯食いたい,というのなら,いいバイトなのかも.


そういえば,若手の会の話は全然していないな...

というか,俺やっぱり今年幹事なんだろうか.幹事資格あるのかな....

_16(Mon)

こんな切羽詰ってるのはゼミの資料を思い出す・・・.


初学者に実装を教えてしまうと,抽象化してある利点を見逃してしまうのではないか,という危惧があります.たとえば,ポインタはアドレスだ,と教えてしまうと,数字しか思い浮かばなくなったり.

いずれは知るべきことかと思うんだけど,果たしてそれは早いほうがいいのか遅いほうがいいのか.教えられる人にもよるんだと思うけどね.


2ch に貼ってあった>http://grape.astron.s.u-tokyo.ac.jp/pub/people/makino/talks/mitaka20060113.pdf

正直読みづらいけど,内容に爆笑してしまった.


少なくとも,私がマクドナルドやジョナサンで原稿なりハックなりをしているのはそれが理由です>たださん(聞いてないって)

Let's Note T4って,バッテリーが素敵に持つ(ecoモードで8時間)ので,素敵に長居ができる(迷惑な客).


というか、家に機材そろえてるんだから、そこでやれよって感じだ。

orz

_m(Mon Jan 16 10:53:50 JST 2006)

 http://grape.astron.s.u-tokyo.ac.jp/~makino/articles/future_sc/face.html

_えむふる(Mon Jan 16 20:22:11 JST 2006)

 HPCって奥が深い、というかキリが無いですね。http://www.ne.jp/asahi/comp/tarusan/ こちらの方の予想も面白い

_向井(Mon Jan 16 21:33:34 JST 2006)

 ネットワークが繋がらない環境だと調べものがしづらくて大変だったりしませんか?(とゆー言い訳を思いついて仕方ない……)

_ささだ(Mon Jan 16 21:52:23 JST 2006)

 結構なんとかなるもんですよ。というか、後でまとめて調べればそれなりにはかどります。

_ただただし(Mon Jan 16 22:34:30 JST 2006)

 マクドは最近、Yahoo! BB Mobileが入ってるから誘惑がなぁ……契約しなければいいだけの話だけど。

_yoosee(Tue Jan 17 00:46:42 JST 2006)

 そのうちIP Unreachableな環境を求めて山に籠るハッカーとか出てくるんだろうか

_15(Sun)

おわんないよウワーン.


いや,gzは終わらせたんだけどね.


wcコマンド難しい.というか,Rubyの解説難しすぎる.割りきりが必要だと思うんだが,どこで割り切ったもんだか.


black black をボトル(?)で買ってみたけど,800円.割安なんだろうか.内容量がどこにも書いていないのでわからない.

_14(Sat)

なんか、温泉について、やることやることが裏目に orz

ごめんなさいごめんなさいごめんなさい。最悪、バスかな...。

_13(Fri)

どうにも,人生を決めるようなメールを投げようとして,日本語がわからなくて困る.


というわけで,プロシンから昨日帰ってきた.


http://aspara.asahi.com/club/user/guest/topNaviList.do?type=reading のカレッジライフ ですねぇ.

俺の業績について,一本書くらしかったんだけど,新聞社側が「わけわかんねー」ということで没にされたという.

_えむふる(Fri Jan 13 22:29:50 JST 2006)

 アスパラに並木研のレポート載ってますよ。今日見つけました。

_ron(Sat Jan 14 00:02:14 JST 2006)

 朝日タウンズ 1/5, 1/12 と並木研が紹介されていますね。 同じ内容かな?

_ささだ(Sat Jan 14 01:23:29 JST 2006)

 同じ内容です.

_12(Thu)

ひたすら眠い.

_11(Wed)

そして眠い.

_10(Tue)

疲れすぎ.ヤバス.

_9(Mon)

明日から箱根.起きられるかな....


Ruby温泉,締め切りは昨日でしたが,もし割り込みたい人はお早めに.

というか,今日が祝日だってことすっかり忘れてたぜ....

_8(Sun)

未踏な新年会.お疲れ様でした.


なぜか川合さん(shiroさんじゃない)が居る.


昨日の話,やりたいことは,

array.c	S/1.html
ascii.c	S/2.html
...
ext/Win32API/Win32API.c	S/69.html
ext/bigdecimal/bigdecimal.c	S/70.html
ext/bigdecimal/bigdecimal.h	S/71.html
ext/curses/curses.c	S/72.html
ext/dbm/dbm.c	S/73.html
ext/digest/defs.h	S/74.html
ext/digest/digest.c	S/75.html
ext/digest/digest.h	S/76.html
ext/digest/md5/md5.c	S/77.html
ext/digest/md5/md5.h	S/78.html
ext/digest/md5/md5init.c	S/79.html
...

これをですね,Compiled HTML の ToC ファイルの形式に変換....説明がメンドイ.

まぁ,なんか木構造にしたい,と.


def make_ary tree, fmap, path
  tree.sort.inject([]){|a, (n, t)|
    a << {
      :name  => n,
      :value => fmap.fetch(path+n),
    }
    t.empty? ? a : a << make_ary(t, fmap, path+n+'/')
  }
end

def read_files
  map = read_map('FILEMAP')
  fmap = map.inject({}){|h, e| h[e[:name]] = e[:value]; h}
  Dir.glob('files/*.html'){|file|
    data = File.read(file)
    if %r|<title>(.+)</title>|m =~ data
      /(.+)\// =~ $1
      fmap[$1] = file
    end
  }

  tree = map.map{|e| e[:name]}.inject({}){|tree, path|
    path.split('/').inject(tree){|t, n|
      t[n] ||= {}
    }
    tree
  }
  ary = make_ary(tree, fmap, '')
end

ごちゃごちゃした処理が混じってるけど,やりたかったのはこんな感じ.

一度 hash にすれば,早かったな,と.


昨日のを同じように解くと,

def make_ary tree
  tree.sort.inject([]){|a, (n, t)|
    a << n
    t.empty? ? a : a << make_ary(t)
  }
end

def solve map
  tree = map.inject({}){|tree, path|
    path.split('/').inject(tree){|t, n|
      t[n] ||= {}
    }
    tree
  }
  ary = make_ary(tree)
end

p solve(['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'])
#=> ["a", "b", "x", ["a", "b", "y", ["a"], "z", ["a"]]]

順序を保存しろ,という話になると,また違うんでしょうけど.

t.empty? ? a : a << make_ary(t) がかっこ悪いと思うんだが,なんか他に方法ないかな.

def make_ary tree
  tree.sort.inject([]){|a, (n, t)|
    a << n
    a << make_ary(t) unless t.empty?
    a
  }
end

こっちのほうがマシ?


tree は inject 無いほうがわかりやすいかな,ということで,

def make_ary tree
  tree.sort.inject([]){|a, (n, t)|
    a << n
    a << make_ary(t) unless t.empty?
    a
  }
end

def solve map
  tree = {}
  map.each{|path|
    path.split('/').inject(tree){|t, n|
      t[n] ||= {}
    }
  }
  ary = make_ary(tree)
end

p solve(['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'])

# parse GNU global outputs and generate hhp, etc

def make_hhp id, title
<<EOS__
[OPTIONS]
Compiled file=#{id}.chm
Default topic=index.html
Title= #{title}

Language=0x411 日本語
Compatibility=1.1 or later
Contents file=toc
Display compile progress=Yes
Full-text search=Yes
Index file=idx

[FILES]
#{
  Dir.glob('**/*.html').join("\n")
}

[INFOTYPES]
EOS__
end


def ary2toc ary
<<EOS__
<UL>
#{
  ary.map{|e|
    if e.kind_of? Array
      ary2toc e
    else
      <<-EOS
      <LI> <OBJECT type="text/sitemap">
        <param name="Name"  value="#{e[:name]}">
        <param name="Local" value="#{e[:value]}">
      </OBJECT>
      EOS
    end
  }.join("\n")
}
</UL>
EOS__
end

def read_map file
  open(file).map{|line|
    line.chomp!
    if /(.+)\s(.+)/ =~ line
      {:name => $1, :value => $2}
    end
  }.compact
end

def make_idx
  idx = read_map('MAP')
  
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
  <HEAD>
    <meta name="GENERATOR" content="texi2html4hh">
    <!-- Sitemap 1.0 -->
  </HEAD>
  <BODY>
#{ary2toc idx}
  </BODY>
</HTML>
EOS__
end

def make_ary tree, fmap, path
  tree.sort.inject([]){|a, (n, t)|
    a << {
      :name  => n,
      :value => fmap.fetch(path+n),
    }
    t.empty? ? a : a << make_ary(t, fmap, path+n+'/')
  }
end

def read_files
  map = read_map('FILEMAP')
  fmap = map.inject({}){|h, e| h[e[:name]] = e[:value]; h}
  Dir.glob('files/*.html'){|file|
    data = File.read(file)
    if %r|<title>(.+)</title>|m =~ data
      /(.+)\// =~ $1
      fmap[$1] = file
    end
  }

  tree = map.map{|e| e[:name]}.inject({}){|tree, path|
    path.split('/').inject(tree){|t, n|
      t[n] ||= {}
    }
    tree
  }
  ary = make_ary(tree, fmap, '')
end

def make_toc
  toc = [
  {:name => 'Index',   :value => 'index.html'},
  {:name => 'Mains',   :value => 'mains.html'},
  {:name => 'Defines', :value => 'defines.html'},
  {:name => 'Files',   :value => 'files.html'},
  read_files
  ]

<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
  <HEAD>
    <meta name="GENERATOR" content="texi2html4hh">
    <!-- Sitemap 1.0 -->
  </HEAD>
  <BODY>
#{ary2toc toc}
  </BODY>
</HTML>
EOS__
end


hhp = make_hhp('ruby-1.9.0-src', 'ruby 1.9.0 (2006-01-06)')
toc = make_toc
idx = make_idx

open('global.hhp', 'w'){|f| f.write hhp}
open('toc', 'w'){|f| f.write toc}
open('idx', 'w'){|f| f.write idx}

んで,やっとましな ruby-1.9.0-src.chm が出来た.


... あぁ,俺は何やってんだ.


GNU global は,対応するフォーマットが少ないので gonzui では出来ないだろうか,と思うのだけれどどうなんだろう.gtags / htags 相当の機能はあるんだろうか?

DB をきちんと見て回れば出来るような気はするが,メンドイかなぁ.

ちなみに,gonzui は scheme をサポートしてくれないだろうか.ん,cvs を見たらありそうな予感.


./gauche-0.8.6-src.chm

やっぱり,*.scm が無いとつまんないな.

_7(Sat)

あぁ,現実逃避に chm を作りまくってしまった.


# parse GNU global outputs and generate hhp, etc

def make_hhp id, title
<<EOS__
[OPTIONS]
Compiled file=#{id}.chm
Default topic=index.html
Title= #{title}

Language=0x411 日本語
Compatibility=1.1 or later
Contents file=toc
Display compile progress=Yes
Full-text search=Yes
Index file=idx

[FILES]
#{
  Dir.glob('**/*.html').join("\n")
}

[INFOTYPES]
EOS__
end


def ary2toc ary
<<EOS__
<UL>
#{
  ary.map{|e|
    if e.kind_of? Array
      ary2toc e
    else
      <<-EOS
      <LI> <OBJECT type="text/sitemap">
        <param name="Name"  value="#{e[:name]}">
        <param name="Local" value="#{e[:value]}">
      </OBJECT>
      EOS
    end
  }.join("\n")
}
</UL>
EOS__
end

def read_map file
  open(file).map{|line|
    line.chomp!
    if /(.+)\s(.+)/ =~ line
      {:name => $1, :value => $2}
    end
  }.compact
end

def make_idx
  idx = read_map('MAP')
  
<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
  <HEAD>
    <meta name="GENERATOR" content="texi2html4hh">
    <!-- Sitemap 1.0 -->
  </HEAD>
  <BODY>
#{ary2toc idx}
  </BODY>
</HTML>
EOS__
end

def make_toc
  toc = [
  {:name => 'Index',   :value => 'index.html'},
  {:name => 'Mains',   :value => 'mains.html'},
  {:name => 'Defines', :value => 'defines.html'},
  {:name => 'Files',   :value => 'files.html'},
  read_map('FILEMAP')
  ]

<<EOS__
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
  <HEAD>
    <meta name="GENERATOR" content="texi2html4hh">
    <!-- Sitemap 1.0 -->
  </HEAD>
  <BODY>
#{ary2toc toc}
  </BODY>
</HTML>
EOS__
end


hhp = make_hhp('ruby-1.8.4-src', 'Ruby 1.8.4')
toc = make_toc
idx = make_idx

open('global.hhp', 'w'){|f| f.write hhp}
open('toc', 'w'){|f| f.write toc}
open('idx', 'w'){|f| f.write idx}

現実逃避の産物.


ruby-1.8.4-src.chm こんなのが出来た.さて,これ便利なんだろうか.1.9 じゃないから便利じゃなさげ.


a, x/a, x/b, x/y/a, x/y/b, ... みたいなものを,[a, x, [a, b, y, [a, b]]] みたいに変換する簡単な方法は....


ruby-1.9.0-src.chm

とりあえず.


p m = ['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'].map{|f|
  f.split('/')
}

def parse ary
  h = {}
  return nil if ary[0].size == 0
  ary.each{|e|
    if h[e[0]]
      h[e[0]] << e[1..-1]
    else
      h[e[0]] = [e[1..-1]]
    end
  }
  h.sort.map{|k, v|
    [k, parse(v)]
  }
end
require 'pp'
pp m = parse(m)

def last ary
  m = []
  ary.each{|e|
    m << e[0]
    if e[1]
      m << last(e[1])
    end
  }
  m
end

pp m = last(m)

#=>
[["a"], ["x", "a"], ["x", "y", "a"], ["x", "b"], ["x", "z", "a"], ["b"]]
[["a", nil],
 ["b", nil],
 ["x", [["a", nil], ["b", nil], ["y", [["a", nil]]], ["z", [["a", nil]]]]]]
["a", "b", "x", ["a", "b", "y", ["a"], "z", ["a"]]]

まぁ,望む答えなんだけど,とてもかっこ悪い気がする.

_shiro(Sat Jan 07 17:45:06 JST 2006)

仕様がよくわからないけど。

(use srfi-1)
(use gauche.collection)
(use util.match)
(define (p input)
  ((rec (r lis)
     (append-map (match-lambda
                   (((x)) `(,x))
                   (((x . y) ...) `(,(car x) ,(r y))))
                 (group-collection lis :key car :test equal?)))
   (map (cut string-split <> #\/) (sort input))))

gosh> (p '("a" "x/a" "x/y/a" "x/b" "x/z/a" "b"))
("a" "b" "x" ("a" "b" "y" ("a") "z" ("a")))
_デフォルトの名無しさん(Sun Jan 08 03:43:59 JST 2006)
class N
  def initialize(n= nil) @n, @c= n, {} end
  def /(n) @c[n]||= N.new(n) end
  def build
    return [@n] if @c.empty?
    res= @c.values.inject([]){|r,e| r+= e.build }
    res= [@n, res] if @n
    res
  end
end
def trans(src)
  t= N.new
  src.each{|e| o= t; e.each{|n| o/= n } }
  t.build
end
src= ['a', 'x/a', 'x/y/a', 'x/b', 'x/z/a', 'b'].map{|e| e.split('/') }
p trans(src)

_6(Fri)

.NET IronPython 1.0 ベータリリース

おー。これからはPythonの時代デスネ。


http://slashdot.jp/comments.pl?sid=295416&cid=859977 誰も突っ込んでないけど,後者二つは同じもの.


最近のputtyは便利なもので,smb over ssh が簡単に出来るのね.

_5(Thu)

sigsafe_syscall(int sys, int argc, void *argv, sigmask) なんてシステムコールがほしい...。

sigsafe: Pattern reference をまた読み返してるんだけど、わかりやすいですね、問題点が。

Windows の handle は便利だよなぁ。

UNIX も、thread ごとに handle を持つようなセマンティックスになってくれれば、いいんだけど。

handle がシグナルでは、どのシステムコールも EINTR で失敗する、シグナルを受けるとhandleはシグナル状態になる、みたいな。シグナル状態の解除は明示的になんかする。

あ、シグナル状態になるのは handle じゃなくて、handle が指すオブジェクト、か。


そういえば、read が終わった後にどうせ CHECKINTS するんだから、結局 read の結果は捨てられるんじゃないだろうか、とか思った(もちろん、sigsafe が問題にしているのはもっと一般的な話だけど)。

なんか、read に関しては select で polling でいいような気がしている人。

write に関しては、まだ理解できていない。


gethostbyname() などでは、運が悪いと(シグナルが入っても)ずーっとブロックするよ、みたいな...。


うーん、これで古畑任三郎終わりか。

_4(Wed)

Thread#raise をいい加減にサポート。

さて、ブロックしてるやつを再開させるには、どうしたもんかな。POSIX なら pthread_kill() しかないんだけど。


trap をいい加減にサポート。


signal をいい加減にサポート。


学校に来てみる.


そういえば,東京に居ると免許って全然要らないんですよねえ.


RDE を使ってみる.うーむ,よくできてるなぁ.


RDE でデバッガを利用してみようと思ってみたんだけど,rde.so が無いと仰る.その前に,RDE のディレクトリに -I でパスを通してあげなきゃいけなくて,その後で rde/ruby19 にもパスを通してあげたんだけれど(-I じゃなくて,メニューからわかりやすくパスを通す方法があるような気がするんだけど,設定が見つからなかった).

どうも,独自ビルドのRubyでは駄目なのかもしれないね.


で,エディタの左にモジュールとかメソッド名一覧がずらーっと並んでいて,大変便利そうだったので,xyzzyでも同様のことができないかどうか考えてみたんだけれど,うまいこといかなかった.

C のメソッド一覧がtabでジャンプできたらいいな,と思ったんだけど.XTAGS でいいじゃん,といううわさもあるけど,動的に更新してくれないし.

code explorer というのか.いいなぁ.


腰がいてぇ.


#!/usr/bin/env ruby

require 'open-uri'
require 'optparse'

class WC
  Version = '0.1'
  
  def self.exec args, default_io
    options = {}
    
    OptionParser.new{|opts|
      opts.banner = "Usage: #{$0} [options]... [Files]..."
      opts.separator ''
      
      opts.on('-c', '--bytes', 'print the byte counts'){
        options[:chars] = true
      }
      opts.on('-m', '--chars', 'print the character counts'){
        options[:chars] = true
      }
      opts.on('-l', '--lines', 'print the newline counts'){
        options[:lines] = true
      }
      opts.on('-L', '--max-line-length', 'print the length of the longest line'){
        options[:length] = true
      }
      opts.on('-w', '--words', 'print the word counts'){
        options[:words] = true
      }
      opts.on_tail('-h', '--help', "Show this message"){
        puts opts
        exit
      }
      opts.on_tail('--version', "Show version"){
        puts "wc command (sample ruby program) #{WC::Version}"
        exit
      }
    }.parse!(ARGV)
    
    options = {
      :lines => true,
      :words => true,
      :chars => true,
    } if options.empty?

    wc = WC.new(options)

    if args.empty?
      puts wc.exec_io(default_io)
    else
      ARGV.each{|filename|
        puts wc.exec_file(filename)
      }
      puts wc.total if wc.total_files > 1
    end
  end

  ######################################################
  
  def initialize opts
    @opts = opts
    @total_lines = @total_words = @total_chars = 0
    @total_files = 0
    @total_length = 0
  end

  attr_reader :total_files

  def exec_io(fobj)
    output_format nil, *count(fobj)
  end
  
  def exec_file(file)
    begin
      open(file){|fobj|
        fobj.binmode
        @total_files += 1
        output_format file, *count(fobj)
      }
    rescue Errno::ENOENT => e
      "#{$0}: #{file}: No such file or directory"
    end
  end

  def total
    output_format("total", @total_lines, @total_words, @total_chars, @total_length)
  end

  private
  
  def count fobj
    lines = words = chars = length = 0
    while line = fobj.gets
      lines += 1 if /\n$/ =~ line
      words += line.strip.split(/\s+/).size
      chars += l = line.split(//).size
      length = l if length < l
    end
    @total_lines += lines
    @total_words += words
    @total_chars += chars
    @total_length = length if @total_length < length
    return lines, words, chars, length
  end

  def output_format filename, lines, words, chars, length
    result = ''
    result << '%8s' % lines  if @opts[:lines]
    result << '%8s' % words  if @opts[:words]
    result << '%8s' % chars  if @opts[:chars]
    result << '%8s' % length if @opts[:length]
    result << " #{filename}" if filename
  end
end

if $0 == __FILE__
  WC.exec(ARGV, ARGF)
end

wc コマンドを作ってみたが,WC クラスの意味が無い,ような気がするが,もしかしたら役に立つこともあるか?

-L オプションを追記してみた。しっかし、wc -L なんて初めて知った。というか、wc にオプションつけたこと無い。


福袋といえば、毎年恒例になっているユニクロの5000円の福袋(服はほぼ、これしか買わない)を元旦に買ったんだけど、ちょっとしょんぼりな感じ。なんか、毎年だんだんしょぼくなってきているような気がする。

コートの下に着るためのジャケットがほしい。


「面倒くさい」…アルバイト高校生、年賀状など雪の中

「面倒くさい」…学生、セキュリティホールを残す

あ、これ俺だ。


上記、wc の output_format がかっこ悪い気がしたので、なんとかならないかと考えてみる。

  def output_format filename, lines, words, chars, length
    [:lines, :words, :chars, :length].map{|sym|
      '%8s' % eval(sym.to_s) if @opts[sym]
    }.join << (filename ? " #{filename}" : '')
  end

eval を使ってるところでなんか負けっぽい。しかも、最期の filename がなんか嫌。なんか無いかね。

_moli(Wed Jan 04 23:00:40 JST 2006)

 2006年のLogが無いようです。↓

_ささだ(Wed Jan 04 23:34:06 JST 2006)

 う、忘れてました。

_babie(Thu Jan 05 05:19:02 JST 2006)

 自分一人なら困らないんだけどねぇ>免許

_3(Tue)

つい、ダラダラーっとしてしまう。


cref の扱いで、また勘違いがあったということに気づいたので、変えなければ。しかし、この変更はめんどくさい...。

_2(Mon)

class の re-open が嫌だ、という人のために、class 文を終わるとき、その class を freeze する何かをつけてみるのはどうか、と思ったけど、大量のライブラリが動かなくなりそうだな。


前に、erb で eval する対象は、コンパイル済みの命令列 (iseq) は簡単に出力できますよ、と言っていたんだが、なかなか難しいことに気づいた。で、昨年から色々考えてみてるんだけど、なかなかいい方法が思いつかない。

eval に渡す binding によって、iseq が変わる、というのが問題。

def m1
  a = 1
  binding 
end

def m2 arg=0
  a = b = 1
end

eval('p a', m1)
eval('p a', m2)

で、iseq は別々のものが生まれる。

このままでは、eval は毎回コンパイルが必要って気がする。うーーーーむ。

eRuby を高速に動かす方法がわからん。なんとかならんかな。

同じ環境(同じ binding)で、という条件つきなら出来るんだが。しかし、binding 、変わる可能性もあるしな。

def a
  :a
end
def m
  binding
end

eval('p a',   b=m)
eval('a = 1', b)
eval('p a',   b)

この例でもコンパイル結果は変わる。うーむ。

コンパイル結果を変えなくてよい、ということを検知する仕組みは...。


なんか違うマシンで2回連続 WinXP が落ちた...。なぜ。


午前中だけ、と思ったら夜までかかってしまった。

最初は陳腐だなぁ、と思ったけど、案外面白かった。いや、使い古されたネタかなぁ、と思っていたんだけど。

タイトルを、どう決着つけるのか楽しみ。

しかし、有力者が居ないと救われないってかんじがして、その辺は嫌な感じだった。

あんまり detail を楽しむ作品ではないのかな、とか思った。

あと、これだけ長い文章なんだから、まぁしょうがないかな、とも思ったが、誤字が結構。

_まつもと(Thu Jan 05 20:15:18 JST 2006)

 open classをclassboxを使って実現、とか夢想してます

_1(Sun)

仮眠したら年が明けてた。

あけました。今年もよろしくお願いします。


仮眠したら、なにやら新年早々物騒な夢を見た。

  • 人の車に勝手に乗る
  • 大変危険な運転をする(私は車の免許持ってない)
  • 警察が凄い勢いで出てくる
  • だましあい

うーむ。


Multi-VM を考えていたんだけど、なかなか良いものが思いつかない。グローバルなものを考えるとね...。やっぱり Ruby では無謀だったか?

core は Multi-VM enable にしておいて、拡張ライブラリでは InitMVM_hoge() みたいなものを用意する、というのはどうだろうな。なければ、2個目からは駄目、とか。


ぐろーばる VM ろっくがあるところで、ブロックするような read をするとき、

unlock_gvl();
{
  read(...); // block しても何してもオケ
}
lock_gvl();

とすればいいなぁ、と思っていた。

で、これだとそのスレッドがブロックしているところに例外を投げたいとき、つまり Thread#raise を実装しようとすると、ブロッキングしてるスレッドに対して pthread_kill みたいなことをしてあげればいいなー、と思っていた。

unlock_gvl();
{
// (*A)
  read(...);
  CHECK_INTS();
  if(errno = EAGAIN){
    // なんか呼ばれてる!
   }
}
lock_gvl();

これで、できるなーと思っていたんだが、(*A) の時点で signal を受けるとすると、read() は実行されて、ブロックしてしまう。

この問題は、unlock と read をアトミックに行う方法が無いということに起因するが、さて。Thread#raise は即時性を持つとは限らない、という注意書きだけでいいんかな?

うーむ、外部からのシグナルも同様な問題があるのか。

Windows のハンドルだと、この辺はうまく行きそうなんだがな。はて。なんかうまい手は無いかな。

... これって、もしかして出来ないのか? ありえない?


ちょっと考えてみた。

要するに、read が失敗すればいいので、read にあり得ないパラメータを渡すようにしてみれば解決する。シグナルハンドラの中で、あり得ないパラメータをスレッドに設定して、read するときは‘必ずそれを使うようにする、というのはどうだろう、と思ってみた。回りくどいけどね。たとえば、read なら -1 とか。

  yarv_thread_t{
    VALUE param;
    VALUE illegal_param;
  }

--------------------------

  // read する人
  th->param = fd;
  th->illegal_param = -1;
  read((int)th()->param, ...)

  if(errno == EAGAIN ||
     th->param == th->ellegal_param){
    ...;
  }

--------------------------

  // signal handler の中の人
  th->param = th->illegal_param;

みたいにする。

ちょっと、でもなくめんどいけど、これくらいしか思いつかないなあ。


あぁ、これも穴があるなぁ。やっぱ小手先で考えても駄目だな。

signal handler から longjmp するか。

んー、これで本当に解決する? するような気がするな。


longjmp でいっかー、と思った途端、Windows には pthread_kill 相当が出来ないから駄目ジャン、ということになってしまった。駄目ジャン。

とりあえず pthread 用にざっと作るか。しかし、cygwin では pthread_kill はまともに動かないのは、どうしたもんかな。


rb_thread_wait_fd() なんかを全部からにしようと思ってたんだけど、そこを unlock で囲めば(fd の話は)解決なのか。

うーむ、そうなると、write が block してしまうという問題に対する対処法はないのか...。


新年早々でアレですが、アレにDHHが来てくれそうです :)

_きむら(Sun Jan 01 06:03:40 JST 2006)

 Auguri Buon Anno! つーことで今年もよろしくお願いします。朝生も終わったので寝る

_akr(Sun Jan 01 08:16:15 JST 2006)

 read が起動した後に longjmp しちゃったら、read の返値が得られないのでうまくいかない。これを解決してしまう sigsafe というライブラリは面白いが、ポータブルではない。nonblocking にして、select で止まっているときに longjmp という手はある。read と違って select の返値は得られなくてもたいして困らないから。

_ささだ(Sun Jan 01 10:47:59 JST 2006)

 なるほどたしかに終わった後の話は思いつきませんでした。select で、というのがよいんですかね。

_akr(Sun Jan 01 15:45:17 JST 2006)

 とりあえず sigsafe のドキュメントを眺めてみるのがいいのでは。http://www.slamb.org/projects/sigsafe/api/

_babie(Sun Jan 01 21:41:26 JST 2006)

 免許取っとき。社会人になるとマジ時間ない。私は転職の際1ヶ月空けて取りに行く予定です。

Sasada Koichi / sasada@namikilab.tuat.ac.jp
$Date: 2003/04/28 10:27:51 $