From: Eric Wong Date: 2012-10-27T11:04:36+09:00 Subject: [ruby-core:48428] Re: [ruby-trunk - Bug #7220] StringIO#initialize_copy causes aliasing between the objects "brixen (Brian Ford)" wrote: > There is no other Ruby core class that causes aliasing when calling > #dup. String#dup, for example, is called in code precisely to create a > new String so the original would not be mutated. No other Ruby core class is a delegate for OS-level objects, either. > That IO and StringIO do cause this aliasing is a deviation from the > typical behavior of #dup, makes no sense, and is not at all required. > It's perfectly possible to do the following: It makes sense when I look at it this way: class Foo # this could be a numeric FD or IO object attr_reader :array def initialize @array = [] # the underlying file handle in the kernel end end a = Foo.new b = a.dup p(a.array.object_id == b.array.object_id) # => true > sasha:rubinius brian$ cat foobar.txt > 123456 > sasha:rubinius brian$ irb > 1.9.3p286 :001 > a = File.open("foobar.txt", "r") > => # > 1.9.3p286 :002 > b = File.open("foobar.txt", "r") > => # It's impossible to implement File#dup using open() reliably. foobar.txt can be unlinked or replaced by an entirely different file in between the File.open calls. > 1.9.3p286 :003 > a.getc > => "1" > 1.9.3p286 :004 > a.pos > => 1 > 1.9.3p286 :005 > b.pos > => 0 > 1.9.3p286 :006 > b.getc > => "1" However, if you want separate offsets, you can still use dup() but always implement read/write using pread()/pwrite() (and manually maintain per-object offsets in userspace).