ruby-changes:9378
From: akr <ko1@a...>
Date: Mon, 22 Dec 2008 21:27:44 +0900 (JST)
Subject: [ruby-changes:9378] Ruby:r20916 (trunk): * io.c (rb_io_s_pipe): IO.pipe can take a block.
akr 2008-12-22 21:27:26 +0900 (Mon, 22 Dec 2008) New Revision: 20916 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20916 Log: * io.c (rb_io_s_pipe): IO.pipe can take a block. (pipe_close): new function. Modified files: trunk/ChangeLog trunk/NEWS trunk/io.c trunk/test/ruby/test_io.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 20915) +++ ChangeLog (revision 20916) @@ -1,3 +1,8 @@ +Mon Dec 22 21:26:12 2008 Tanaka Akira <akr@f...> + + * io.c (rb_io_s_pipe): IO.pipe can take a block. + (pipe_close): new function. + Mon Dec 22 21:08:54 2008 Tanaka Akira <akr@f...> * lib/test/unit/assertions.rb (assert_nothing_raised): increment Index: io.c =================================================================== --- io.c (revision 20915) +++ io.c (revision 20916) @@ -6906,6 +6906,21 @@ } +static +VALUE pipe_close(VALUE args) +{ + VALUE *rw = (VALUE*)args; + VALUE io; + int i; + + for (i = 0; i < 2; i++) { + io = rw[i]; + if (!rb_io_closed(io)) + rb_io_close(io); + } + return Qnil; +} + /* * call-seq: * IO.pipe -> [read_io, write_io] @@ -6913,11 +6928,18 @@ * IO.pipe("ext_enc:int_enc" [, opt]) -> [read_io, write_io] * IO.pipe(ext_enc, int_enc [, opt]) -> [read_io, write_io] * + * IO.pipe(...) {|read_io, write_io| ... } + * * Creates a pair of pipe endpoints (connected to each other) and * returns them as a two-element array of <code>IO</code> objects: - * <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>. Not - * available on all platforms. + * <code>[</code> <i>read_io</i>, <i>write_io</i> <code>]</code>. * + * If a block is given, the block is called and + * returns the value of the block. + * <i>read_io</i> and <i>write_io</i> are sent to the block as arguments. + * + * Not available on all platforms. + * * If an encoding (encoding name or encoding object) is specified as an optional argument, * read string from pipe is tagged with the encoding specified. * If the argument is a colon separated two encoding names "A:B", @@ -6965,6 +6987,8 @@ VALUE opt; rb_io_t *fptr, *fptr2; int fmode = 0; + VALUE ret; + VALUE rw[2]; opt = pop_last_hash(&argc, argv); rb_scan_args(argc, argv, "02", &v1, &v2); @@ -6997,7 +7021,13 @@ fptr->mode |= fmode; fptr2->mode |= fmode; - return rb_assoc_new(r, w); + ret = rb_assoc_new(r, w); + rw[0] = r; + rw[1] = w; + if (rb_block_given_p()) { + return rb_ensure(rb_yield, ret, pipe_close, (VALUE)rw); + } + return ret; } struct foreach_arg { Index: NEWS =================================================================== --- NEWS (revision 20915) +++ NEWS (revision 20916) @@ -13,6 +13,9 @@ * builtin classes + * IO + * IO.pipe takes a block. + * Enumerator#rewind Now calls the "rewind" method of the enclosed object if defined. Index: test/ruby/test_io.rb =================================================================== --- test/ruby/test_io.rb (revision 20915) +++ test/ruby/test_io.rb (revision 20916) @@ -22,6 +22,34 @@ IO.instance_methods.index(:"nonblock=") end + def test_pipe + r, w = IO.pipe + assert_instance_of(IO, r) + assert_instance_of(IO, w) + w.print "abc" + w.close + assert_equal("abc", r.read) + r.close + end + + def test_pipe_block + x = nil + ret = IO.pipe {|r, w| + x = [r,w] + assert_instance_of(IO, r) + assert_instance_of(IO, w) + w.print "abc" + w.close + assert_equal("abc", r.read) + assert(!r.closed?) + assert(w.closed?) + :foooo + } + assert_equal(:foooo, ret) + assert(x[0].closed?) + assert(x[1].closed?) + end + def test_gets_rs # default_rs r, w = IO.pipe -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/