three tests (to make up for missing Monday)

3 views
Skip to first unread message

pat eyler

unread,
Dec 7, 2005, 5:20:28 PM12/7/05
to Ruby-Test-Fi...@googlegroups.com
def test_precedence
sheet = Sheet.new
sheet.put("A1", "=7+2*3")
assert_equal("13", sheet.get("A1"))
end

def test_full_expression
sheet = Sheet.new
sheet.put("A1", "=7*(2+3)*((((2+1))))")
assert_equal("105", sheet.get("A1"))
end

def test_simple_formula_error
sheet = Sheet.new
sheet.put("A1", "=7*")
assert_equal("#Error", sheet.get("A1"))
end


--
thanks,
-pate
-------------------------

Jacob Fugal

unread,
Dec 7, 2005, 5:38:00 PM12/7/05
to Ruby-Test-Fi...@googlegroups.com
My current solution:

# ----- 8< -------
class Sheet
NUMERIC = /^\s+(\d+)\s+$/
FORMULA = /^=(.+)$/

def initialize
@storage = {}
end

def get( cell )
normalize( get_literal( cell ))
end

def get_literal( cell )
@storage[cell] ||= ''
end

def put( cell, data )
@storage[cell] = data
end

private
def normalize( data )
case data
when NUMERIC then $1
when FORMULA then formula_eval( $1 )
else data
end
end

def formula_eval( formula )
eval( formula ).to_s
rescue SyntaxError
'#Error'
end
end
# ----- 8< -------

The only change I had to make for this set is the rescue block on the
formula_eval method. eval took care of the other two new tests fine.

Jacob Fugal

Bill Guindon

unread,
Dec 7, 2005, 5:48:19 PM12/7/05
to Ruby-Test-Fi...@googlegroups.com
I also added a begin/rescue to the eval, but I left it in my case
statement. Seeing Jacob's post makes me want to move it out of there,
but I'm too lazy ;) Maybe next test.

class Sheet
NUMERIC = /^\s*(\d+)\s*$/
FORMULA = /^=(.*)$/

def initialize
@cells = Hash.new("")
end

def put(cell, val="")
@cells[cell] = val
end

def get(cell)
case @cells[cell]


when NUMERIC then $1
when FORMULA

begin
(eval $1).to_s
rescue SyntaxError
'#Error'
end
else @cells[cell]
end
end

def get_literal(cell)
@cells[cell]
end

end

--
Bill Guindon (aka aGorilla)

James Edward Gray II

unread,
Dec 9, 2005, 8:19:01 PM12/9/05
to Ruby Test First Challenge
I like what bill said, about eval() being dangerous. I agree. I'm
sticking to letting the tests guide me though and so far, eval() is
getting the job done. When the =system "rm -rf /" test shows up, I'll
think of something better. ;)

I guess it also depends on who this library is for. If it's intended
as a backend for end-user applications, eval() has to go. If it's
intended as a development library, having it may be a big win. It's
all point of view I guess.

Here's my code:

#!/usr/local/bin/ruby -w

# SimpleSpread.rb
#
# Created by James Edward Gray II on 2005-11-05.
# Copyright 2005 Gray Productions. All rights reserved.

require "forwardable"

class Sheet
extend Forwardable

def initialize
@cells = Hash.new { |cells, cell| cells[cell] = "" }
end

def get( cell )
case @cells[cell]
when /^\s*(\d+)\s*$/
$1
when /^=(.*)$/
eval($1).to_s
else
@cells[cell]
end
rescue Exception
"#Error"
end

def_delegator :@cells, :[], :get_literal
def_delegator :@cells, :[]=, :put
end

__END__

James Edward Gray II

Jacob Fugal

unread,
Dec 12, 2005, 11:28:02 AM12/12/05
to Ruby-Test-Fi...@googlegroups.com
On 12/9/05, James Edward Gray II <ja...@grayproductions.net> wrote:
>
> I like what bill said, about eval() being dangerous. I agree. I'm
> sticking to letting the tests guide me though and so far, eval() is
> getting the job done. When the =system "rm -rf /" test shows up, I'll
> think of something better. ;)

My sentiments exactly.

Jacob Fugal

[1] Apologies for the content-free post, but I have no elaboration to add... :)

Reply all
Reply to author
Forward
0 new messages