Project

General

Profile

Actions

Feature #3203

closed

LazySweepGC patch

Added by authorNari (Narihiro Nakamura) over 12 years ago. Updated over 11 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-dev:41067]

Description

=begin
ご無沙汰しています。nariです。

CRubyのGCにLazySweepを組み込んだパッチを作成しました(リビジョン27489向
け)。

= 実装について

== 概要
基本的に以下の動作を繰り返します。
0. オブジェクトが足りなくなったら 1.へ

  1. マーク済みのRubyヒープスロットの一つをスイープ
  2. もし、空きオブジェクトが見つかればオブジェクトを返却し、LazySweep終
  3. もし、空きオブジェクトな見つからなければ、次のマーク済みRubyヒープス
    ロットをLazySweepの対象とし、1.へ
  4. マーク済みRubyヒープスロットがすべてなくなった場合はマークを実施し、
    1.へ

LazySweepしないGC(普通のGC)も残しており、GC.startの時はこちらを呼びま
す。

== Rubyヒープ拡張&縮小
Rubyヒープの拡張と縮小はタイミングが異なるだけです。

Rubyのヒープ拡張はLazySweepと同時に行います。具体的にはヒープスロットを
1個増やすと同時に、Rubyヒープスロットを1個スイープするようにしています。
この工夫によって、Rubyヒープ内にまったく空きがない場合でも、GC停止時間
を最低限に抑えることができます。

Rubyヒープ拡張をLazySweep時に行うため、マーク後には拡張の決定をしなけれ
ばなりません。そのため、マーク時に生きているオブジェクト数をカウントし
ています。これによってマークフェーズは以前と比べて少しだけ遅くなります。

Rubyヒープ縮小も同じくLazySweep時に行います。

== sorted_heaps_slot構造体の追加
heaps_slot構造体は配列として管理するのをやめ、LazySweepの対象となる
Rubyヒープスロットは双方向リストで管理しています。

is_pointer_to_heap()関数ではheaps_slot構造体の変わりに
sorted_heaps_slot構造体を使用するように変更しました。

= 性能評価

== ベンチマークプログラム
生きているオブジェクト、死んでいるオブジェクトがある程度バラバラにRuby
ヒープ内に分布するようなベンチマークプログラムを作成し、計測に使用しま
した(※添付ファイル参照)。

== 結果
GC最大停止時間:48.00ms => 28.00ms (58%)
GC総停止時間:0.83ms => 0.92ms (110%)

総停止時間は悪くなりますが、最大停止時間については改善が見られます。

その他、有用なベンチマークをご存じでしたら測ってご報告いただけると嬉し
いです。

= 動作検証
以下の環境でのmake test-allが通る(パッチ対象のリビジョンと比較して変化
がない)ことを確認しています。

$ uname -a
Linux nari-laptop 2.6.31-20-generic #58-Ubuntu SMP Fri Mar 12 05:23:09 UTC 2010 i686 GNU/Linux
=end


Files

bm_gc_fragmentation.rb (445 Bytes) bm_gc_fragmentation.rb authorNari (Narihiro Nakamura), 04/27/2010 01:11 AM
gc_simple_lazy_sweep_r27489.diff (28 KB) gc_simple_lazy_sweep_r27489.diff authorNari (Narihiro Nakamura), 04/27/2010 01:11 AM
Actions #1

