M
Martin Hansen
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.
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 << (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 << (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,
Martin
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 << (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 << (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,
Martin