Bug #18407
closed
Behavior difference between integer and string flags to File creation
Added by deivid (David Rodríguez) almost 3 years ago.
Updated over 2 years ago.
Description
Hi!
I was under the impression that these two commands should either both work of both fail, however they behave differently.
$ ruby -ropen-uri -EUTF-8:UTF-8 -e 'f = File.new("foo", "wb"); f.write URI.open("https://rubygems.org/gems/rake-13.0.6.gem").read'
$ ruby -ropen-uri -EUTF-8:UTF-8 -e 'f = File.new("foo", File::WRONLY | File::TRUNC | File::BINARY); f.write URI.open("https://rubygems.org/gems/rake-13.0.6.gem").read'
-e:1:in `write': "\\x8B" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError)
from -e:1:in `<main>'
Could be an actual bug, and me misunderstanding the documentation. In any case it seemed worth reporting.
Reduced test, without open-uri and without changing the default external encoding:
Encoding.default_internal = Encoding::UTF_8
f = File.new("/tmp/test.bin", File::CREAT | File::WRONLY | File::TRUNC | File::BINARY)
f.write "\xC8".force_encoding(Encoding::BINARY)
Digging just a little bit:
#ifdef O_BINARY
if (oflags & O_BINARY) {
fmode |= FMODE_BINMODE;
}
#endif
and:
>> File::BINARY
=> 0
In short File::BINARY
is noop on unixes, it's a windows only option, so Ruby defines it as 0
on these OS and basically does nothing.
The problem now is that to make it behave like b
, it would need to have another value than 0
, which could be a breaking change :/
- Description updated (diff)
- Status changed from Open to Closed
IO::BINARY
is for O_BINARY
which comes from underlying runtimes, and unrelated to ruby encodings.
The second form is for specifying such flags in a fine-grained manner, so it needs an encoding explicitly unlike the shorthand "wb"
.
@deivid (David Rodríguez) This should work
$ ruby -ropen-uri -EUTF-8:UTF-8 -e 'f = File.new("foo", File::WRONLY | File::TRUNC | File::BINARY, encoding: "BINARY"); f.write URI.open("https://rubygems.org/gems/rake-13.0.6.gem").read'
Thanks! The documentation seems much better now (master) than on 3.1, but I will try a PR to clarify a bit more!
BTW, why do you use File::
instead of IO::
?
Because the documents in io.c use the former?
I guess, yeah, and because I was dealing with opening a file, so File::
constants seemed appropriate to set the open mode, right?
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0