From: nobu@... Date: 2018-02-14T01:37:44+00:00 Subject: [ruby-core:85537] [Ruby trunk Bug#14472][Rejected] `File::open` closes the file too early when used with callcc Issue #14472 has been updated by nobu (Nobuyoshi Nakada). Status changed from Open to Rejected blackenedgold (Sunrin SHIMURA) wrote: > This code throws an IOError, but expected to exit normally: `callcc` rollbacks `ensure`s. > The bugging code is useful to rewrite nested `open` blocks to flat style like this: > > ~~~ ruby > 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") > ~~~ You can do it by `File.open` without a block. If `callcc` weren't fire `ensure`s, it's unpredictable when `f1` and `f2` will get closed. It's same as w/o-block form `open`. ---------------------------------------- Bug #14472: `File::open` closes the file too early when used with callcc https://bugs.ruby-lang.org/issues/14472#change-70326 * Author: blackenedgold (Sunrin SHIMURA) * Status: Rejected * Priority: Normal * Assignee: * Target version: * ruby -v: ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu] * Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN ---------------------------------------- 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: ~~~ ruby 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 `
' ~~~ I think this is a bug because the code above must be the same as code below, which works fine: ~~~ ruby File::open("test1", 'w') {|f1| f1.write("hello")} ~~~ In fact, an equivalent scheme code works fine: ~~~scheme (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: ~~~ ruby File::open("test1", 'w') do |f1| File::open("test2", 'w') do |f2| f1.write("hello") f2.write("hello") end end ~~~ ~~~ ruby 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: ~~~ ruby ["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)))) ~~~ -- https://bugs.ruby-lang.org/ Unsubscribe: