M

#### Martin Hansen

Unfortunately Ruby don't have bitwise operators for Class String like

Perl do. I am hoping very much that such operators will be implemented

in Ruby one day at a low level so they will fast! But until such a day,

I will roll my own crude operators by monkey patching Class String.

However, I am experiencing a peculiar error from my Unit Tests:

Loaded suite ./test_bits

Started

....F.

Finished in 0.000661 seconds.

1) Failure:

test_Bits_XOR_with_equal_length_returns_correctly(TestBits)

[./test_bits.rb:27]:

<"00110001"> expected but was

<"\x00\x00\x01\x01\x00\x00\x00\x01">.

6 tests, 9 assertions, 1 failures, 0 errors, 0 skips

Test run options: --seed 36958

Code:

# Monkey patching Class String to add bitwise operators.

# Behaviour matching Perl's:

# http://perldoc.perl.org/perlop.html#Bitwise-String-Operators

class String

# Method that performs bitwise AND operation where bits

# are copied if they exists in BOTH operands. If the operand

# sizes are different, the & operator methods acts as though

# the longer operand were truncated to the length of the shorter.

def &(str)

new = ""

(0 ... [self.length, str.length].min).each do |i|

new << (self

*.ord & str*

*.ord)*

end

new

end

# Method that performs bitwise OR operation where bits

# are copied if they exists in EITHER operands. If the operand

# sizes differ, the shorter operand is extended with the terminal

# part of the longer operand.

def |(str)

new = ""

min = [self.length, str.length].min

(0 ... min).each do |i|

new << (selfend

new

end

# Method that performs bitwise OR operation where bits

# are copied if they exists in EITHER operands. If the operand

# sizes differ, the shorter operand is extended with the terminal

# part of the longer operand.

def |(str)

new = ""

min = [self.length, str.length].min

(0 ... min).each do |i|

new << (self

*.ord | str**.ord)*

end

if self.length > str.length

new << self[min ... self.length]

elsif self.length < str.length

new << str[min ... str.length]

end

new

end

# Method that performs bitwise XOR operation where bits

# are copied if they exists in ONE BUT NOT BOTH operands.

def ^(str)

new = ""

(0 ... [self.length, str.length].min).each do |i|

new << (selfend

if self.length > str.length

new << self[min ... self.length]

elsif self.length < str.length

new << str[min ... str.length]

end

new

end

# Method that performs bitwise XOR operation where bits

# are copied if they exists in ONE BUT NOT BOTH operands.

def ^(str)

new = ""

(0 ... [self.length, str.length].min).each do |i|

new << (self

*.ord ^ str**.ord)*

end

new

end

end

Tests:

#!/usr/bin/env ruby

require 'bits'

require 'test/unit'

require 'pp'

class TestBits < Test::Unit::TestCase

def test_Bits_AND_with_equal_length_returns_correctly

assert_equal("00001100", "00111100" & "00001101")

end

def test_Bits_AND_with_unequal_length_returns_correctly

assert_equal("JAPH\n", "japh\nJunk" & '_____')

assert_equal("JAPH\n", '_____' & "japh\nJunk")

end

def test_Bits_OR_with_equal_length_returns_correctly

assert_equal("00111101", "00111100" | "00001101")

end

def test_Bits_OR_with_unequal_length_returns_correctly

assert_equal("japh\n", "JA" | " ph\n")

assert_equal("japh\n", " ph\n" | "JA")

end

def test_Bits_XOR_with_equal_length_returns_correctly

assert_equal("00110001", "00111100" ^ "00001101")

end

def test_Bits_XOR_with_unequal_length_returns_correctly

assert_equal("JAPH", "j p \n" ^ " a h")

assert_equal("JAPH", " a h" ^ "j p \n")

end

end

So, what is this error I see?

Cheers,

Martinend

new

end

end

Tests:

#!/usr/bin/env ruby

require 'bits'

require 'test/unit'

require 'pp'

class TestBits < Test::Unit::TestCase

def test_Bits_AND_with_equal_length_returns_correctly

assert_equal("00001100", "00111100" & "00001101")

end

def test_Bits_AND_with_unequal_length_returns_correctly

assert_equal("JAPH\n", "japh\nJunk" & '_____')

assert_equal("JAPH\n", '_____' & "japh\nJunk")

end

def test_Bits_OR_with_equal_length_returns_correctly

assert_equal("00111101", "00111100" | "00001101")

end

def test_Bits_OR_with_unequal_length_returns_correctly

assert_equal("japh\n", "JA" | " ph\n")

assert_equal("japh\n", " ph\n" | "JA")

end

def test_Bits_XOR_with_equal_length_returns_correctly

assert_equal("00110001", "00111100" ^ "00001101")

end

def test_Bits_XOR_with_unequal_length_returns_correctly

assert_equal("JAPH", "j p \n" ^ " a h")

assert_equal("JAPH", " a h" ^ "j p \n")

end

end

So, what is this error I see?

Cheers,

Martin