It appears that in Ruby2.0 it's impossible to treat strings as mutable byte arrays. Is there any replacement?
FWIW, the string is initialized with:
v = ["00" * len].pack("H*")
and trouble is caused at:
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r
Where I am told:
"q = 8, r = 0"
test.rb:54:in `[]=': no implicit conversion of Fixnum into String (TypeError)
a test modification to see if 0 was being handled specially:
v[i] = r unless r == 0
yielded:
"q = 8, r = 0"
"q = 0, r = 8"
test.rb:54:in `[]=': no implicit conversion of Fixnum into String (TypeError)
even though 0x08 is a valid ASCII code (backspace).
In more detail, the code was:
def i2key(int, len = 18)
if not len.is_a?(Fixnum) then
raise TypeError, "len not a Fixnum, == #{len.inspect}"
end #if
if len < 2 then
raise ArgumentError, "len too small, == #{len}"
end #if
if not int.is_a?(Integer) then
raise TypeError, "int not an Integer, == #{int.inspect}"
end #if
if int < 0 then
raise ArgumentError, "int too small, == #{int}"
end #if
v = ["00" * len].pack("H*")
i = len
q = int
while (q > 0 and i > 0)
i = i - 1
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r unless r == 0
end #while
return v
end #i2key
On 2013-09-08, at 3:28 AM, Charles Hixson <charleshixsn@earthlink.net> wrote:
It appears that in Ruby2.0 it's impossible to treat strings as mutable byte arrays. Is there any replacement?
FWIW, the string is initialized with:
v = ["00" * len].pack("H*")
and trouble is caused at:
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r
Where I am told:
"q = 8, r = 0"
test.rb:54:in `=': no implicit conversion of Fixnum into String (TypeError)
a test modification to see if 0 was being handled specially:
v[i] = r unless r == 0
yielded:
"q = 8, r = 0"
"q = 0, r = 8"
test.rb:54:in `=': no implicit conversion of Fixnum into String (TypeError)
even though 0x08 is a valid ASCII code (backspace).
In more detail, the code was:
def i2key(int, len = 18)
if not len.is_a?(Fixnum) then
raise TypeError, "len not a Fixnum, == #{len.inspect}"
end #if
if len < 2 then
raise ArgumentError, "len too small, == #{len}"
end #if
if not int.is_a?(Integer) then
raise TypeError, "int not an Integer, == #{int.inspect}"
end #if
if int < 0 then
raise ArgumentError, "int too small, == #{int}"
end #if
v = ["00" * len].pack("H*")
i = len
q = int
while (q > 0 and i > 0)
i = i - 1
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r unless r == 0
end #while
return v
end #i2key
Sorry, but I want to set the ASCII char whose value is 5. A 64 bit Fixnum can be held in 9 bytes if you can code it mod 128. Using standard string translation can take over twice as many. (I didn't calculate it exactly, but lots more. Since the key value is to determine the sort order, I can't use the standard pack("w") routine, either. That produces a string without leading zeros, which won't sort correctly.
···
On 09/07/2013 08:46 PM, Harry Kakueki wrote:
I just glanced at this, but it looks like you are trying to do this....
Thanks. Those were the routines I needed to know about. I can't really test it until I write the inverse function, but inspection of the results for: #v[i] = r unless r == 0
v.setbyte(i, r)
looks quite good. Checking individual numbers gives the expected values.
1
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
2
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
3
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"
4
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
8
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b"
16
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10"
···
On 09/07/2013 08:31 PM, Mike Stok wrote:
On 2013-09-08, at 3:28 AM, Charles Hixson <charleshixsn@earthlink.net> wrote:
It appears that in Ruby2.0 it's impossible to treat strings as mutable byte arrays. Is there any replacement?
FWIW, the string is initialized with:
v = ["00" * len].pack("H*")
and trouble is caused at:
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r
Where I am told:
"q = 8, r = 0"
test.rb:54:in `=': no implicit conversion of Fixnum into String (TypeError)
a test modification to see if 0 was being handled specially:
v[i] = r unless r == 0
yielded:
"q = 8, r = 0"
"q = 0, r = 8"
test.rb:54:in `=': no implicit conversion of Fixnum into String (TypeError)
even though 0x08 is a valid ASCII code (backspace).
In more detail, the code was:
def i2key(int, len = 18)
if not len.is_a?(Fixnum) then
raise TypeError, "len not a Fixnum, == #{len.inspect}"
end #if
if len < 2 then
raise ArgumentError, "len too small, == #{len}"
end #if
if not int.is_a?(Integer) then
raise TypeError, "int not an Integer, == #{int.inspect}"
end #if
if int < 0 then
raise ArgumentError, "int too small, == #{int}"
end #if
v = ["00" * len].pack("H*")
i = len
q = int
while (q > 0 and i > 0)
i = i - 1
q,r = q.divmod(128)
p("q = #{q}, r = #{r}")
v[i] = r unless r == 0
end #while
return v
end #i2key
Have you considered using String#getbyte(index) and String#setbyte(index, integer)?
This line looked odd to me when I glanced through.
In this line, if r is a Fixnum then you are trying to put a Fixnum into a
String v[i].
If r is a String then when will r == 0 ?
I did not read all of your code, I just looked at the error location first.