[前][次][番号順一覧][スレッド一覧]

ruby-changes:6567

From: mame <ko1@a...>
Date: Wed, 16 Jul 2008 00:26:27 +0900 (JST)
Subject: [ruby-changes:6567] Ruby:r18082 (trunk): * test/ruby/envutil.rb (Test::Unit::Assertions#assert_in_out_err): new

mame	2008-07-16 00:26:04 +0900 (Wed, 16 Jul 2008)

  New Revision: 18082

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18082

  Log:
    * test/ruby/envutil.rb (Test::Unit::Assertions#assert_in_out_err): new
      method.
    
    * test/ruby/test_argf.rb: use assert_in_out_err instead of
      EnvUtil.rubyexec.
    
    * test/ruby/test_module.rb: ditto.
    
    * test/ruby/test_require.rb: ditto.
    
    * test/ruby/test_objectspace.rb: ditto.
    
    * test/ruby/test_object.rb: ditto.
    
    * test/ruby/test_string.rb: ditto.
    
    * test/ruby/test_method.rb: ditto.
    
    * test/ruby/test_variable.rb: ditto.
    
    * test/ruby/test_io.rb: ditto.
    
    * test/ruby/test_rubyoptions.rb: ditto.
    
    * test/ruby/test_exception.rb: ditto.
    
    * test/ruby/test_class.rb: ditto.
    
    * test/ruby/test_thread.rb: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/envutil.rb
    trunk/test/ruby/test_argf.rb
    trunk/test/ruby/test_class.rb
    trunk/test/ruby/test_exception.rb
    trunk/test/ruby/test_io.rb
    trunk/test/ruby/test_method.rb
    trunk/test/ruby/test_module.rb
    trunk/test/ruby/test_object.rb
    trunk/test/ruby/test_objectspace.rb
    trunk/test/ruby/test_require.rb
    trunk/test/ruby/test_rubyoptions.rb
    trunk/test/ruby/test_string.rb
    trunk/test/ruby/test_thread.rb
    trunk/test/ruby/test_variable.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 18081)
+++ ChangeLog	(revision 18082)
@@ -1,3 +1,35 @@
+Wed Jul 16 00:04:30 2008  Yusuke Endoh  <mame@t...>
+
+	* test/ruby/envutil.rb (Test::Unit::Assertions#assert_in_out_err): new
+	  method.
+
+	* test/ruby/test_argf.rb: use assert_in_out_err instead of
+	  EnvUtil.rubyexec.
+
+	* test/ruby/test_module.rb: ditto.
+
+	* test/ruby/test_require.rb: ditto.
+
+	* test/ruby/test_objectspace.rb: ditto.
+
+	* test/ruby/test_object.rb: ditto.
+
+	* test/ruby/test_string.rb: ditto.
+
+	* test/ruby/test_method.rb: ditto.
+
+	* test/ruby/test_variable.rb: ditto.
+
+	* test/ruby/test_io.rb: ditto.
+
+	* test/ruby/test_rubyoptions.rb: ditto.
+
+	* test/ruby/test_exception.rb: ditto.
+
+	* test/ruby/test_class.rb: ditto.
+
+	* test/ruby/test_thread.rb: ditto.
+
 Tue Jul 15 22:34:03 2008  NAKAMURA Usaku  <usa@r...>
 
 	* win32/Makefile.sub (ruby_version): follow changes in configure.in.
Index: test/ruby/test_argf.rb
===================================================================
--- test/ruby/test_argf.rb	(revision 18081)
+++ test/ruby/test_argf.rb	(revision 18082)
@@ -131,92 +131,83 @@
   end
 
   def test_inplace
-    EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "while line = ARGF.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("", r.read)
-      assert_equal("1.new\n2.new\n", File.read(@t1.path))
-      assert_equal("3.new\n4.new\n", File.read(@t2.path))
-      assert_equal("5.new\n6.new\n", File.read(@t3.path))
-      assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
-      assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
-      assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
-    end
+    assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+      ARGF.inplace_mode = '.bak'
+      while line = ARGF.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
+    assert_equal("1.new\n2.new\n", File.read(@t1.path))
+    assert_equal("3.new\n4.new\n", File.read(@t2.path))
+    assert_equal("5.new\n6.new\n", File.read(@t3.path))
+    assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+    assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
+    assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
   end
 
   def test_inplace2
-    EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p ARGF.inplace_mode"
-      w.puts "ARGF.inplace_mode = nil"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p ARGF.inplace_mode"
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p ARGF.inplace_mode"
-      w.puts "ARGF.inplace_mode = nil"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("", r.read)
-      assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
-      assert_equal("3\n4\n", File.read(@t2.path))
-      assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
-      assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
-      assert_equal(false, File.file?(@t2.path + ".bak"))
-      assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
-    end
+    assert_in_out_err(["-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+      ARGF.inplace_mode = '.bak'
+      puts ARGF.gets.chomp + '.new'
+      puts ARGF.gets.chomp + '.new'
+      p ARGF.inplace_mode
+      ARGF.inplace_mode = nil
+      puts ARGF.gets.chomp + '.new'
+      puts ARGF.gets.chomp + '.new'
+      p ARGF.inplace_mode
+      ARGF.inplace_mode = '.bak'
+      puts ARGF.gets.chomp + '.new'
+      p ARGF.inplace_mode
+      ARGF.inplace_mode = nil
+      puts ARGF.gets.chomp + '.new'
+    INPUT
+    assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+    assert_equal("3\n4\n", File.read(@t2.path))
+    assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+    assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+    assert_equal(false, File.file?(@t2.path + ".bak"))
+    assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
   end
 
   def test_inplace3
-    EnvUtil.rubyexec("-i.bak", "-", @t1.path, @t2.path, @t3.path) do |w, r, e|
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p $-i"
-      w.puts "$-i = nil"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p $-i"
-      w.puts "$-i = '.bak'"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.puts "p $-i"
-      w.puts "$-i = nil"
-      w.puts "puts ARGF.gets.chomp + '.new'"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("", r.read)
-      assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
-      assert_equal("3\n4\n", File.read(@t2.path))
-      assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
-      assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
-      assert_equal(false, File.file?(@t2.path + ".bak"))
-      assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
-    end
+    assert_in_out_err(["-i.bak", "-", @t1.path, @t2.path, @t3.path], <<-INPUT, [], [])
+      puts ARGF.gets.chomp + '.new'
+      puts ARGF.gets.chomp + '.new'
+      p $-i
+      $-i = nil
+      puts ARGF.gets.chomp + '.new'
+      puts ARGF.gets.chomp + '.new'
+      p $-i
+      $-i = '.bak'
+      puts ARGF.gets.chomp + '.new'
+      p $-i
+      $-i = nil
+      puts ARGF.gets.chomp + '.new'
+    INPUT
+    assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+    assert_equal("3\n4\n", File.read(@t2.path))
+    assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+    assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+    assert_equal(false, File.file?(@t2.path + ".bak"))
+    assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
   end
 
   def test_inplace_rename_impossible
     t = make_tempfile
 
-    EnvUtil.rubyexec("-", t.path) do |w, r, e|
-      w.puts "ARGF.inplace_mode = '/\\\\'"
-      w.puts "while line = ARGF.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
+    assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+      ARGF.inplace_mode = '/\\\\'
+      while line = ARGF.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
       if no_safe_rename
-        assert_equal("", e.read)
-        assert_equal("", r.read)
+        assert_equal([], e)
+        assert_equal([], r)
         assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
       else
-        assert_match(/Can't rename .* to .*: .*. skipping file/, e.read) #'
-        assert_equal("", r.read)
+        assert_match(/Can't rename .* to .*: .*. skipping file/, e.first) #'
+        assert_equal([], r)
         assert_equal("foo\nbar\nbaz\n", File.read(t.path))
       end
     end
@@ -225,17 +216,17 @@
   def test_inplace_no_backup
     t = make_tempfile
 
-    EnvUtil.rubyexec("-", t.path) do |w, r, e|
-      w.puts "ARGF.inplace_mode = ''"
-      w.puts "while line = ARGF.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
+    assert_in_out_err(["-", t.path], <<-INPUT) do |r, e|
+      ARGF.inplace_mode = ''
+      while line = ARGF.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
       if no_safe_rename
-        assert_match(/Can't do inplace edit without backup/, e.read) #'
+        assert_match(/Can't do inplace edit without backup/, e.join) #'
       else
-        assert_equal("", e.read)
-        assert_equal("", r.read)
+        assert_equal([], e)
+        assert_equal([], r)
         assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
       end
     end
@@ -244,46 +235,37 @@
   def test_inplace_dup
     t = make_tempfile
 
-    EnvUtil.rubyexec("-", t.path) do |w, r, e|
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "f = ARGF.dup"
-      w.puts "while line = f.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("", r.read)
-      assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
-    end
+    assert_in_out_err(["-", t.path], <<-INPUT, [], [])
+      ARGF.inplace_mode = '.bak'
+      f = ARGF.dup
+      while line = f.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
+    assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
   end
 
   def test_inplace_stdin
     t = make_tempfile
 
-    EnvUtil.rubyexec("-", "-") do |w, r, e|
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "f = ARGF.dup"
-      w.puts "while line = f.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
-      assert_match("Can't do inplace edit for stdio; skipping", e.read)
-      assert_equal("", r.read)
-    end
+    assert_in_out_err(["-", "-"], <<-INPUT, [], /Can't do inplace edit for stdio; skipping/)
+      ARGF.inplace_mode = '.bak'
+      f = ARGF.dup
+      while line = f.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
   end
 
   def test_inplace_stdin2
     t = make_tempfile
 
-    EnvUtil.rubyexec("-") do |w, r, e|
-      w.puts "ARGF.inplace_mode = '.bak'"
-      w.puts "while line = ARGF.gets"
-      w.puts "  puts line.chomp + '.new'"
-      w.puts "end"
-      w.close
-      assert_match("Can't do inplace edit for stdio", e.read)
-      assert_equal("", r.read)
-    end
+    assert_in_out_err(["-"], <<-INPUT, [], /Can't do inplace edit for stdio/)
+      ARGF.inplace_mode = '.bak'
+      while line = ARGF.gets
+        puts line.chomp + '.new'
+      end
+    INPUT
   end
 
   def test_encoding
@@ -583,13 +565,8 @@
   end
 
   def test_each_line_paragraph
-    EnvUtil.rubyexec('-e', 'ARGF.each_line("") {|para| p para}') do |w, r, e|
-      w << "a\n\nb\n"
-      w.close
-      assert_equal("\"a\\n\\n\"\n", r.gets, "[ruby-dev:34958]")
-      assert_equal("\"b\\n\"\n", r.gets)
-      assert_equal(nil, r.gets)
-    end
+    assert_in_out_err(['-e', 'ARGF.each_line("") {|para| p para}'], "a\n\nb\n",
+                      ["\"a\\n\\n\"", "\"b\\n\""], [])
   end
 
   def test_each_byte
Index: test/ruby/test_module.rb
===================================================================
--- test/ruby/test_module.rb	(revision 18081)
+++ test/ruby/test_module.rb	(revision 18082)
@@ -30,10 +30,6 @@
     $VERBOSE = @verbose
   end
 
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def test_LT_0
     assert_equal true, String < Object
     assert_equal false, Object < String
@@ -476,20 +472,17 @@
   end
 
   def test_attr
-    ruby do |w, r, e|
-      w.puts "$VERBOSE = true"
-      w.puts "c = Class.new"
-      w.puts "c.instance_eval do"
-      w.puts "  private"
-      w.puts "  attr_reader :foo"
-      w.puts "end"
-      w.puts "o = c.new"
-      w.puts "o.foo rescue p(:ok)"
-      w.puts "p(o.instance_eval { foo })"
-      w.close
-      assert_equal(":ok\nnil", r.read.chomp)
-      assert_match(/warning: private attribute\?$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok nil), /warning: private attribute\?$/)
+      $VERBOSE = true
+      c = Class.new
+      c.instance_eval do
+        private
+        attr_reader :foo
+      end
+      o = c.new
+      o.foo rescue p(:ok)
+      p(o.instance_eval { foo })
+    INPUT
 
     c = Class.new
     assert_raise(NameError) do
@@ -521,13 +514,10 @@
     end
 
     %w(object_id __send__ initialize).each do |m|
-      ruby do |w, r, e|
-        w.puts "$VERBOSE = false"
-        w.puts "Class.new.instance_eval { undef_method(:#{m}) }"
-        w.close
-        assert_equal("", r.read.chomp)
-        assert_match(/warning: undefining `#{m}' may cause serious problem$/, e.read.chomp)
-      end
+      assert_in_out_err([], <<-INPUT, [], /warning: undefining `#{m}' may cause serious problem$/)
+        $VERBOSE = false
+        Class.new.instance_eval { undef_method(:#{m}) }
+      INPUT
     end
   end
 
@@ -537,19 +527,16 @@
       m.class_eval { alias foo bar }
     end
 
-    ruby do |w, r, e|
-      w.puts "$VERBOSE = true"
-      w.puts "c = Class.new"
-      w.puts "c.class_eval do"
-      w.puts "  def foo; 1; end"
-      w.puts "  def bar; 2; end"
-      w.puts "end"
-      w.puts "c.class_eval { alias foo bar }"
-      w.puts "p c.new.foo"
-      w.close
-      assert_equal("2", r.read.chomp)
-      assert_match(/warning: discarding old foo$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(2), /warning: discarding old foo$/)
+      $VERBOSE = true
+      c = Class.new
+      c.class_eval do
+        def foo; 1; end
+        def bar; 2; end
+      end
+      c.class_eval { alias foo bar }
+      p c.new.foo
+    INPUT
   end
 
   def test_mod_constants
@@ -618,17 +605,14 @@
   end
 
   def test_top_public_private
-    ruby do |w, r, e|
-      w.puts "private"
-      w.puts "def foo; :foo; end"
-      w.puts "public"
-      w.puts "def bar; :bar; end"
-      w.puts "p self.private_methods.grep(/^foo$|^bar$/)"
-      w.puts "p self.methods.grep(/^foo$|^bar$/)"
-      w.close
-      assert_equal("[:foo]\n[:bar]", r.read.chomp)
-      assert_equal("", e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), [])
+      private
+      def foo; :foo; end
+      public
+      def bar; :bar; end
+      p self.private_methods.grep(/^foo$|^bar$/)
+      p self.methods.grep(/^foo$|^bar$/)
+    INPUT
   end
 
   def test_append_features
Index: test/ruby/test_require.rb
===================================================================
--- test/ruby/test_require.rb	(revision 18081)
+++ test/ruby/test_require.rb	(revision 18082)
@@ -4,37 +4,28 @@
 require_relative 'envutil'
 
 class TestRequire < Test::Unit::TestCase
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def test_require_invalid_shared_object
     t = Tempfile.new(["test_ruby_test_require", ".so"])
     t.puts "dummy"
     t.close
 
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  require \"#{ t.path }\""
-      w.puts "rescue LoadError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      begin
+        require \"#{ t.path }\"
+      rescue LoadError
+        p :ok
+      end
+    INPUT
   end
 
   def test_require_too_long_filename
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  require '#{ "foo/" * 10000 }foo'"
-      w.puts "rescue LoadError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      e.read
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), /^.+$/)
+      begin
+        require '#{ "foo/" * 10000 }foo'
+      rescue LoadError
+        p :ok
+      end
+    INPUT
   end
 
   def test_require_path_home
@@ -42,30 +33,18 @@
 
     ENV["RUBYPATH"] = "~"
     ENV["HOME"] = "/foo" * 10000
-    ruby("-S", "test_ruby_test_require") do |w, r, e|
-      w.close
-      e.read
-      assert_equal("", r.read)
-    end
+    assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
 
     ENV["RUBYPATH"] = "~" + "/foo" * 10000
     ENV["HOME"] = "/foo"
-    ruby("-S", "test_ruby_test_require") do |w, r, e|
-      w.close
-      e.read
-      assert_equal("", r.read)
-    end
+    assert_in_out_err(%w(-S test_ruby_test_require), "", [], /^.+$/)
 
     t = Tempfile.new(["test_ruby_test_require", ".rb"])
     t.puts "p :ok"
     t.close
     ENV["RUBYPATH"] = "~"
     ENV["HOME"], name = File.split(t.path)
-    ruby("-S", name) do |w, r, e|
-      w.close
-      assert_equal(":ok", r.read.chomp)
-      assert_equal("", e.read)
-    end
+    assert_in_out_err(["-S", name], "", %w(:ok), [])
 
   ensure
     env_rubypath ? ENV["RUBYPATH"] = env_rubypath : ENV.delete("RUBYPATH")
@@ -79,44 +58,35 @@
       return
     end
 
-    ruby do |w, r, e|
-      w.puts "BasicSocket = 1"
-      w.puts "begin"
-      w.puts "  require 'socket'"
-      w.puts "  p :ng"
-      w.puts "rescue TypeError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      BasicSocket = 1
+      begin
+        require 'socket'
+        p :ng
+      rescue TypeError
+        p :ok
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "class BasicSocket; end"
-      w.puts "begin"
-      w.puts "  require 'socket'"
-      w.puts "  p :ng"
-      w.puts "rescue NameError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      class BasicSocket; end
+      begin
+        require 'socket'
+        p :ng
+      rescue NameError
+        p :ok
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "class BasicSocket < IO; end"
-      w.puts "begin"
-      w.puts "  require 'socket'"
-      w.puts "  p :ok"
-      w.puts "rescue Exception"
-      w.puts "  p :ng"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      class BasicSocket < IO; end
+      begin
+        require 'socket'
+        p :ok
+      rescue Exception
+        p :ng
+      end
+    INPUT
   end
 
   def test_define_class_under
@@ -126,47 +96,38 @@
       return
     end
 
-    ruby do |w, r, e|
-      w.puts "module Zlib; end"
-      w.puts "Zlib::Error = 1"
-      w.puts "begin"
-      w.puts "  require 'zlib'"
-      w.puts "  p :ng"
-      w.puts "rescue TypeError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      module Zlib; end
+      Zlib::Error = 1
+      begin
+        require 'zlib'
+        p :ng
+      rescue TypeError
+        p :ok
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "module Zlib; end"
-      w.puts "class Zlib::Error; end"
-      w.puts "begin"
-      w.puts "  require 'zlib'"
-      w.puts "  p :ng"
-      w.puts "rescue NameError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      module Zlib; end
+      class Zlib::Error; end
+      begin
+        require 'zlib'
+        p :ng
+      rescue NameError
+        p :ok
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "module Zlib; end"
-      w.puts "class Zlib::Error < StandardError; end"
-      w.puts "begin"
-      w.puts "  require 'zlib'"
-      w.puts "  p :ok"
-      w.puts "rescue Exception"
-      w.puts "  p :ng"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      module Zlib; end
+      class Zlib::Error < StandardError; end
+      begin
+        require 'zlib'
+        p :ok
+      rescue Exception
+        p :ng
+      end
+    INPUT
   end
 
   def test_define_module
@@ -176,18 +137,15 @@
       return
     end
 
-    ruby do |w, r, e|
-      w.puts "Zlib = 1"
-      w.puts "begin"
-      w.puts "  require 'zlib'"
-      w.puts "  p :ng"
-      w.puts "rescue TypeError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      Zlib = 1
+      begin
+        require 'zlib'
+        p :ng
+      rescue TypeError
+        p :ok
+      end
+    INPUT
   end
 
   def test_define_module_under
@@ -197,20 +155,17 @@
       return
     end
 
-    ruby do |w, r, e|
-      w.puts "class BasicSocket < IO; end"
-      w.puts "class Socket < BasicSocket; end"
-      w.puts "Socket::Constants = 1"
-      w.puts "begin"
-      w.puts "  require 'socket'"
-      w.puts "  p :ng"
-      w.puts "rescue TypeError"
-      w.puts "  p :ok"
-      w.puts "end"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":ok", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok), [])
+      class BasicSocket < IO; end
+      class Socket < BasicSocket; end
+      Socket::Constants = 1
+      begin
+        require 'socket'
+        p :ng
+      rescue TypeError
+        p :ok
+      end
+    INPUT
   end
 
   def test_load
@@ -221,14 +176,11 @@
     t.puts "p :ok"
     t.close
 
-    ruby do |w, r, e|
-      w.puts "load(#{ t.path.dump }, true)"
-      w.puts "GC.start"
-      w.puts "p :end"
-      w.close
-      assert_match(/error in at_exit test/, e.read)
-      assert_equal(":ok\n:end\n:wrap_end", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:ok :end :wrap_end), /error in at_exit test/)
+      load(#{ t.path.dump }, true)
+      GC.start
+      p :end
+    INPUT
 
     assert_raise(ArgumentError) { at_exit }
   end
Index: test/ruby/test_objectspace.rb
===================================================================
--- test/ruby/test_objectspace.rb	(revision 18081)
+++ test/ruby/test_objectspace.rb	(revision 18082)
@@ -56,16 +56,12 @@
   end
 
   def test_finalizer
-    EnvUtil.rubyexec("-e", <<-END) do |w, r, e|
+    assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
       a = []
       ObjectSpace.define_finalizer(a) { p :ok }
       b = a.dup
       ObjectSpace.define_finalizer(a) { p :ok }
     END
-      assert_equal("", e.read)
-      assert_equal(":ok\n:ok\n:ok\n:ok\n", r.read)
-
-      assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) }
-    end
+    assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) }
   end
 end
Index: test/ruby/test_object.rb
===================================================================
--- test/ruby/test_object.rb	(revision 18081)
+++ test/ruby/test_object.rb	(revision 18082)
@@ -11,10 +11,6 @@
     $VERBOSE = @verbose
   end
 
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def test_dup
     assert_raise(TypeError) { 1.dup }
     assert_raise(TypeError) { true.dup }
@@ -220,34 +216,25 @@
   end
 
   def test_redefine_method_under_verbose
-    ruby do |w, r, e|
-      w.puts "$VERBOSE = true"
-      w.puts "o = Object.new"
-      w.puts "def o.foo; 1; end"
-      w.puts "def o.foo; 2; end"
-      w.puts "p o.foo"
-      w.close
-      assert_equal("2", r.read.chomp)
-      assert_match(/warning: method redefined; discarding old foo$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(2), /warning: method redefined; discarding old foo$/)
+      $VERBOSE = true
+      o = Object.new
+      def o.foo; 1; end
+      def o.foo; 2; end
+      p o.foo
+    INPUT
   end
 
   def test_redefine_method_which_may_case_serious_problem
-    ruby do |w, r, e|
-      w.puts "$VERBOSE = false"
-      w.puts "def (Object.new).object_id; end"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/warning: redefining `object_id' may cause serious problem$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, [], /warning: redefining `object_id' may cause serious problem$/)
+      $VERBOSE = false
+      def (Object.new).object_id; end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "$VERBOSE = false"
-      w.puts "def (Object.new).__send__; end"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/warning: redefining `__send__' may cause serious problem$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, [], /warning: redefining `__send__' may cause serious problem$/)
+      $VERBOSE = false
+      def (Object.new).__send__; end
+    INPUT
   end
 
   def test_remove_method
@@ -272,17 +259,14 @@
     end
 
     %w(object_id __send__ initialize).each do |m|
-      ruby do |w, r, e|
-        w.puts "$VERBOSE = false"
-        w.puts "begin"
-        w.puts "  Class.new.instance_eval { remove_method(:#{m}) }"
-        w.puts "rescue NameError"
-        w.puts "  p :ok"
-        w.puts "end"
-        w.close
-        assert_equal(":ok", r.read.chomp)
-        assert_match(/warning: removing `#{m}' may cause serious problem$/, e.read.chomp)
-      end
+      assert_in_out_err([], <<-INPUT, %w(:ok), /warning: removing `#{m}' may cause serious problem$/)
+        $VERBOSE = false
+        begin
+          Class.new.instance_eval { remove_method(:#{m}) }
+        rescue NameError
+          p :ok
+        end
+      INPUT
     end
   end
 
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 18081)
+++ test/ruby/test_string.rb	(revision 18082)
@@ -687,9 +687,10 @@
     str = 'abc'
     a = [str.hash.to_s]
     3.times {
-      EnvUtil.rubyexec("-e", "print #{str.dump}.hash") {|i,o,e|
-        a << o.read
-      }
+      assert_in_out_err(["-e", "print #{str.dump}.hash"], "") do |r, e|
+        a += r
+        assert_equal([], e)
+      end
     }
     assert_not_equal([str.hash.to_s], a.uniq)
   end
Index: test/ruby/test_method.rb
===================================================================
--- test/ruby/test_method.rb	(revision 18081)
+++ test/ruby/test_method.rb	(revision 18082)
@@ -11,10 +11,6 @@
     $VERBOSE = @verbose
   end
 
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def m0() end
   def m1(a) end
   def m2(a, b) end
@@ -209,12 +205,7 @@
   end
 
   def test_callee_top_level
-    ruby do |w, r, e|
-      w.puts "p __callee__"
-      w.close
-      assert_equal("nil", r.read.chomp)
-      assert_match("", e.read.chomp)
-    end
+    assert_in_out_err([], "p __callee__", %w(nil), [])
   end
 
   def test_caller_negative_level
Index: test/ruby/test_variable.rb
===================================================================
--- test/ruby/test_variable.rb	(revision 18081)
+++ test/ruby/test_variable.rb	(revision 18082)
@@ -78,10 +78,6 @@
   end
 
   def test_global_variable_0
-    EnvUtil.rubyexec("-e", "$0='t'*1000;print $0") do |w, r, e|
-      w.close
-      assert_equal("", e.read)
-      assert_match(/\At+\z/, r.read)
-    end
+    assert_in_out_err(["-e", "$0='t'*1000;print $0"], "", /\At+\z/, [])
   end
 end
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 18081)
+++ test/ruby/test_io.rb	(revision 18082)
@@ -1080,12 +1080,7 @@
   def test_print
     t = make_tempfile
 
-    EnvUtil.rubyexec("-", t.path) do |w, r, e|
-      w.puts "print while $<.gets"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("foo\nbar\nbaz\n", r.read)
-    end
+    assert_in_out_err(["-", t.path], "print while $<.gets", %w(foo bar baz), [])
   end
 
   def test_putc
@@ -1097,12 +1092,7 @@
       assert_equal("ABD", r.read)
     end
 
-    EnvUtil.rubyexec do |w, r, e|
-      w.puts "putc 65"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("A", r.read)
-    end
+    assert_in_out_err([], "putc 65", %w(A), [])
   end
 
   def test_puts_recursive_array
@@ -1122,24 +1112,13 @@
       assert_equal("foo", r.read)
     end
 
-    EnvUtil.rubyexec do |w, r, e|
-      w.puts "'foo'.display"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("foo", r.read)
-    end
+    assert_in_out_err([], "'foo'.display", %w(foo), [])
   end
 
   def test_set_stdout
     assert_raise(TypeError) { $> = Object.new }
 
-    EnvUtil.rubyexec do |w, r, e|
-      w.puts "$> = $stderr"
-      w.puts "puts 'foo'"
-      w.close
-      assert_equal("foo\n", e.read)
-      assert_equal("", r.read)
-    end
+    assert_in_out_err([], "$> = $stderr\nputs 'foo'", [], %w(foo))
   end
 
   def test_initialize
@@ -1183,17 +1162,11 @@
   end
   
   def test_new_with_block
-    EnvUtil.rubyexec do |w, r, e|
-      w.puts "r, w = IO.pipe"
-      w.puts "IO.new(r) {}"
-      w.close
-      assert_not_equal("", e.read)
-      assert_equal("", r.read)
-    end
+    assert_in_out_err([], "r, w = IO.pipe; IO.new(r) {}", [], /^.+$/)
   end
 
   def test_readline2
-    EnvUtil.rubyexec("-e", <<-SRC) do |w, r, e|
+    assert_in_out_err(["-e", <<-SRC], "foo\nbar\nbaz\n", %w(foo bar baz end), [])
       puts readline
       puts readline
       puts readline
@@ -1203,24 +1176,11 @@
         puts "end"
       end
     SRC
-      w.puts "foo"
-      w.puts "bar"
-      w.puts "baz"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("foo\nbar\nbaz\nend\n", r.read)
-    end
   end
 
   def test_readlines
-    EnvUtil.rubyexec("-e", "p readlines") do |w, r, e|
-      w.puts "foo"
-      w.puts "bar"
-      w.puts "baz"
-      w.close
-      assert_equal("", e.read)
-      assert_equal("[\"foo\\n\", \"bar\\n\", \"baz\\n\"]\n", r.read)
-    end
+    assert_in_out_err(["-e", "p readlines"], "foo\nbar\nbaz\n",
+                      ["[\"foo\\n\", \"bar\\n\", \"baz\\n\"]"], [])
   end
 
   def test_s_read
Index: test/ruby/envutil.rb
===================================================================
--- test/ruby/envutil.rb	(revision 18081)
+++ test/ruby/envutil.rb	(revision 18082)
@@ -113,6 +113,63 @@
         out_c.close if out_c && !out_c.closed?
         out_p.close if out_p && !out_p.closed?
       end
+
+      LANG_ENVS = %w"LANG LC_ALL LC_CTYPE"
+      def assert_in_out_err(args, test_stdin = "", test_stdout = "", test_stderr = "", message = nil)
+        in_c, in_p = IO.pipe
+        out_p, out_c = IO.pipe
+        err_p, err_c = IO.pipe
+        c = "C"
+        env = {}
+        LANG_ENVS.each {|lc| env[lc], ENV[lc] = ENV[lc], c}
+        pid = spawn(EnvUtil.rubybin, *args, STDIN=>in_c, STDOUT=>out_c, STDERR=>err_c)
+        in_c.close
+        out_c.close
+        err_c.close
+        in_p.write test_stdin
+        in_p.close
+        th_stdout = Thread.new { out_p.read }
+        th_stderr = Thread.new { err_p.read }
+        if th_stdout.join(10) && th_stderr.join(10)
+          stdout = th_stdout.value
+          stderr = th_stderr.value
+        else
+          flunk("timeout")
+        end
+        out_p.close
+        err_p.close
+        Process.wait pid
+        if block_given?
+          yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp })
+        else
+          if test_stdout.is_a?(Regexp)
+            assert_match(test_stdout, stdout, message)
+          else
+            assert_equal(test_stdout, stdout.lines.map {|l| l.chomp }, message)
+          end
+          if test_stderr.is_a?(Regexp)
+            assert_match(test_stderr, stderr, message)
+          else
+            assert_equal(test_stderr, stderr.lines.map {|l| l.chomp }, message)
+          end
+        end
+      ensure
+        env.each_pair {|lc, v|
+          if v
+            ENV[lc] = v
+          else
+            ENV.delete(lc)
+          end
+        } if env
+        in_c.close if in_c && !in_c.closed?
+        in_p.close if in_p && !in_p.closed?
+        out_c.close if out_c && !out_c.closed?
+        out_p.close if out_p && !out_p.closed?
+        err_c.close if err_c && !err_c.closed?
+        err_p.close if err_p && !err_p.closed?
+        (th_stdout.kill; th_stdout.join) if th_stdout
+        (th_stderr.kill; th_stderr.join) if th_stderr
+      end
     end
   end
 end
Index: test/ruby/test_rubyoptions.rb
===================================================================
--- test/ruby/test_rubyoptions.rb	(revision 18081)
+++ test/ruby/test_rubyoptions.rb	(revision 18082)
@@ -5,360 +5,213 @@
 require_relative 'envutil'
 
 class TestRubyOptions < Test::Unit::TestCase
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def test_source_file
-    ruby('') do |w, r, e|
-      w.close
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
+    assert_in_out_err([], "", [], [])
   end
 
   def test_usage
-    ruby('-h') do |w, r, e|
-      w.close
-      assert(r.readlines.size <= 24)
+    assert_in_out_err(%w(-h)) do |r, e|
+      assert_operator(r.size, :<=, 24)
+      assert_equal([], e)
     end
 
-    ruby('--help') do |w, r, e|
-      w.close
-      assert(r.readlines.size <= 24)
+    assert_in_out_err(%w(--help)) do |r, e|
+      assert_operator(r.size, :<=, 24)
+      assert_equal([], e)
     end
   end
 
   def test_option_variables
-    ruby('-e', 'p [$-p, $-l, $-a]') do |w, r, e|
-      assert_equal('[false, false, false]', r.read.chomp)
+    assert_in_out_err(["-e", 'p [$-p, $-l, $-a]']) do |r, e|
+      assert_equal(["[false, false, false]"], r)
+      assert_equal([], e)
     end
 
-    ruby('-p', '-l', '-a', '-e', 'p [$-p, $-l, $-a]') do |w, r, e|
-      w.puts 'foo'
-      w.puts 'bar'
-      w.puts 'baz'
-      w.close_write
-      r = r.readlines.map {|l| l.chomp }
+    assert_in_out_err(%w(-p -l -a -e) + ['p [$-p, $-l, $-a]'],
+                      "foo\nbar\nbaz\n") do |r, e|
       assert_equal(
         [ '[true, true, true]', 'foo',
           '[true, true, true]', 'bar',
           '[true, true, true]', 'baz' ], r)
+      assert_equal([], e)
     end
   end
 
   def test_warning
-    ruby('-W0', '-e', 'p $-W') do |w, r, e|
-      assert_equal('0', r.read.chomp)
-    end
-    ruby('-W1', '-e', 'p $-W') do |w, r, e|
-      assert_equal('1', r.read.chomp)
-    end
-    ruby('-Wx', '-e', 'p $-W') do |w, r, e|
-      assert_equal('1', r.read.chomp)
-    end
-    ruby('-W', '-e', 'p $-W') do |w, r, e|
-      assert_equal('2', r.read.chomp)
-    end
+    assert_in_out_err(%w(-W0 -e) + ['p $-W'], "", %w(0), [])
+    assert_in_out_err(%w(-W1 -e) + ['p $-W'], "", %w(1), [])
+    assert_in_out_err(%w(-Wx -e) + ['p $-W'], "", %w(1), [])
+    assert_in_out_err(%w(-W -e) + ['p $-W'], "", %w(2), [])
   end
 
   def test_safe_level
-    ruby('-T', '-e', '') do |w, r, e|
-      assert_match(/no -e allowed in tainted mode \(SecurityError\)/, e.read)
-    end
+    assert_in_out_err(%w(-T -e) + [""], "", [],
+                      /no -e allowed in tainted mode \(SecurityError\)/)
 
-    ruby('-T4', '-S', 'foo.rb') do |w, r, e|
-      assert_match(/no -S allowed in tainted mode \(SecurityError\)/, e.read)
-    end
+    assert_in_out_err(%w(-T4 -S foo.rb), "", [],
+                      /no -S allowed in tainted mode \(SecurityError\)/)
   end
 
   def test_debug
-    ruby('-de', 'p $DEBUG') do |w, r, e|
-      assert_equal('true', r.read.chomp)
-    end
+    assert_in_out_err(%w(-de) + ["p $DEBUG"], "", %w(true), [])
 
-    ruby('--debug', '-e', 'p $DEBUG') do |w, r, e|
-      assert_equal('true', r.read.chomp)
-    end
+    assert_in_out_err(%w(--debug -e) + ["p $DEBUG"], "", %w(true), [])
   end
 
   def test_verbose
-    ruby('-vve', '') do |w, r, e|
-      description = r.read
-      assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, description)
-      assert_equal RUBY_DESCRIPTION, description.chomp
+    assert_in_out_err(%w(-vve) + [""]) do |r, e|
+      assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.join)
+      assert_equal RUBY_DESCRIPTION, r.join.chomp
+      assert_equal([], e)
     end
 
