Issue #8445 has been updated by JesseJohnson (Jesse Johnson).
I can replicate this in 3.2.2.
----------------------------------------
Bug #8445: IO.open and IO#set_enconding does not support :fallback option
https://bugs.ruby-lang.org/issues/8445#change-105299
* Author: pjmtdw (Haruhiro Yoshimoto)
* Status: Assigned
* Priority: Normal
* Assignee: akr (Akira Tanaka)
* ruby -v: trunk(ruby 2.1.0dev)
----------------------------------------
RubyDoc says that `IO.open` and `IO#set_encoding` supports optional argument defined in
`String#encode`.
http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options
In fact, `:invalid, :undef and :replace` works as expected.
However, `:fallback` option does not work neither for `IO.open` and `IO#set_encoding`.
Following is the example code which does not work.
`f(x)` is never called even if hoge.txt contains non convertible character.
```ruby
File.open("./hoge.txt","r:Shift_JIS:utf-8", :fallback =>
lambda{|x|f(x)}){|f|
...
}
File.open("./hoge.txt"){|f|
f.set_encoding("Shift_JIS","utf-8",:fallback => lambda{|x|f(x)})
...
}
```
I Think this is because `fill_cbuf()` in `io.c` calls `rb_econv_convert()` from
`transcode.c` directly.
On the other hand, `fallback_func` is called in `transcode_loop()`, which is called by
`str_encode()`.
Since `transcode_loop()` also calls `rb_econv_convert()`, I wrote a small patch which
moves some codes from
`transcode_loop()` to `rb_econv_convert()` to fix the problem.
The attached file is the patch. Hope this helps.
---Files--------------------------------
support-fallback-for-io.patch (3.9 KB)
--
https://bugs.ruby-lang.org/