From: merch-redmine@... Date: 2020-03-27T17:33:11+00:00 Subject: [ruby-core:97605] [Ruby master Bug#16737] File::BINARY doesn't work Issue #16737 has been updated by jeremyevans0 (Jeremy Evans). I agree with @nobu that this isn't a bug on !Windows. The documentation for `File::Constants::BINARY` states "disable line code conversion", nothing about setting binary mode. I guess the constant name is a bit misleading, but due to backwards compatibility, we cannot change it. The `File::BINARY` behavior on Windows is definitely a bug, as `#binmode?` is true but binary external encoding is not set. Calling `#binmode` on the file does set the binary external encoding: ```ruby f = File.open('a', File::WRONLY|File::TRUNC|File::CREAT|File::BINARY) # => # f.binmode? # => true f.external_encoding # => nil f.binmode # => # f.binmode? # => true f.external_encoding # => # ``` This is because the code to set the encoding is not called if keywords are not provided. If you provide keywords, it works correctly (in the example below you get a warning on Ruby 2.7 for positional hash to keyword conversion): ```ruby f = File.open('a', File::WRONLY|File::TRUNC|File::CREAT|File::BINARY, {}) # => # f.binmode? # => true f.external_encoding # => # ``` I have submitted a pull request to fix this: https://github.com/ruby/ruby/pull/2985 ---------------------------------------- Bug #16737: File::BINARY doesn't work https://bugs.ruby-lang.org/issues/16737#change-84793 * Author: sos4nt (Stefan Sch��ler) * Status: Open * Priority: Normal * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- `File.open` takes a `mode` argument which can be given as a string or as an integer using `File::Constants`. When using the latter, the constant `File::BINARY` doesn't have any effect: ```ruby # this works: File.open('foo', 'wb') do |f| p f.binmode? p f.external_encoding end #=> true #=> # # this doesn't: File.open('foo', File::WRONLY|File::TRUNC|File::CREAT|File::BINARY) do |f| p f.binmode? p f.external_encoding end #=> false #=> nil ``` Further inspecting `File::BINARY` reveals that it has a value of zero: ```ruby File::BINARY #=> 0 ``` So it's no surprise that OR-ing it doesn't do anything. I've tried various Ruby versions from 1.9.3 to 2.7.0 and all showed the above behavior. (I'm on macOS if that matters) I'm aware that I can achieve the desired result by using a string mode or by passing `binary: true`. But since Ruby accepts `mode` to be given as an integer, there should be a (working) "b" equivalent. -- https://bugs.ruby-lang.org/ Unsubscribe: