Checking whether a string is a number in disguise?

I'm working on an RPN calculator (don't ask why...) and I'm having
trouble getting a number from gets - how am I supposed to know whether
it's a number?

At the moment I'm doing [eval(oper) == oper.to_f], which is far from
ideal. Any ideas? You all get to win my calculator if you know of a
better way :D.

···

--
Posted via http://www.ruby-forum.com/.

Alle giovedì 22 novembre 2007, Peter Bunyan ha scritto:

I'm working on an RPN calculator (don't ask why...) and I'm having
trouble getting a number from gets - how am I supposed to know whether
it's a number?

At the moment I'm doing [eval(oper) == oper.to_f], which is far from
ideal. Any ideas? You all get to win my calculator if you know of a
better way :D.

Do you mean you need to find out whether a string contains a number or not? In
this case, you can either use Kernel#Float, which returns str.to_f if the
string contains a number and raises an exception owtherwise, or try to craft
a regexp which only matches strings containing numbers. For example, the
(untested) regexp

/[+-]?\d+(.\d+)?(e[+-]?\d+)?/

should match numbers with an optional + or - in front, followed by at least
one digit, with an optional decimal part (if there's a dot, there should be
at least one digit following it; if you want to allow something like 11. then
replace (.\d+) with (.\d*) ). The number can also be in exponential form,
with a downcase e and an optional + or - in front of the exponent.

I hope this helps

Stefano

str = gets # chomp is not needed for Float
num = Float(str) rescue nil

if num
  puts "I'm a number: #{num}"
end

Cheers

robert

···

2007/11/22, Peter Bunyan <peter.bunyan@gmail.com>:

I'm working on an RPN calculator (don't ask why...) and I'm having
trouble getting a number from gets - how am I supposed to know whether
it's a number?

At the moment I'm doing [eval(oper) == oper.to_f], which is far from
ideal. Any ideas? You all get to win my calculator if you know of a
better way :D.

--
use.inject do |as, often| as.you_can - without end

Is that the only way to do it? There's no built-in method for telling if
a string is a number? :frowning:

···

--
Posted via http://www.ruby-forum.com/.

OK, this seems to work:

class String
  def is_number?
    Float(self) == self.to_f
    rescue false
  end
end

···

--
Posted via http://www.ruby-forum.com/.

Stefano Crocco wrote:

Alle giovedì 22 novembre 2007...
In this case, you can either use Kernel#Float, which returns str.to_f
.. or try to craft a regexp which only matches strings containing
numbers.
For example, the (untested) regexp

/[+-]?\d+(.\d+)?(e[+-]?\d+)?/

Two small additions:
a) the 'dot' should be literally a dot (else it matches any character)
b) the boundaries to the whole expresssion are needed (else "ab23.35de"
would be
validated).

So, the regexp should be something like:

/^ [+-]? \d+ (?: [.]\d+)? (?: e[+-]? \d+)? $ /x

(If capture of components is desired, parenthesis should enclose all
components, and the ?: removed).

Raul

···

--
Posted via http://www.ruby-forum.com/\.

Alle giovedì 22 novembre 2007, Peter Bunyan ha scritto:

Is that the only way to do it? There's no built-in method for telling if
a string is a number? :frowning:

As far as I know, no.

Stefano

Strings are never numbers in ruby. Ever. That is the beauty of working in a clean typesafe language.

What you're doing, possibly without realizing it, is writing a parser for RPN but it sounds like you've not addressed this project like a parser. I suggest you go look at the screencast for treetop (a parser generator). In this screencast they build up an infix parser, which is much more than you need for RPN, but the tool is clean, powerful, and worth learning.

http://www.pivotalblabs.com/files/treetop-arithmetic-example.mov

···

On Nov 22, 2007, at 10:05 , Peter Bunyan wrote:

Is that the only way to do it? There's no built-in method for telling if
a string is a number? :frowning:

That's an error prone approach because it relies on comparing floats (which is also superfluous here because the real work is done by Float and rescue). Why don't you just do

def float?
   Float(self) rescue nil
end

Cheers

  robert

···

On 22.11.2007 20:11, Peter Bunyan wrote:

OK, this seems to work:

class String
  def is_number?
    Float(self) == self.to_f
    rescue false
  end
end

I do not think you can unless you can assume that it is base 10 or less.

···

--
Posted via http://www.ruby-forum.com/.