Project

General

Profile

Actions

Bug #12748

closed

irb の評価結果が2回表示されます

Added by dogatana (Toshihiko Ichida) over 7 years ago. Updated over 7 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.4.0preview2 (2016-09-09 trunk 56129) [i386-mswin32_140]
[ruby-dev:49786]

Description

irbを実行すると次のように評価結果が2回表示されます。
副作用のある呼び出しをしても副作用そのものは1回だけ実行されているので、表示上だけの問題でないかと思います。

作成: Visual Studio 2015 Community
実行: Windows 10 Pro 64bit

*****@*****-PC C:\usr\local\bin          
> irb                                    
irb(main):001:0> irb(main):001:0> 1      
=> 1                                     
=> 1                                     
irb(main):002:0> irb(main):002:0> 1 + 2  
=> 3                                     
=> 3                                     
irb(main):003:0> irb(main):003:0> "ruby" 
=> "ruby"                                
=> "ruby"                                
irb(main):004:0> irb(main):004:0> exit  

Updated by dogatana (Toshihiko Ichida) over 7 years ago

irb ではなく、ruby の出力そのものがおかしいようです。

*****@*****-PC C:\usr\local\bin 
> type test.rb                  
STDOUT.puts 'stdout.hello'      
STDERR.puts 'stderr.hello'      
                                
*****@*****-PC C:\usr\local\bin 
> ruby test.rb                  
stdout.hellostdout.hello        
                                
stderr.hellostderr.hello        
                                

ファイルにリダイレクトした場合はstdout.hello と1行だけ保存されます。

Updated by usa (Usaku NAKAMURA) over 7 years ago

  • Status changed from Open to Feedback

残念ながら、当方の手元(Win7, Win10 / vc10, vc12, vc14 / x86, x64)では再現することができませんでした。
そちらの環境では、例えば過去のバージョンのrubyでは問題はなかったのでしょうか?

Updated by dogatana (Toshihiko Ichida) over 7 years ago

現在の環境で
ruby 2.3.0p0 (2015-12-25 revision 53290) [i386-mingw32]
を常用していますが、この問題は始めてです。

なお、io.c の rb_io_puts() の string: ラベル以降を

  string:
    puts("# before");
    rb_io_write(out, line);
    puts("# end");

と書き換えたところ、

 > ruby -e 'puts 1' 
 # before           
 11# end            

となるので、rb_io_write()の中で2回出力されているようです。

Updated by usa (Usaku NAKAMURA) over 7 years ago

あ、ソースをいじってコンパイルが試せるのであれば話が早いかもです。

win32/win32.crb_w32_write_consoleの中にある、7123行目または7132行目の
WriteConsleWが実際の出力処理になります。
そのどっちが呼ばれてるか、またその時引数ptrおよびlen(またはcurlen)がどうなってるか、
というあたりを観察すると、何かわかるかもしれません。

Updated by dogatana (Toshihiko Ichida) over 7 years ago

io.c の io_fwrite() に問題があるようです。

この関数内で #ifdef _WIN32 内の、rb_w32_write_console() と、その下の io_binwrite() の両方が呼び出されるために、2回出力されています。
リダイレクトすると片方だけになります。

  > ruby -e 'p 1'            
  # io_fwrite: rb_w32        
  handle: 14c                
  dwMode: 7                  
  1# io_fwrite: io_binwrite  
  # io_fwrite: rb_w32        
  handle: 14c                
  dwMode: 7                  
                             
  # io_fwrite: io_binwrite   
  1                          
                             
  > ruby -e 'p 1' > dump.txt 
  # io_fwrite: io_binwrite   
  # io_fwrite: io_binwrite  

同様の記述が rb_write_error_str() にもあり、こちらも確認が必要かもしれません。
rb_w32_write_console() と コンソール出力かどうかの判定方法が異なるのが気になります。

win32.c の rb_w32_write_console() を眺めたところ、ENABLE_VIRTUAL_TERMINAL_PROCESSING を判定しているので、色出力を対応するための処理のようですね。
2.4 からの追加でしょうか。

Updated by usa (Usaku NAKAMURA) over 7 years ago

あー、なるほど、バグですね。
これは2.4から入ったコードなので2.3以前で起きないのも納得です。
直しておきます。

Updated by usa (Usaku NAKAMURA) over 7 years ago

  • Status changed from Feedback to Open
Actions #8

Updated by usa (Usaku NAKAMURA) over 7 years ago

  • Status changed from Open to Closed

Applied in changeset r56134.


Updated by nagachika (Tomoyuki Chikanaga) over 7 years ago

  • Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: DONTNEED, 2.2: DONTNEED, 2.3: DONTNEED
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0