われら Ruby Crackers

$Id: baka.rd,v 1.1 2003/06/18 22:49:42 aamine Exp $

Ruby のいろんな限界を試し、あわよくばウブな Ruby インタプリタを 「せぐぶ」させちゃおうというバカなページ。

引数のデフォルト値にはどんな式まで書けるのか?

$global = 'global'
Const = 'const'
@inst = 'ivar'
@@cvar = 'cvar'

def meth( a1 = true,       # 擬似ローカル変数 (って覚えてる?)
          a2 = Const,      # 定数
          a3 = @inst,      # インスタンス変数
          a4 = $global,    # グローバル変数
          a5 = (lv = 1),   # ローカル変数への代入 & 参照
          a6 = @@cvar,     # クラス変数
          a7 = 1 + 1,      # 演算
          a8 = a7,         # 既に出た引数の参照
          a9 = ((1+1; 2*2; 'a9'))  # 複数の文
  )
  [a1, a2, a3, a4, a5, a6, a7, a8, a9].each {|i| p i }
  p lv
end

meth()

結論としては、メソッド本体で書けることはなんでもやれるようである。 実際に eval.c を見て確認すると、引数デフォルト値の評価はメソッド 本体のコンテキストで実行されているようである。

いやあ、そうじゃないかとは思ってたんだけどね。 ていうか普通ここまでやるか?

巨大ファイルをロードだ!

Hacking Guide にも書いたネタなんだが、Ruby スクリプトは 8000 行くらいを 越えると行番号がループする。

File.open( 'test.rb', 'w' ) {|f|
  9000.times do
    f.puts
  end
  f.puts 'raise'
}

とかやって作った test.rb を実行してみよう。

巨大 Array リテラルに苦しむ Ruby

Racc で実験してて気付いたことなんだけど、巨大な Array リテラルを スクリプト中に書くとロードがメチャクチャ遅くなる。まあ考えてみれば 当然で、要素一個につき内部でノードが二個生成されるのでそれを作る だけでも相当に大変なのだ。ついでにコンパイル中はノードを GC しない のでオブジェクト数は激増、GC 起こりまくりで悲惨なことになるという わけだな。

# 実験スクリプト

File.open( 'test.rb', 'w' ) {|f|
  f.print '['
  10000.times do
    f.puts '1,' * 25
  end
  f.puts '1]'
}

もちろんこれは Array に限った話ではない。Hash とか使うと 計算量が増えて苦痛が増すのでよさげである。

一方回避策はと言うと、要素数が少なくなればいいんだから、例えばなんらかの 形でシリアライズしておき、その文字列をヒアドキュメントとかでぶちこんで やればよい。

to be continued.

まだ少ないね……