filesystem/converted_writes_parens.rb

tests/_examples/filesystem/converted_writes_parens.rb in the metorex repository.

# A stream told an encoding writes text carried into it, one piece at a
# time, while `syswrite` writes the bytes as they stand. A stream told none
# writes bytes, and nothing written asks nothing of the stream.
path = "/tmp/metorex_converted_writes_#{Process.pid()}.txt"

File.open(path, "w", encoding: Encoding::UTF_32LE) { |file| p(file.write("h", "i")) }
p(File.binread(path).bytes())
File.open(path, "w", external_encoding: Encoding::UTF_16BE) { |file| file.syswrite("hi") }
p(File.binread(path).bytes())
File.open(path, "w") { |file| file.write("\x87".b(), "ą") }
p(File.binread(path).bytes())
File.open(path, "r") { |file| p(file.write("")) }

def refusal()
  yield()
rescue StandardError => problem
  [problem.class(), problem.message()]
end

File.open(path, "w", external_encoding: Encoding::UTF_16BE) do |file|
  p(refusal() { file.write("été".b()) })
end

# `IO.write` passes its options to the open, or `open_args:` in their place,
# and answers how many bytes it wrote.
p(IO.write(path, "hi", mode: "w", encoding: Encoding::UTF_32LE))
p(IO.write(path, "hi", open_args: ["w", nil, {encoding: Encoding::UTF_32LE}]))
p(IO.write(path, "hi", 2, mode: "r", open_args: ["w"]))
p(File.read(path))
p(refusal() { IO.write(path, "hi", open_args: [{encoding: Encoding::UTF_32LE}]) })
p(refusal() { IO.write(path, "hi", mode: "w:UTF-16BE", encoding: Encoding::UTF_32LE) })

File.delete(path)

Output:

8
[104, 0, 0, 0, 105, 0, 0, 0]
[104, 105]
[135, 196, 133]
0
[Encoding::UndefinedConversionError, "\"\\xC3\" from ASCII-8BIT to UTF-8"]
8
8
2
"\u0000\u0000hi"
[ArgumentError, "ASCII incompatible encoding needs binmode"]
[ArgumentError, "encoding specified twice"]