Hello all,
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.
- 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[i].ord & str[i].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 << (self[i].ord | str[i].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 << (self[i].ord ^ str[i].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,
Martin