Marnen Laibow-Koser wrote:
A string is composed of characters. Binary data is composed of bytes.
They’re two different things and should be supported as such in the
language.
I was about to disagree. But then I remembered I have some ruby 1.8
code like this:
while line = gets
line.length.times do |i|
line[i] ^= 0x80 if (line[i] & 0x7f).between?(0x21, 0x7e)
end
print line
end
…which while it’s still technically operating on “text”, it’s
7-bit ASCII text where I need to toggle the 8th bit.
With 1.9, I guess this becomes something like:
while line = gets
line.force_encoding Encoding::BINARY
line.length.times do |i|
val = line.getbyte(i)
if (val & 0x7f).between?(0x21, 0x7e)
line.setbyte(i, val ^ 0x80)
end
end
print line
end
…except, I don’t trust the ‘gets’ and the ‘print’ here. If I
were doing I/O to a file I’d opened directly, I’d use “rb” and
“wb” modes to get ASCII-8BIT encoding. But this is stdin/stdout.
So I can’t expect the encoding to be binary-compatible.
Maybe before the loop, instead, setting:
Encoding.default_external = Encoding::BINARY
Encoding.default_internal = Encoding::BINARY
while line = gets
line.length.times do |i|
val = line.getbyte(i)
if (val & 0x7f).between?(0x21, 0x7e)
line.setbyte(i, val ^ 0x80)
end
end
print line
end
…the above indeed appears to work. (I presumably instead could
have specified -EBINARY:BINARY on the command line, but I didn’t
want to have to remember that when running this tool.)
So…
I guess this is a weird hybrid case, since I’m doing binary
processing on text. 
So even if Ruby had a data type for binary data that was separate
from String, I’m not sure that would help in my hybrid case where
I still want to use ‘gets’.
:shrug:
Regards,
Bill