# Working with kernel.eval

#1

I’m trying to calculate the results of formulas that are stored in
text files.

For example, a file may contain the line: 1+2/3

I want to take that line & get the result of the formula, 1.66 (roughly)

The way to do this seems to be Kernel.eval. But I can’t get it to
work correctly. Here’s my irb session:

irb(main):001:0> a = “1+2/3”
=> “1+2/3”
irb(main):002:0> b = eval(a)
=> 1
irb(main):004:0> b.class
=> Fixnum

I would think that eval(a) should return a Float, not a Fixnum.

I thought maybe that eval wasn’t following the standard order of
operations, which could explain the return value of 1. So then I
tried this:

irb(main):005:0> a = “2/3”
=> “2/3”
irb(main):006:0> b = eval(a)
=> 0
irb(main):007:0> b.class
=> Fixnum

So, it’s not an order of operations thing.

Maybe I shouldn’t be using eval. But I can’t find another option. Any
thoughts?

Thanks,

Ian

#2

\$ irb
irb(main):001:0> 2/3
=> 0
irb(main):002:0> 2.0/3
=> 0.666666666666667
irb(main):003:0>

Kent.

#3

require “mathn” for a batch of tweaks that will make Ruby maths
expression
more maths-like than C-like.

David V.

DÅ?a Pondelok 13 FebruÃ¡r 2006 21:07 Ian W. napÃ­sal:

#4

Ian W. wrote:

irb(main):001:0> a = “1+2/3”
=> “1+2/3”
irb(main):002:0> b = eval(a)
=> 1
irb(main):004:0> b.class
=> Fixnum

I would think that eval(a) should return a Float, not a Fixnum.

It’s nothing to do with eval, but rather that if you start with fixnums,
you do fixnum arithmetic. Try replacing 2 with 2.0. That invokes float
division, and every result depending on that input will be float. In
general, you can use x.to_f if you want to force a value to be treated
as float.

#5

On Feb 13, 2006, at 2:24 PM, Ian W. wrote:

Any thoughts on how I can take the string as it stands, “1+2/3” and

Well, depending on how many operators you need to support, it’s
fairly easy to parse them into an Abstract Syntax Tree and run the
calculation.

James Edward G. II

#6

This works and I appreciate the response. But it doesn’t solve the
problem that the formulas in the text files already exist & they
weren’t written with Ruby’s arithmetic in mind. My life would be
easier if I didn’t have to go update all of those text files.

Any thoughts on how I can take the string as it stands, “1+2/3” and
get the right answer? I could use regex to replace every integer with
a floating point number, I guess. But that seems kludgey.

#7

Ian W. wrote:

Any thoughts on how I can take the string as it stands, “1+2/3” and get
the right answer? I could use regex to replace every integer with a
floating point number, I guess. But that seems kludgey.

David’s suggestion to require ‘mathn’ is a good way to go, but be aware
that 2/3 will evaluate to a rational–precise, but in general slower to
compute with.

#8

That does appear to be the best solution. I plugged that in & my unit
tests look good.

Thanks,

Ian