Ara.T.Howard wrote: > On Thu, 20 May 2004, Simon Strandgaard wrote: > > > I want to clone a filedescriptor, but no matter > > what I try I becomes ugly. The nice solution doesn't > > seems to work. [snip] > doesn't this do it? > [snip] > f2 = f1.dup [snip] Hmmm bad proof of concept.. Therefore I will have to tell the full story: Im writing a file-iterator which both can go forward and backwards. #dup doesn't work here, only the long ugly expression I showed you in the first mail. By using #dup then my clone test fails. I have absolutely no idea why #dup is yielding nil here.... maybe bug? server> ruby test_file.rb Loaded suite XTestFile Started ..F. Finished in 0.042698 seconds. 1) Failure: test_clone1(XTestFile) [test_file.rb:106]: <101> expected but was <nil>. 4 tests, 5 assertions, 1 failures, 0 errors server> By using @file.clone.reopen(@file), then it works, but I am not confident that it really works (because its really ugly). server> ruby test_file.rb Loaded suite XTestFile Started .... Finished in 0.006764 seconds. 4 tests, 6 assertions, 0 failures, 0 errors server> The testcase looks like def test_clone1 @i.next(2) assert_equal("c"[0], @i.current) i2 = @i.clone begin i2.next(2) assert_equal("e"[0], i2.current) # check that clone were harmless assert_equal("c"[0], @i.current) ensure i2.close end end I have attached the source code for. In order to run it you will need to fetch my 'iterator' package. http://raa.ruby-lang.org/list.rhtml?name=iterator require 'test/unit' require 'iterator' module Iterator class File < Base def initialize(file) @file = file end attr_reader :file def clone #cfd = IO.new(@file.fileno, 'r') #cfd = @file.clone #cfd = @file.dup cfd = @file.clone.reopen(@file) # BOOM BOOM BOOM... this clone is ugly #puts "FD=#{@file.fileno} CLONE=#{cfd.fileno}" self.class.new(cfd) end def close @file.close end def first @file.rewind self end def last @file.seek(0, IO::SEEK_END) self end def has_next? not @file.eof? end def next1 @file.seek(1, IO::SEEK_CUR) end def current byte = @file.getc @file.seek(-1, IO::SEEK_CUR) byte end def has_prev? (@file.pos > 0) end def prev1 @file.seek(-1, IO::SEEK_CUR) end def current_prev @file.seek(-1, IO::SEEK_CUR) @file.getc end end end # module Iterator class XTestFile < Test::Unit::TestCase def setup @data = "abcdefg" #@i = @data.create_iterator # yields integers between 0..255 @filename = "____filedata" File.open(@filename, "w+") do |f| f.write(@data) end @file = File.open(@filename, "r") @i = Iterator::File.new(@file) end def teardown @i.close raise "@file not closed" unless @file.closed? end def test_forward1 result = [] while @i.has_next? result << @i.current @i.next end assert_equal("abcdefg", result.map{|byte| byte.chr}.join) end def test_backward1 @i.last result = [] while @i.has_prev? result << @i.current_prev @i.prev end result.reverse! assert_equal("abcdefg", result.map{|byte| byte.chr}.join) end def test_backward2 rev = @i.last.reverse result = [] while rev.has_next? result << rev.current rev.next end result.reverse! assert_equal("abcdefg", result.map{|byte| byte.chr}.join) ensure rev.close end def test_clone1 @i.next(2) assert_equal("c"[0], @i.current) i2 = @i.clone begin i2.next(2) assert_equal("e"[0], i2.current) # check that clone were harmless assert_equal("c"[0], @i.current) ensure i2.close end end end if $0 == __FILE__ require 'test/unit/ui/console/testrunner' Test::Unit::UI::Console::TestRunner.run(XTestFile) end BTW: I am using CVS-head version of Ruby. server> ruby -v ruby 1.9.0 (2004-05-17) [i386-freebsd5.1] server> -- Simon Strandgaard