Updated by matz (Yukihiro Matsumoto) over 12 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:41067] [Feature #3203] LazySweepGC patch"
on Tue, 27 Apr 2010 01:11:50 +0900, Narihiro Nakamura writes:

|CRubyのGCにLazySweepを組み込んだパッチを作成しました(リビジョン27489向
|け)。

コミットしちゃっていいんじゃないですかね。

=end

Actions #2

Updated by mame (Yusuke Endoh) over 12 years ago

=begin
遠藤です。

2010年4月27日1:11 Narihiro Nakamura :

その他、有用なベンチマークをご存じでしたら測ってご報告いただけると嬉し
いです。

有用かはわかりませんが、make benchmark の結果くらいは確認して欲しいです。

というだけなのもなんなので、自分で試してみましたが、app_pentomino で

./benchmark/bm_app_pentomino.rb:117:in block (2 levels) in setpiece': method method_missing' called on unexpected T_NODE object (0x8217f0c
flags=0x383c klass=0x0) (NotImplementedError)

で落ちました。もうちょっとデバッグが必要なようです。

いずれにせよ、1.9.2 にはコミットするかは議論の余地があると思います。

--
Yusuke Endoh

=end

Actions #3

Updated by naruse (Yui NARUSE) over 12 years ago

=begin
成瀬です。

Yusuke ENDOH :

2010年4月27日1:11 Narihiro Nakamura >:

その他、有用なベンチマークをご存じでしたら測ってご報告いただけると嬉しいです。
有用かはわかりませんが、make benchmark の結果くらいは確認して欲しいです。

make test-all の所要時間と、make test-rubyspec の所要時間とか (結果も)、
あと encoding テーブルの作成時間とかもありますかね。

いずれにせよ、1.9.2 にはコミットするかは議論の余地があると思います。

え、1.9.2 に対してのコミットで議論の余地があるんですか?
このレベルの変更を今から 1.9.2 に対して行うのは無いと思います。
やるなら1.9.2ブランチを切ってからでしょう。

--
NARUSE, Yui

=end

Actions #4

Updated by authorNari (Narihiro Nakamura) over 12 years ago

=begin
nariです。

2010年4月27日10:18 NARUSE, Yui :

成瀬です。

Yusuke ENDOH :

2010年4月27日1:11 Narihiro Nakamura >:

その他、有用なベンチマークをご存じでしたら測ってご報告いただけると嬉しいです。
有用かはわかりませんが、make benchmark の結果くらいは確認して欲しいです。

make test-all の所要時間と、make test-rubyspec の所要時間とか (結果も)、
あと encoding テーブルの作成時間とかもありますかね。

ありがとうございます。調べてみます。
バグもあるみたいなので直します。

いずれにせよ、1.9.2 にはコミットするかは議論の余地があると思います。

え、1.9.2 に対してのコミットで議論の余地があるんですか?
このレベルの変更を今から 1.9.2 に対して行うのは無いと思います。
やるなら1.9.2ブランチを切ってからでしょう。

個人的な考えでは1.9.2に入れるつもりはありませんでした。
混乱させてしまってすみません。

--
Narihiro Nakamura (nari)

=end

Actions #5

Updated by authorNari (Narihiro Nakamura) about 12 years ago

=begin
nariです。

make test-rubyspec、check、benchmarkが通るようなりました。

また、make、make benchmark、test-all、test-rubyspecの実行速度も調べてみ
ました。極端に遅くなったものはなさそうです。そもそもプログラム実行時間
が早くなるたぐいの修正ではないので、目立ってに遅くなければOKだろうと思っ
ています。

make test-all
trunk : 183.42s
lazy_sweep : 196.92s

make test-rubyspec
trunk : 104.484065s
lazy_sweep : 106.389376s

make
trunk : 229.13s
lazy_sweep : 228.63s

make bechmark
minimum results in each 5 measurements.
name trunk lazy_sweep
app_answer 0.149 0.152
app_erb 1.027 1.090
app_factorial 0.495 0.500
app_fib 1.683 1.838
app_mandelbrot 0.460 0.506
app_pentomino 45.964 46.075
app_raise 1.364 1.403
app_strconcat 0.868 0.901
app_tak 2.334 2.447
app_tarai 1.857 1.840
app_uri 2.043 2.086
io_file_create 0.681 0.678
io_file_read 0.930 0.881
io_file_write 0.326 0.329
loop_for 3.810 6.067
loop_generator 1.984 1.988
loop_times 3.343 3.450
loop_whileloop 1.558 2.283
loop_whileloop2 0.322 0.477
so_ackermann 2.085 2.009
so_array 4.263 4.331
so_binary_trees 1.004 0.998
so_concatenate 0.956 0.970
so_count_words 0.424 0.439
so_exception 2.768 2.839
so_fannkuch 42.900 43.804
so_fasta 5.927 5.611
so_k_nucleotide 3.812 3.824
so_lists 0.854 0.876
so_mandelbrot 13.081 13.742
so_matrix 0.997 1.014
so_meteor_contest 14.278 14.269
so_nbody 9.369 10.590
so_nested_loop 3.067 3.061
so_nsieve 7.446 6.849
so_nsieve_bits 8.297 8.183
so_object 2.272 2.238
so_partial_sums 12.288 12.358
so_pidigits 3.317 3.311
so_random 0.808 0.850
so_reverse_complement 3.596 3.420
so_sieve 0.211 0.264
so_spectralnorm 11.595 8.725
vm1_block* 4.135 4.208
vm1_const* 2.050 2.176
vm1_ensure* 0.326 1.420
vm1_ivar* 2.275 2.938
vm1_ivar_set* 2.280 2.827
vm1_length* 1.588 2.262
vm1_neq* 1.184 1.194
vm1_not* 0.987 1.457
vm1_rescue* 0.422 0.336
vm1_simplereturn* 2.753 2.958
vm1_swap* 0.784 1.144
vm2_array* 1.802 1.917
vm2_case* 0.467 0.328
vm2_eval* 44.158 48.817
vm2_method* 4.541 4.400
vm2_mutex* 3.076 3.464
vm2_poly_method* 6.382 6.475
vm2_poly_method_ov* 0.881 0.856
vm2_proc* 1.595 1.432
vm2_regexp* 3.122 3.466
vm2_send* 1.030 0.910
vm2_super* 1.317 1.074
vm2_unif1* 0.904 0.579
vm2_zsuper* 1.277 1.357
vm3_gc 1.784 1.758
vm3_thread_create_join 5.890 6.038
vm3_thread_mutex 6.216 3.074

r28028に対するパッチを添付しておきます。

githubでforkして開発しています。

http://github.com/authorNari/ruby

Attachment: gc_simple_lazy_sweep_r28028.diff
=end

Actions #6

Updated by kosaki (Motohiro KOSAKI) about 12 years ago

=begin
kosakiです

個人的意見ですが

nariです。

make test-rubyspec、check、benchmarkが通るようなりました。

また、make、make benchmark、test-all、test-rubyspecの実行速度も調べてみ
ました。極端に遅くなったものはなさそうです。そもそもプログラム実行時間
が早くなるたぐいの修正ではないので、目立ってに遅くなければOKだろうと思っ
ています。

すでにまつもとさんからコミット許可もでているようだし、コミットしちゃえば
いいんじゃないですかね。
こういう変更大きいやつはブランチきってすぐの、今のような時期が一番
リスク低いんじゃないかなー的な意味で

=end

Actions #7

Updated by matz (Yukihiro Matsumoto) about 12 years ago

=begin
まつもと ゆきひろです

In message "Re: [ruby-dev:41443] Re: [Feature #3203] LazySweepGC patch"
on Fri, 28 May 2010 05:15:09 +0900, Narihiro Nakamura writes:

|make test-rubyspec、check、benchmarkが通るようなりました。
|
|また、make、make benchmark、test-all、test-rubyspecの実行速度も調べてみ
|ました。極端に遅くなったものはなさそうです。そもそもプログラム実行時間
|が早くなるたぐいの修正ではないので、目立ってに遅くなければOKだろうと思っ
|ています。

コミットしちゃって。

=end

Actions #8

Updated by akr (Akira Tanaka) about 12 years ago

=begin
2010年5月28日5:15 Narihiro Nakamura :

make test-rubyspec、check、benchmarkが通るようなりました。

思い立って、GC.stress を true にしてテストを動かしてみました。

つまり、

for f in test/test_* test/*(/)
do
echo $f
./ruby -e 'GC.stress = true; load "test/runner.rb"' $f
done

のようなかんじです。

まだ終わってませんが、いくつも問題を発生させられるようです。
コンパイラなどによっても違うでしょうから私だけでなく、他の人もやってみるといいかもしれません。

とりあえず、発生した問題の一つは以下のようなものです。

% ./ruby -e 'GC.stress = true; load "test/runner.rb"' test/cgi
Loaded suite -e
Started
......................................
Finished in 597.027141 seconds.

38 tests, 524 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 55933
-e: [BUG] Segmentation fault
ruby 1.9.3dev (2010-05-29 trunk 28057) [i686-linux]

-- control frame ----------
c:0001 p:0000 s:0002 b:0002 l:00236c d:00236c TOP

-- C level backtrace information -------------------------------------------
./ruby(rb_vm_bugreport+0x73) [0x815803e]
./ruby [0x818d07b]
./ruby(rb_bug+0x36) [0x818d0d6]
./ruby [0x80eecb7]
[0xb7fbc410]
./ruby [0x806813d]
./ruby(rb_gc_call_finalizer_at_exit+0x19) [0x806806a]
./ruby [0x805e98a]
./ruby(ruby_cleanup+0x1de) [0x805eb7c]
./ruby(ruby_run_node+0x43) [0x805ee2d]
./ruby(main+0x74) [0x805d898]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7ddc455]
./ruby [0x805d791]

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

lazy sweep 以前からあった問題かも知れませんけれど。

[田中 哲][たなか あきら][Tanaka Akira]

=end

Actions #9

Updated by authorNari (Narihiro Nakamura) about 12 years ago

=begin
2010年5月29日18:28 Tanaka Akira :

2010年5月28日5:15 Narihiro Nakamura :

make test-rubyspec、check、benchmarkが通るようなりました。

思い立って、GC.stress を true にしてテストを動かしてみました。

つまり、

for f in test/test_* test/*(/)
do
echo $f
./ruby -e 'GC.stress = true; load "test/runner.rb"' $f
done

のようなかんじです。

まだ終わってませんが、いくつも問題を発生させられるようです。
コンパイラなどによっても違うでしょうから私だけでなく、他の人もやってみるといいかもしれません。

とりあえず、発生した問題の一つは以下のようなものです。

% ./ruby -e 'GC.stress = true; load "test/runner.rb"' test/cgi
Loaded suite -e
Started
......................................
Finished in 597.027141 seconds.

38 tests, 524 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 55933
-e: [BUG] Segmentation fault
ruby 1.9.3dev (2010-05-29 trunk 28057) [i686-linux]

-- control frame ----------
c:0001 p:0000 s:0002 b:0002 l:00236c d:00236c TOP

-- C level backtrace information -------------------------------------------
./ruby(rb_vm_bugreport+0x73) [0x815803e]
./ruby [0x818d07b]
./ruby(rb_bug+0x36) [0x818d0d6]
./ruby [0x80eecb7]
[0xb7fbc410]
./ruby [0x806813d]
./ruby(rb_gc_call_finalizer_at_exit+0x19) [0x806806a]
./ruby [0x805e98a]
./ruby(ruby_cleanup+0x1de) [0x805eb7c]
./ruby(ruby_run_node+0x43) [0x805ee2d]
./ruby(main+0x74) [0x805d898]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7ddc455]
./ruby [0x805d791]

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

lazy sweep 以前からあった問題かも知れませんけれど。

ご指摘ありがとうございます。
調べてみます。

--
[田中 哲][たなか あきら][Tanaka Akira]

--
Narihiro Nakamura (nari)

=end

Actions #10

Updated by mame (Yusuke Endoh) about 12 years ago

=begin
遠藤です。

2010年5月29日18:28 Tanaka Akira :

思い立って、GC.stress を true にしてテストを動かしてみました。

ということを考えると、テストフレームワークは極限まで単純な方がいいですねえ。

% ./ruby -e 'GC.stress = true; load "test/runner.rb"' test/cgi
snip

lazy sweep 以前からあった問題かも知れませんけれど。

これに関しては、lazy sweep 以前からあった問題のようです。

diff --git a/string.c b/string.c
index f2f49ab..ae42893 100644
--- a/string.c
+++ b/string.c
@@ -613,8 +613,8 @@ str_replace_shared(VALUE str2, VALUE str)
STR_SET_EMBED_LEN(str2, RSTRING_LEN(str));
}
else {

  • FL_SET(str2, STR_NOEMBED);
    str = rb_str_new_frozen(str);
  • FL_SET(str2, STR_NOEMBED);
    RSTRING(str2)->as.heap.len = RSTRING_LEN(str);
    RSTRING(str2)->as.heap.ptr = RSTRING_PTR(str);
    RSTRING(str2)->as.heap.aux.shared = str;

--
Yusuke Endoh

=end

Actions #11

Updated by mame (Yusuke Endoh) about 12 years ago

=begin
遠藤です。

2010年5月29日23:02 Narihiro Nakamura :

ご指摘ありがとうございます。
調べてみます。

akr さんの件は無実でした (というか [Bug #3241] でパッチ作成済み
だったのに私がコミットし忘れてました。すみません) が、以下は Lazy
Sweep コミット後から SEGV するようになったようです。
ご確認ください。

$ ./ruby -e '1000.times { ObjectSpace.define_finalizer("foo".dup, proc
{ GC.start }) }'
-e:1: [BUG] gc_sweep(): unknown data type 0x1e(0x822c574)
ruby 1.9.3dev (2010-05-28 trunk 28063) [i686-linux]

-- control frame ----------
c:0005 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC :start
c:0004 p:0015 s:0008 b:0008 l:002054 d:000007 BLOCK -e:1
c:0003 p:---- s:0006 b:0006 l:000005 d:000005 FINISH
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 CFUNC :call
c:0001 p:0000 s:0002 b:0002 l:002054 d:002054 TOP

-- Ruby level backtrace information ----------------------------------------
-e:0:in call' -e:1:in block (2 levels) in '
-e:1:in `start'

-- C level backtrace information -------------------------------------------
./ruby(rb_vm_bugreport+0xbd) [0x815903d]
./ruby [0x81968ae]
./ruby(rb_bug+0x28) [0x8196968]
./ruby [0x8063641]
./ruby [0x8067597]
./ruby(rb_gc_start+0x19) [0x8067c79]
./ruby [0x814fab0]
./ruby [0x8151e88]
./ruby [0x815576b]
./ruby(rb_vm_invoke_proc+0x76) [0x8149696]
./ruby [0x8061434]
./ruby [0x8144c1d]
./ruby [0x8149ba9]
./ruby [0x814b1e8]
./ruby(rb_eval_cmd+0xe6) [0x8156736]
./ruby [0x8063961]
./ruby(rb_protect+0x128) [0x805b358]
./ruby [0x8063900]
./ruby [0x8064b3b]
./ruby [0x8064c02]
./ruby(ruby_cleanup+0x1a4) [0x805ccd4]
./ruby(ruby_run_node+0x3a) [0x805ceea]
./ruby(main+0x5a) [0x805a95a]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7e11455]
./ruby [0x805a861]

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

アボートしました

--
Yusuke Endoh

=end

Actions #12

Updated by akr (Akira Tanaka) about 12 years ago

=begin
2010年5月30日0:23 Yusuke ENDOH :

akr さんの件は無実でした (というか [Bug #3241] でパッチ作成済み
だったのに私がコミットし忘れてました。すみません) が、以下は Lazy

そうでしたか。

まぁ、それはそれとしていくつも出るのでもうひとつ。
もちろん lazy sweep と関係あるかどうかは不明です。

% ./ruby -ve 'GC.stress = true; load "test/runner.rb"' test/test_delegate.rb
ruby 1.9.3dev (2010-05-30 trunk 28074) [x86_64-linux]
Loaded suite -e
Started
....E../home/akr/chkbuild/tmp/build/ruby-trunk/20100530T001915/lib/ruby/1.9.1/minitest/unit.rb:302:
warning: too many arguments for format string
E..
Finished in 1.676947 seconds.

  1. Error:
    test_instance_method(TestDelegateClass):
    TypeError: can't convert Hash into String
    /home/akr/chkbuild/tmp/build/ruby-trunk/20100530T001915/ruby/test/test_delegate.rb:111:in
    `test_instance_method'

  2. Error:
    test_private_method(TestDelegateClass):
    TypeError: can't convert Array into String
    /home/akr/chkbuild/tmp/build/ruby-trunk/20100530T001915/ruby/test/test_delegate.rb:126:in
    `test_private_method'

10 tests, 24 assertions, 0 failures, 2 errors, 0 skips

Test run options: --seed 37501

[田中 哲][たなか あきら][Tanaka Akira]

=end

Actions #13

Updated by metanest (Makoto Kishimoto) about 12 years ago

=begin
きしもとです

手元の環境だと以下のエラーが出てます。
test-all すると(動き出すまでにえらい時間がかかったあと)同じところで to_str が
無限に再帰して? core を吐きます。

$ ../tool/runruby.rb --extout=.ext -- -e 'GC.stress = true; load "../test/runner.rb"' ../test/cgi/test_cgi_core.rb
Loaded suite -e
Started
..E......
Finished in 1.831383 seconds.

  1. Error:
    test_cgi_core_htmltype(CGICoreTest):
    TypeError: can't convert NoMethodError into String
    /export/home/ksmakoto/ruby-trunk/test/cgi/test_cgi_core.rb:339:in `test_cgi_core_htmltype'

9 tests, 75 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 49582

=end

Actions #14

Updated by akr (Akira Tanaka) about 12 years ago

=begin
2010年6月1日10:55 KISHIMOTO, Makoto :

  1. Error:
    test_cgi_core_htmltype(CGICoreTest):
    TypeError: can't convert NoMethodError into String
    /export/home/ksmakoto/ruby-trunk/test/cgi/test_cgi_core.rb:339:in `test_cgi_core_htmltype'

9 tests, 75 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 49582

これ、いろんなところで出ますねぇ。

現時点で、以下が観測できました。

TypeError: can't convert Array into String
test/rake/test_fileutils.rb:130:in test_fileutils_method TypeError: can't convert Array into String test/ruby/test_basicinstructions.rb:208:in set_lvar_in_another_method'
TypeError: can't convert Array into String
test/test_delegate.rb:111:in test_instance_method' TypeError: can't convert Array into String test/test_syslog.rb:13:in test_new'
TypeError: can't convert NoMethodError into String
test/cgi/test_cgi_core.rb:339:in test_cgi_core_htmltype' TypeError: can't convert NoMethodError into String test/date/test_date_arith.rb:87:in test_prev'
TypeError: can't convert NoMethodError into String
test/rake/test_fileutils.rb:130:in test_fileutils_methods_dont_leak' TypeError: can't convert NoMethodError into String test/ruby/test_alias.rb:44:in test_alias'
TypeError: can't convert NoMethodError into String
test/ruby/test_clone.rb:24:in test_clone' TypeError: can't convert NoMethodError into String test/ruby/test_complex.rb:1070:in test_ruby19'
TypeError: can't convert NoMethodError into String
test/ruby/test_complexrational.rb:104:in test_comp_srat' TypeError: can't convert NoMethodError into String test/ruby/test_exception.rb:312:in test_nomethoderror'
TypeError: can't convert NoMethodError into String
test/test_delegate.rb:111:in test_instance_method' TypeError: can't convert NoMethodError into String test/test_delegate.rb:124:in test_private_method'

それぞれどんなコードかと思って調べると...

test/rake/test_fileutils.rb:130
assert_raise(NoMethodError) { obj.copy } # from FileUtils
test/ruby/test_basicinstructions.rb:208
assert_raise(NameError) { a }
test/test_delegate.rb:111
assert_raise(NoMethodError, '[ruby-dev:40314]#3') {m.call}
test/test_syslog.rb:13
assert_raises(NoMethodError) {
test/cgi/test_cgi_core.rb:339
assert_raise(NoMethodError) do cgi.doctype end
test/date/test_date_arith.rb:87
assert_raise(NoMethodError) do
test/rake/test_fileutils.rb:130
assert_raise(NoMethodError) { obj.copy } # from FileUtils
test/ruby/test_alias.rb:44
assert_raise(NoMethodError) { x.foo }
test/ruby/test_clone.rb:24
assert_raise(NoMethodError) {foo.test2}
test/ruby/test_complex.rb:1070
assert_raise(NoMethodError){ Complex.new(1) }
test/ruby/test_complexrational.rb:104
assert_raise(NoMethodError){c <=> 2}
test/ruby/test_exception.rb:312
e = assert_raise(NoMethodError) {str.send(id)}
test/test_delegate.rb:111
assert_raise(NoMethodError, '[ruby-dev:40314]#3') {m.call}
test/test_delegate.rb:124
assert_raise(NoMethodError) {foo.delegate_test_private}

みごとにすべて assert_raise (と assert_raises) ですな。

[田中 哲][たなか あきら][Tanaka Akira]

=end

Actions #15

Updated by naruse (Yui NARUSE) about 12 years ago

  • Status changed from Open to Closed

=begin

=end

Actions

Also available in: Atom PDF