Hi all,

I noticed subclassing IO didn't work as expected for pipe/popen and
pushed the following patch out to the "io-subclass-fix" branch of
  git://git.bogomips.org/rubinius.git

I'm not sure about the spec location/style, but the fix itself is
trivially correct to me.  Let me know if you have any
questions/comments.

>From 69e7a1cc0a7b2187f13245930980171b46afcc6f Mon Sep 17 00:00:00 2001
From: Eric Wong <[email protected]>
Date: Sat, 25 Sep 2010 04:31:47 +0000
Subject: [PATCH] subclassing IO works properly for pipe/popen

Subclasses of IO should return objects of the
subclass, not the core IO object.
---
 kernel/common/io.rb                          |    8 ++--
 spec/ruby/core/io/subclass_singleton_spec.rb |   41 ++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 4 deletions(-)
 create mode 100644 spec/ruby/core/io/subclass_singleton_spec.rb

diff --git a/kernel/common/io.rb b/kernel/common/io.rb
index 8907631..67c7bee 100644
--- a/kernel/common/io.rb
+++ b/kernel/common/io.rb
@@ -340,8 +340,8 @@ class IO
   #  Sending message to parent
   #  Parent got: <Hi Dad>
   def self.pipe
-    lhs = IO.allocate
-    rhs = IO.allocate
+    lhs = allocate
+    rhs = allocate
     connect_pipe(lhs, rhs)
     lhs.sync = true
     rhs.sync = true
@@ -401,8 +401,8 @@ class IO
       readable = true
     end
 
-    pa_read, ch_write = IO.pipe if readable
-    ch_read, pa_write = IO.pipe if writable
+    pa_read, ch_write = pipe if readable
+    ch_read, pa_write = pipe if writable
 
     pid = Process.fork
 
diff --git a/spec/ruby/core/io/subclass_singleton_spec.rb 
b/spec/ruby/core/io/subclass_singleton_spec.rb
new file mode 100644
index 0000000..d7ac05b
--- /dev/null
+++ b/spec/ruby/core/io/subclass_singleton_spec.rb
@@ -0,0 +1,41 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+class SubIO < IO
+end
+
+describe "subclassed IO singleton methods exposes subclassed objects" do
+
+  it "lets subclassed popen yield an object of subclass" do
+    SubIO.popen("true", "r") do |io|
+      io.should be_an_instance_of(SubIO)
+    end
+  end
+
+  it "lets subclassed popen return an object of subclass" do
+    io = SubIO.popen("true", "r")
+    io.should be_an_instance_of(SubIO)
+    io.close
+  end
+
+  it "returns a pipe belonging to subclasses" do
+    r, w = SubIO.pipe
+    r.should be_an_instance_of(SubIO)
+    w.should be_an_instance_of(SubIO)
+    w.close
+    r.close
+  end
+
+  it "creates objects belonging to subclasses from file descriptors" do
+    r, w = IO.pipe
+    r.should be_an_instance_of(IO)
+    w.should be_an_instance_of(IO)
+    sr = SubIO.for_fd(r.fileno)
+    sr.should be_an_instance_of(SubIO)
+    sr.close
+    begin
+      r.close
+    rescue Errno::EBADF
+    end
+    w.close
+  end
+end
-- 
Eric Wong

-- 
--- !ruby/object:MailingList
name: rubinius-dev
view: http://groups.google.com/group/rubinius-dev?hl=en
post: [email protected]
unsubscribe: [email protected]

Reply via email to