Project

General

Profile

Bug #8445

Updated by ko1 (Koichi Sasada) 4 months 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. 

Back