-    ruby('--verbose', '-e', 'p $VERBOSE') do |w, r, e|
-      assert_equal('true', r.read.chomp)
-    end
+    assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
 
-    ruby('--verbose') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
+    assert_in_out_err(%w(--verbose), "", [], [])
   end
 
   def test_copyright
-    ruby('--copyright') do |w, r, e|
-      assert_match(/^ruby - Copyright \(C\) 1993-\d+ Yukihiro Matsumoto$/, r.read)
-    end
+    assert_in_out_err(%w(--copyright), "",
+                      /^ruby - Copyright \(C\) 1993-\d+ Yukihiro Matsumoto$/, [])
 
-    ruby('--verbose', '-e', 'p $VERBOSE') do |w, r, e|
-      assert_equal('true', r.read.chomp)
-    end
+    assert_in_out_err(%w(--verbose -e) + ["p $VERBOSE"], "", %w(true), [])
   end
 
   def test_enable
-    ruby('--enable', 'all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--enable-all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--enable=all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--enable', 'foobarbazqux', '-e', '') do |w, r, e|
-      assert_match(/unknown argument for --enable: `foobarbazqux'/, e.read) #`
-    end
-
-    ruby('--enable') do |w, r, e|
-      assert_match(/missing argument for --enable/, e.read)
-    end
+    assert_in_out_err(%w(--enable all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--enable-all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--enable=all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--enable foobarbazqux -e) + [""], "", [],
+                      /unknown argument for --enable: `foobarbazqux'/)
+    assert_in_out_err(%w(--enable), "", [], /missing argument for --enable/)
   end
 
   def test_disable
-    ruby('--disable', 'all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--disable-all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--disable=all', '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
-
-    ruby('--disable', 'foobarbazqux', '-e', '') do |w, r, e|
-      assert_match(/unknown argument for --disable: `foobarbazqux'/, e.read) #`
-    end
-
-    ruby('--disable') do |w, r, e|
-      assert_match(/missing argument for --disable/, e.read)
-    end
+    assert_in_out_err(%w(--disable all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--disable-all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--disable=all -e) + [""], "", [], [])
+    assert_in_out_err(%w(--disable foobarbazqux -e) + [""], "", [],
+                      /unknown argument for --disable: `foobarbazqux'/)
+    assert_in_out_err(%w(--disable), "", [], /missing argument for --disable/)
   end
 
   def test_kanji
-    ruby('-KU') do |w, r, e|
-      w.puts "p '\u3042'"
-      w.close
-      assert_equal("\"\u3042\"", r.read.chomp.force_encoding(Encoding.find('utf-8')))
+    assert_in_out_err(%w(-KU), "p '\u3042'") do |r, e|
+      assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
     end
-
-    ruby('-KE', '-e', '') do |w, r, e|
-      assert_equal("", r.read)
-      assert_equal("", e.read)
-    end
-
-    ruby('-KS', '-e', '') do |w, r, e|
-      assert_equal("", r.read)
-      assert_equal("", e.read)
-    end
-
-    ruby('-KN', '-e', '') do |w, r, e|
-      assert_equal("", r.read)
-      assert_equal("", e.read)
-    end
+    assert_in_out_err(%w(-KE -e) + [""], "", [], [])
+    assert_in_out_err(%w(-KS -e) + [""], "", [], [])
+    assert_in_out_err(%w(-KN -e) + [""], "", [], [])
   end
 
   def test_version
-    ruby('--version') do |w, r, e|
-      assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.read)
+    assert_in_out_err(%w(--version)) do |r, e|
+      assert_match(/^ruby #{RUBY_VERSION} .*? \[#{RUBY_PLATFORM}\]$/, r.join)
+      assert_equal RUBY_DESCRIPTION, r.join.chomp
+      assert_equal([], e)
     end
   end
 
   def test_eval
-    ruby('-e') do |w, r, e|
-      assert_match(/no code specified for -e \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err(%w(-e), "", [], /no code specified for -e \(RuntimeError\)/)
   end
 
   def test_require
-    ruby('-r', 'pp', '-e', 'pp 1') do |w, r, e|
-      assert_equal('1', r.read.chomp)
-    end
-    ruby('-rpp', '-e', 'pp 1') do |w, r, e|
-      w.close
-      assert_equal('1', r.read.chomp)
-    end
+    require "pp"
+    assert_in_out_err(%w(-r pp -e) + ["pp 1"], "", %w(1), [])
+    assert_in_out_err(%w(-rpp -e) + ["pp 1"], "", %w(1), [])
+  rescue LoadError
   end
 
   def test_include
     d = Dir.tmpdir
-    ruby('-I' + d, '-e', '') do |w, r, e|
-      assert_equal('', e.read.chomp)
-      assert_equal('', r.read.chomp)
-    end
-
-    d = Dir.tmpdir
-    ruby('-I', d, '-e', '') do |w, r, e|
-      assert_equal('', e.read.chomp)
-      assert_equal('', r.read.chomp)
-    end
+    assert_in_out_err(["-I" + d, "-e", ""], "", [], [])
+    assert_in_out_err(["-I", d, "-e", ""], "", [], [])
   end
 
   def test_separator
-    ruby('-000', '-e', 'print gets') do |w, r, e|
-      w.write "foo\nbar\0baz"
-      w.close
-      assert_equal('', e.read)
-      assert_equal("foo\nbar\0baz", r.read)
-    end
+    assert_in_out_err(%w(-000 -e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0baz), [])
 
-    ruby('-0141', '-e', 'print gets') do |w, r, e|
-      w.write "foo\nbar\0baz"
-      w.close
-      assert_equal('', e.read)
-      assert_equal("foo\nba", r.read)
-    end
+    assert_in_out_err(%w(-0141 -e) + ["print gets"], "foo\nbar\0baz", %w(foo ba), [])
 
-    ruby('-0e', 'print gets') do |w, r, e|
-      w.write "foo\nbar\0baz"
-      w.close
-      assert_equal('', e.read)
-      assert_equal("foo\nbar\0", r.read)
-    end
+    assert_in_out_err(%w(-0e) + ["print gets"], "foo\nbar\0baz", %W(foo bar\0), [])
   end
 
   def test_autosplit
-    ruby('-an', '-F:', '-e', 'p $F') do |w, r, e|
-      w.puts "foo:bar:baz"
-      w.puts "qux:quux:quuux"
-      w.close
-      r = r.readlines.map {|l| l.chomp }
-      assert_equal(['["foo", "bar", "baz\n"]', '["qux", "quux", "quuux\n"]'], r)
-    end
+    assert_in_out_err(%w(-an -F: -e) + ["p $F"], "foo:bar:baz\nqux:quux:quuux\n",
+                      ['["foo", "bar", "baz\n"]', '["qux", "quux", "quuux\n"]'], [])
   end
 
   def test_chdir
-    ruby('-C') do |w, r, e|
-      assert_match(/Can't chdir/, e.read)
-    end
+    assert_in_out_err(%w(-C), "", [], /Can't chdir/)
 
-    ruby('-C', 'test_ruby_test_rubyoptions_foobarbazqux') do |w, r, e|
-      assert_match(/Can't chdir/, e.read)
-    end
+    assert_in_out_err(%w(-C test_ruby_test_rubyoptions_foobarbazqux), "", [], /Can't chdir/)
 
     d = Dir.tmpdir
-    ruby('-C', d, '-e', 'puts Dir.pwd') do |w, r, e|
-      assert_equal('', e.read)
-      assert(File.identical?(r.read.chomp, d))
+    assert_in_out_err(["-C", d, "-e", "puts Dir.pwd"]) do |r, e|
+      assert(File.identical?(r.join, d))
+      assert_equal([], e)
     end
   end
 
   def test_yydebug
-    ruby('-ye', '') do |w, r, e|
-      assert_equal("", r.read)
-      assert_nothing_raised { e.read }
+    assert_in_out_err(["-ye", ""]) do |r, e|
+      assert_equal([], r)
+      assert_not_equal([], e)
     end
 
-    ruby('--yydebug', '-e', '') do |w, r, e|
-      assert_equal("", r.read)
-      assert_nothing_raised { e.read }
+    assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
+      assert_equal([], r)
+      assert_not_equal([], e)
     end
   end
 
   def test_encoding
-    ruby('-Eutf-8') do |w, r, e|
-      w.puts "p '\u3042'"
-      w.close
-      assert_match(/invalid multibyte char/, e.read)
-    end
+    assert_in_out_err(%w(-Eutf-8), "p '\u3042'", [], /invalid multibyte char/)
 
-    ruby('--encoding') do |w, r, e|
-      assert_match(/missing argument for --encoding/, e.read)
-    end
+    assert_in_out_err(%w(--encoding), "", [], /missing argument for --encoding/)
 
-    ruby('--encoding', 'test_ruby_test_rubyoptions_foobarbazqux') do |w, r, e|
-      assert_match(/unknown encoding name - test_ruby_test_rubyoptions_foobarbazqux \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err(%w(--encoding test_ruby_test_rubyoptions_foobarbazqux), "", [],
+                      /unknown encoding name - test_ruby_test_rubyoptions_foobarbazqux \(RuntimeError\)/)
 
-    ruby('--encoding', 'utf-8') do |w, r, e|
-      w.puts "p '\u3042'"
-      w.close
-      assert_match(/invalid multibyte char/, e.read)
-    end
+    assert_in_out_err(%w(--encoding utf-8), "p '\u3042'", [], /invalid multibyte char/)
   end
 
   def test_syntax_check
-    ruby('-c', '-e', '1+1') do |w, r, e|
-      assert_equal('Syntax OK', r.read.chomp)
-    end
+    assert_in_out_err(%w(-c -e 1+1), "", ["Syntax OK"], [])
   end
 
   def test_invalid_option
-    ruby('--foobarbazqux') do |w, r, e|
-      assert_match(/invalid option --foobarbazqux/, e.read)
-    end
+    assert_in_out_err(%w(--foobarbazqux), "", [], /invalid option --foobarbazqux/)
 
-    ruby("-\r", '-e', '') do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
+    assert_in_out_err(%W(-\r -e) + [""], "", [], [])
 
-    ruby("-\rx") do |w, r, e|
-      assert_match(/invalid option -\\x0D  \(-h will show valid options\) \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err(%W(-\rx), "", [], /invalid option -\\x0D  \(-h will show valid options\) \(RuntimeError\)/)
 
-    ruby("-\x01") do |w, r, e|
-      assert_match(/invalid option -\\x01  \(-h will show valid options\) \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err(%W(-\x01), "", [], /invalid option -\\x01  \(-h will show valid options\) \(RuntimeError\)/)
 
-    ruby('-Z') do |w, r, e|
-      assert_match(/invalid option -Z  \(-h will show valid options\) \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err(%w(-Z), "", [], /invalid option -Z  \(-h will show valid options\) \(RuntimeError\)/)
   end
 
   def test_rubyopt
     rubyopt_orig = ENV['RUBYOPT']
 
     ENV['RUBYOPT'] = ' - -'
-    ruby do |w, r, e|
-      w.close
-      assert_equal('', e.read)
-      assert_equal('', r.read)
-    end
+    assert_in_out_err([], "", [], [])
 
     ENV['RUBYOPT'] = '-e "p 1"'
-    ruby do |w, r, e|
-      assert_match(/invalid switch in RUBYOPT: -e \(RuntimeError\)/, e.read)
-    end
+    assert_in_out_err([], "", [], /invalid switch in RUBYOPT: -e \(RuntimeError\)/)
 
     ENV['RUBYOPT'] = '-T1'
-    ruby do |w, r, e|
-      assert_match(/no program input from stdin allowed in tainted mode \(SecurityError\)/, e.read)
-    end
+    assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
 
     ENV['RUBYOPT'] = '-T4'
-    ruby do |w, r, e|
-    end
+    assert_in_out_err([], "", [], /no program input from stdin allowed in tainted mode \(SecurityError\)/)
 
     ENV['RUBYOPT'] = '-KN -Eus-ascii'
-    ruby('-KU', '-Eutf-8') do |w, r, e|
-      w.puts "p '\u3042'"
-      w.close
-      assert_equal("\"\u3042\"", r.read.chomp.force_encoding(Encoding.find('utf-8')))
+    assert_in_out_err(%w(-KU -Eutf-8), "p '\u3042'") do |r, e|
+      assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+      assert_equal([], e)
     end
 
   ensure
@@ -382,17 +235,11 @@
 
     ENV['PATH'] = File.dirname(t.path)
 
-    ruby('-S', File.basename(t.path)) do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('1', r.read.chomp)
-    end
+    assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
 
     ENV['RUBYPATH'] = File.dirname(t.path)
 
-    ruby('-S', File.basename(t.path)) do |w, r, e|
-      assert_equal('', e.read)
-      assert_equal('1', r.read.chomp)
-    end
+    assert_in_out_err(%w(-S) + [File.basename(t.path)], "", %w(1), [])
 
   ensure
     if rubypath_orig
@@ -410,48 +257,27 @@
   end
 
   def test_shebang
-    ruby do |w, r, e|
-      w.print "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux\r\np 1\r\n"
-      w.close
-      assert_match(/Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/, e.read) #'
-      assert_equal('', r.read.chomp)
-    end
+    assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux\r\np 1\r\n",
+                      [], /Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/)
 
-    ruby do |w, r, e|
-      w.print "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux -foo -bar\r\np 1\r\n"
-      w.close
-      assert_match(/Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/, e.read) #'
-      assert_equal('', r.read.chomp)
-    end
+    assert_in_out_err([], "#! /test_r_u_b_y_test_r_u_b_y_options_foobarbazqux -foo -bar\r\np 1\r\n",
+                      [], /Can't exec [\/\\]test_r_u_b_y_test_r_u_b_y_options_foobarbazqux \(fatal\)/)
 
-    ruby do |w, r, e|
-      w.print "#!ruby -KU -Eutf-8\r\np \"\u3042\"\r\n"
-      w.close
-      assert_equal('', e.read.chomp)
-      assert_equal("\"\u3042\"", r.read.chomp.force_encoding(Encoding.find('utf-8')))
+    assert_in_out_err([], "#!ruby -KU -Eutf-8\r\np \"\u3042\"\r\n") do |r, e|
+      assert_equal("\"\u3042\"", r.join.force_encoding(Encoding::UTF_8))
+      assert_equal([], e)
     end
   end
 
   def test_sflag
-    ruby('-', '-abc', '-def=foo', '-ghi-jkl', '--', '-xyz') do |w, r, e|
-      w.print "#!ruby -s\np [$abc, $def, $ghi_jkl, $xyz]\n"
-      w.close
-      assert_equal('', e.read)
-      assert_equal('[true, "foo", true, nil]', r.read.chomp)
-    end
+    assert_in_out_err(%w(- -abc -def=foo -ghi-jkl -- -xyz),
+                      "#!ruby -s\np [$abc, $def, $ghi_jkl, $xyz]\n",
+                      ['[true, "foo", true, nil]'], [])
 
-    ruby('-', '-#') do |w, r, e|
-      w.print "#!ruby -s\n"
-      w.close
-      assert_match(/invalid name for global variable - -# \(NameError\)/, e.read)
-      assert_equal('', r.read.chomp)
-    end
+    assert_in_out_err(%w(- -#), "#!ruby -s\n", [],
+                      /invalid name for global variable - -# \(NameError\)/)
 
-    ruby('-', '-#=foo') do |w, r, e|
-      w.print "#!ruby -s\n"
-      w.close
-      assert_match(/invalid name for global variable - -# \(NameError\)/, e.read)
-      assert_equal('', r.read.chomp)
-    end
+    assert_in_out_err(%w(- -#=foo), "#!ruby -s\n", [],
+                      /invalid name for global variable - -# \(NameError\)/)
   end
 end
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 18081)
+++ test/ruby/test_exception.rb	(revision 18082)
@@ -2,10 +2,6 @@
 require_relative 'envutil'
 
 class TestException < Test::Unit::TestCase
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   def test_exception
     begin
       raise "this must be handled"
@@ -197,53 +193,34 @@
   end
 
   def test_errat
-    ruby do |w, r, e|
-      w.puts "p $@"
-      w.close
-      assert_equal("nil", r.read.chomp)
-      assert_equal("", e.read.chomp)
-    end
+    assert_in_out_err([], "p $@", %w(nil), [])
 
-    ruby do |w, r, e|
-      w.puts "$@ = 1"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/\$! not set \(ArgumentError\)$/, e.read.chomp)
-    end
+    assert_in_out_err([], "$@ = 1", [], /\$! not set \(ArgumentError\)$/)
 
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  raise"
-      w.puts "rescue"
-      w.puts "  $@ = 1"
-      w.puts "end"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/backtrace must be Array of String \(TypeError\)$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, [], /backtrace must be Array of String \(TypeError\)$/)
+      begin
+        raise
+      rescue
+        $@ = 1
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  raise"
-      w.puts "rescue"
-      w.puts "  $@ = 'foo'"
-      w.puts "  raise"
-      w.puts "end"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/^foo: unhandled exception$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception$/)
+      begin
+        raise
+      rescue
+        $@ = 'foo'
+        raise
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  raise"
-      w.puts "rescue"
-      w.puts "  $@ = %w(foo bar baz)"
-      w.puts "  raise"
-      w.puts "end"
-      w.close
-      assert_equal("", r.read.chomp)
-      assert_match(/^foo: unhandled exception\s+from bar\s+from baz$/, e.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, [], /^foo: unhandled exception\s+from bar\s+from baz$/)
+      begin
+        raise
+      rescue
+        $@ = %w(foo bar baz)
+        raise
+      end
+    INPUT
   end
 end
Index: test/ruby/test_class.rb
===================================================================
--- test/ruby/test_class.rb	(revision 18081)
+++ test/ruby/test_class.rb	(revision 18082)
@@ -2,10 +2,6 @@
 require_relative 'envutil'
 
 class TestClass < Test::Unit::TestCase
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   # ------------------
   # Various test classes
   # ------------------
@@ -133,18 +129,15 @@
     assert_raise(TypeError) { 1.extend(Module.new) }
     assert_raise(TypeError) { :foo.extend(Module.new) }
 
-    ruby do |w, r, e|
-      w.puts "module Foo; def foo; :foo; end; end"
-      w.puts "false.extend(Foo)"
-      w.puts "true.extend(Foo)"
-      w.puts "p false.foo"
-      w.puts "p true.foo"
-      w.puts "p FalseClass.include?(Foo)"
-      w.puts "p TrueClass.include?(Foo)"
-      w.close
-      assert_equal("", e.read)
-      assert_equal(":foo\n:foo\ntrue\ntrue", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(:foo :foo true true), [])
+      module Foo; def foo; :foo; end; end
+      false.extend(Foo)
+      true.extend(Foo)
+      p false.foo
+      p true.foo
+      p FalseClass.include?(Foo)
+      p TrueClass.include?(Foo)
+    INPUT
   end
 
   def test_uninitialized
Index: test/ruby/test_thread.rb
===================================================================
--- test/ruby/test_thread.rb	(revision 18081)
+++ test/ruby/test_thread.rb	(revision 18082)
@@ -3,10 +3,6 @@
 require_relative 'envutil'
 
 class TestThread < Test::Unit::TestCase
-  def ruby(*r, &b)
-    EnvUtil.rubyexec(*r, &b)
-  end
-
   class Thread < ::Thread
     Threads = []
     def self.new(*)
@@ -180,13 +176,11 @@
   end
 
   def test_kill_main_thread
-    ruby do |w, r, e|
-      w.puts "p 1"
-      w.puts "Thread.kill Thread.current"
-      w.puts "p 2"
-      w.close
-      assert_equal("1", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(1), [])
+      p 1
+      Thread.kill Thread.current
+      p 2
+    INPUT
   end
 
   def test_exit
@@ -218,104 +212,83 @@
   end
 
   def test_stop
-    ruby do |w, r, e|
-      w.puts "begin"
-      w.puts "  Thread.stop"
-      w.puts "  p 1"
-      w.puts "rescue ThreadError"
-      w.puts "  p 2"
-      w.puts "end"
-      w.close
-      assert_equal("2", r.read.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(2), [])
+      begin
+        Thread.stop
+        p 1
+      rescue ThreadError
+        p 2
+      end
+    INPUT
   end
 
   def test_list
-    ruby do |w, r, e|
-      w.puts "t1 = Thread.new { sleep }"
-      w.puts "t2 = Thread.new { loop { } }"
-      w.puts "t3 = Thread.new { }.join"
-      w.puts "p [Thread.current, t1, t2].sort_by {|t| t.object_id }"
-      w.puts "p Thread.list.sort_by {|t| t.object_id }"
-      w.close
-      assert_equal(r.gets, r.gets)
+    assert_in_out_err([], <<-INPUT) do |r, e|
+      t1 = Thread.new { sleep }
+      t2 = Thread.new { loop { } }
+      t3 = Thread.new { }.join
+      p [Thread.current, t1, t2].sort_by {|t| t.object_id }
+      p Thread.list.sort_by {|t| t.object_id }
+    INPUT
+      assert_equal(r.first, r.last)
+      assert_equal([], e)
     end
   end
 
   def test_main
-    ruby do |w, r, e|
-      w.puts "p Thread.main == Thread.current"
-      w.puts "Thread.new { p Thread.main == Thread.current }.join"
-      w.close
-      assert_equal("true", r.gets.chomp)
-      assert_equal("false", r.gets.chomp)
-    end
+    assert_in_out_err([], <<-INPUT, %w(true false), [])
+      p Thread.main == Thread.current
+      Thread.new { p Thread.main == Thread.current }.join
+    INPUT
   end
 
   def test_abort_on_exception
-    ruby do |w, r, e|
-      w.puts "p Thread.abort_on_exception"
-      w.puts "begin"
-      w.puts "  Thread.new { raise }"
-      w.puts "  sleep 0.5"
-      w.puts "  p 1"
-      w.puts "rescue"
-      w.puts "  p 2"
-      w.puts "end"
-      w.close_write
-      assert_equal("false", r.gets.chomp)
-      assert_equal("1", r.gets.chomp)
-      assert_equal("", e.read)
-    end
+    assert_in_out_err([], <<-INPUT, %w(false 1), [])
+      p Thread.abort_on_exception
+      begin
+        Thread.new { raise }
+        sleep 0.5
+        p 1
+      rescue
+        p 2
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "Thread.abort_on_exception = true"
-      w.puts "p Thread.abort_on_exception"
-      w.puts "begin"
-      w.puts "  Thread.new { raise }"
-      w.puts "  sleep 0.5"
-      w.puts "  p 1"
-      w.puts "rescue"
-      w.puts "  p 2"
-      w.puts "end"
-      w.close_write
-      assert_equal("true", r.gets.chomp)
-      assert_equal("2", r.gets.chomp)
-      assert_equal("", e.read)
-    end
+    assert_in_out_err([], <<-INPUT, %w(true 2), [])
+      Thread.abort_on_exception = true
+      p Thread.abort_on_exception
+      begin
+        Thread.new { raise }
+        sleep 0.5
+        p 1
+      rescue
+        p 2
+      end
+    INPUT
 
-    ruby('-d') do |w, r, e|
-      w.puts "p Thread.abort_on_exception"
-      w.puts "begin"
-      w.puts "  Thread.new { raise }"
-      w.puts "  sleep 0.5"
-      w.puts "  p 1"
-      w.puts "rescue"
-      w.puts "  p 2"
-      w.puts "end"
-      w.close_write
-      assert_equal("false", r.gets.chomp)
-      assert_equal("2", r.gets.chomp)
-      assert_not_equal("", e.read)
-    end
+    assert_in_out_err(%w(-d), <<-INPUT, %w(false 2), /.+/)
+      p Thread.abort_on_exception
+      begin
+        Thread.new { raise }
+        sleep 0.5
+        p 1
+      rescue
+        p 2
+      end
+    INPUT
 
-    ruby do |w, r, e|
-      w.puts "p Thread.abort_on_exception"
-      w.puts "begin"
-      w.puts "  t = Thread.new { sleep 0.5; raise }"
-      w.puts "  t.abort_on_exception = true"
-      w.puts "  p t.abort_on_exception"
-      w.puts "  sleep 1"
-      w.puts "  p 1"
-      w.puts "rescue"
-      w.puts "  p 2"
-      w.puts "end"
-      w.close_write
-      assert_equal("false", r.gets.chomp)
-      assert_equal("true", r.gets.chomp)
-      assert_equal("2", r.gets.chomp)
-      assert_equal("", e.read)
-    end
+    assert_in_out_err([], <<-INPUT, %w(false true 2), [])
+      p Thread.abort_on_exception
+      begin
+        t = Thread.new { sleep 0.5; raise }
+        t.abort_on_exception = true
+        p t.abort_on_exception
+        sleep 1
+        p 1
+      rescue
+        p 2
+      end
+    INPUT
   end
 
   def test_status_and_stop_p

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]