Forum: Ruby byte strings

A665665c83ac8d18e9f36083db34e971?d=identicon&s=25 Charles Hixson (charlesh)
on 2013-09-08 04:32
(Received via mailing list)
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
2ffac40f8a985a2b2749244b8a1c4161?d=identicon&s=25 Mike Stok (Guest)
on 2013-09-08 05:32
(Received via mailing list)
On 2013-09-08, at 3:28 AM, Charles Hixson <charleshixsn@earthlink.net>
wrote:

> test.rb:54:in `[]=': no implicit conversion of Fixnum into String (TypeError)
> In more detail, the code was:
>        if    int < 0    then
>        end    #while
>        return    v
>    end    #i2key

Have you considered using String#getbyte(index) and
String#setbyte(index, integer)?

http://ruby-doc.org/core-2.0.0/String.html#method-i-getbyte
http://ruby-doc.org/core-2.0.0/String.html#method-i-setbyte

ratdog:~ mike$ pry
[1] pry(main)> str = ['00' * 10].pack('H*')
=> "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
[2] pry(main)> str.setbyte(5, 8)
=> 8
[3] pry(main)> str.getbyte(5)
=> 8
[4] pry(main)> str
=> "\x00\x00\x00\x00\x00\b\x00\x00\x00\x00"
[5] pry(main)> RUBY_VERSION
=> "2.0.0"

Hope this helps,

Mike

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.
2f4d4f9c35ea851bffb9a9cc2e086365?d=identicon&s=25 Harry Kakueki (Guest)
on 2013-09-08 05:47
(Received via mailing list)
>
>

I just glanced at this, but it looks like you are trying to do this....

p RUBY_VERSION

v = "abcdef"
v[2] = 5   # try 5.to_s ?
p v



Harry
A665665c83ac8d18e9f36083db34e971?d=identicon&s=25 Charles Hixson (charlesh)
on 2013-09-08 06:13
(Received via mailing list)
On 09/07/2013 08:46 PM, Harry Kakueki wrote:
>
>
>
> Harry
>
>
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.
A665665c83ac8d18e9f36083db34e971?d=identicon&s=25 Charles Hixson (charlesh)
on 2013-09-08 06:22
(Received via mailing list)
On 09/07/2013 08:31 PM, Mike Stok wrote:
>> Where I am told:
>> even though 0x08 is a valid ASCII code (backspace).
>>             raise    TypeError, "int not an Integer, == #{int.inspect}"
>>             p("q = #{q}, r = #{r}")
> [1] pry(main)> str = ['00' * 10].pack('H*')
> Hope this helps,
>
> Mike
>
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"
2f4d4f9c35ea851bffb9a9cc2e086365?d=identicon&s=25 Harry Kakueki (Guest)
on 2013-09-08 06:39
(Received via mailing list)
v[i]    =    r        unless r == 0

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.

Harry
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.