Minor discrepancies running Thomas' "Roman" program: why?

Hi,

I’m running Ruby 1.8.2 over WinXP-Pro/SP2.

I’ve written a variant of Dave T.’ Decimal-to-Roman program from
PickAxe 2. I get a couple of minor differences in execution…

One difference is that my assert statements that test values need a
“to_s” to avoid failure. His do not, e.g.

	assert_equal('i', Roman.new(1).to_s)
	assert_equal('ii', Roman.new(2).to_s)
	assert_equal('iv', Roman.new(4).to_s)

My statement
assert_raise(RuntimeError, Roman.new(0))
shows up in the “errors” count and a traceback is produced. Dave’s
example shows no errors nor a traceback.

I test under SciTE and in a Command Window; they yield identical
results.

Dave’s book says he’s covering the same Ruby version I’m using. Could
it be he’s developing on Uni* while I’m on Windows? The code’s below
if your interested.

Thanks in Advance,
Richard

TestC.rb

equire ‘roman3’ # No debugging code … just one puts statement
require ‘test/unit’
class TestRoman < Test::Unit::TestCase
def test_simple
assert_equal(‘i’, Roman.new(1).to_s)
assert_equal(‘ii’, Roman.new(2).to_s)
assert_equal(‘iv’, Roman.new(4).to_s)
assert_equal(‘v’, Roman.new(5).to_s)
assert_equal(‘vi’, Roman.new(6).to_s)
assert_equal(‘ixx’, Roman.new(19).to_s)
assert_equal(‘ic’, Roman.new(99).to_s)
assert_equal(‘ci’, Roman.new(101).to_s)
assert_equal(‘vmmmmm’, Roman.new(4995).to_s)
assert_equal(‘immmmm’, Roman.new(4999).to_s)
assert_raise(RuntimeError, Roman.new(0))
end
end

Results

Loaded suite TestC
Started
1=>i
2=>ii
4=>iv
5=>v
6=>vi
19=>ixx
99=>ic
101=>ci
4995=>vmmmmm
4999=>immmmm
E
Finished in 0.0 seconds.

  1. Error:
    test_simple(TestRoman):
    RuntimeError: Roman numerals must be between 1 & 4999
    ./roman3.rb:9:in initialize' TestC.rb:15:innew’
    TestC.rb:15:in `test_simple’

1 tests, 10 assertions, 0 failures, 1 errors

Roman3.rb

class Roman
MAXROMAN = 4999
Symbols= [ [“m”, 1000], [“d”, 500], [“c”, 100], [“l”, 50],
[“x”, 10], [“v”, 5], [“i”, 1]
]

def initialize(value)
	if value <= 0 || value > MAXROMAN
		fail "Roman numerals must be between 1 & #{MAXROMAN}"
	end
	@value = value
end

def to_s
	value = @value
	roman = ""
	# Check for exact match
	for code, dec_equiv in Symbols
		if dec_equiv == value then roman << code; value = 0;  break;  end
	end

	for code, dec_equiv in Symbols
		break unless value > 0
		orig_val =value
		count, value = value.divmod(dec_equiv)

		if (count < 0 || count * dec_equiv == orig_val)
		else
				for new_code, new_dec_equiv in Symbols
					next unless new_dec_equiv < dec_equiv
					if orig_val + new_dec_equiv == dec_equiv * (count+1)
						roman << new_code
						count += 1
						value = orig_val + new_dec_equiv - (count * dec_equiv)
						break
					end
				end
		end
		roman << (code * count)
		break if value == 0
	end
	puts @value.to_s + '=>' + roman
	roman
end

end

<…>

My statement
assert_raise(RuntimeError, Roman.new(0))
shows up in the “errors” count and a traceback is produced. Dave’s
example shows no errors nor a traceback.
<…>
Dave’s book says he’s covering the same Ruby version I’m using. Could
it be he’s developing on Uni* while I’m on Windows?
<…>

It has nothing to do with Uni* or Windows.

Your code:
assert_raise(RuntimeError, Roman.new(0))
Dave’s code:
assert_raise(RuntimeError) { Roman.new(0) }

From the documentation of assert_raise:
assert_raise(*args) {|| …}
Passes if the block raises one of the given exceptions.

Your code has no block…


Regards,
Rimantas

http://rimantas.com/