Actions
Bug #14472
closed`File::open` closes the file too early when used with callcc
Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]
Description
First of all, I know callcc
is deprecated feature and I'm not in trouble with this bug.
I was just curious and happened to find this bug.
Bug Description¶
This code throws an IOError, but expected to exit normally:
require 'continuation'
f1 = callcc {|k| File::open("test1", 'w') {|f| k.(f)}}
f1.write("hello")
$ ruby openfile_cont.rb
/usr/lib/x86_64-linux-gnu/ruby/2.3.0/continuation.so: warning: callcc is obsolete; use Fiber instead
openfile_cont.rb:14:in `write': closed stream (IOError)
from openfile_cont.rb:14:in `<main>'
I think this is a bug because the code above must be the same as code below, which works fine:
File::open("test1", 'w') {|f1| f1.write("hello")}
In fact, an equivalent scheme code works fine:
(let* ((f1 (call/cc (lambda (k) (call-with-output-file "test1" k)))))
(display "hello" f1))
$ gosh openfile_cont.scm
$ cat test1
hello
Importance¶
Again, I'm not in trouble with this bug.
The bugging code is useful to rewrite nested open
blocks to flat style like this:
File::open("test1", 'w') do |f1|
File::open("test2", 'w') do |f2|
f1.write("hello")
f2.write("hello")
end
end
f1 = callcc {|k| File::open("test1", 'w') {|f| k.(f)}}
f2 = callcc {|k| File::open("test2", 'w') {|f| k.(f)}}
f1.write("hello")
f2.write("hello")
Or, even code that cannot be written with nested open
s can be written with callcc:
["test1", "test2", "test3"].map{|path| callcc {|k| File::open(path, 'w') {|f| k.(f)}}}.each do |f|
f.write("hello")
end
Again, equivalent scheme code works fine:
(let ((paths '("test1" "test2" "test3")))
(let ((ports (map (lambda (path) (call/cc (lambda (k) (call-with-output-file path k)))) paths)))
(dolist (port ports)
(display "hello" port))))
Actions
Like0
Like0Like0Like0Like0