Bug #8445
Updated by ko1 (Koichi Sasada) over 2 years ago
RubyDoc says that `IO.open` IO.open and `IO#set_encoding` IO#set_encoding supports optional argument defined in `String#encode`. String#encode. http://ruby-doc.org/core-2.0/IO.html#method-c-new-label-Options In fact, `:invalid, :invalid, :undef and :replace` :replace works as expected. However, `:fallback` :fallback option does not work neither for `IO.open` IO.open and `IO#set_encoding`. IO#set_encoding. Following is the example code which does not work. `f(x)` 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()` fill_cbuf() in `io.c` io.c calls `rb_econv_convert()` rb_econv_convert() from `transcode.c` transcode.c directly. On the other hand, `fallback_func` fallback_func is called in `transcode_loop()`, transcode_loop(), which is called by `str_encode()`. str_encode(). Since `transcode_loop()` transcode_loop() also calls `rb_econv_convert()`, rb_econv_convert(), I wrote a small patch which moves some codes from `transcode_loop()` transcode_loop() to `rb_econv_convert()` rb_econv_convert() to fix the problem. The attached file is the patch. Hope this helps.