Code Critique: check if int or float

O

ole __

Hello again folks,

I'm really starting to like this language. I'm working towards building
a simple expression evaluator. I couldn't seem to find any methods for
testing whether a string contains an integer or float. In PHP (where I'm
from) you've got your is_numeric(). Is there such a method in Ruby?

Anyway, under the assumption that there wasn't and to learn a bit I
decided to add the methods i? and f? to String. I was wondering if I
could get a bit of a critique on this code because I'm still ultra new
to Ruby.

I'm a TDD maniac, so I've got miself a test case in there too:
===============================
class String
# Strict test whether the string is a valid integer
# Underscores are not permitted.
# allowScientific is false by default because "4e3".to_i is 4
def i?(allowScientific = false)
if allowScientific
return (self =~ /^-?\d+(e-?\d+)?$/) != nil
end
(self =~ /^-?\d+$/) != nil
end
# Strict test whether the string is a valid float.
# i.e. 4 is not but 4.0 is. Scientific notation acceptable.
def f?(allowScientific = true)
if allowScientific
return (self =~ /^-?\d*\.\d+(e-?\d+)?$/) != nil
end
(self =~ /^-?\d*.\d+$/) != nil
end
end

require 'test/unit'

class StringExtensionsTest < Test::Unit::TestCase
def testI
assert '45'.i?
assert '-3'.i?
assert !'3s'.i?
assert !'3_000'.i?
assert !'3e3'.i?
end
def testIScientific
assert !'e4'.i?(true)
assert '4e2'.i?(true)
assert '-8e3'.i?(true)
assert '-5e-25'.i?(true)
end
def testFBasic
assert !'3'.f?(false)
assert '3.0'.f?(false)
assert '-25.36'.f?(false)
assert '.52'.f?(false)
assert '-.14'.f?(false)
end
def testFScientific
assert !'e1'.f?
assert !'4e1'.f?
assert '3.12e1'.f?
assert '-2.0e-3'.f?
assert '-.6e2'.f?
end
end
===============================
4 tests, 19 assertions, 0 failures, 0 errors
===============================

Final question, what are your feelings on camelCase and Ruby's apparent
shunning of it?
 
M

Marcel Molina Jr.

I'm really starting to like this language. I'm working towards building
a simple expression evaluator. I couldn't seem to find any methods for
testing whether a string contains an integer or float. In PHP (where I'm
from) you've got your is_numeric(). Is there such a method in Ruby?

Anyway, under the assumption that there wasn't and to learn a bit I
decided to add the methods i? and f? to String. I was wondering if I
could get a bit of a critique on this code because I'm still ultra new
to Ruby.
ArgumentError: invalid value for Integer: "3s"
from (irb):3:in `Integer'
from (irb):3ArgumentError: invalid value for Float(): "3s"
from (irb):5:in `Float'
from (irb):5ArgumentError: invalid value for Integer: "-8e3"
from (irb):9:in `Integer'
from (irb):9

You could likely come up with a much cleaner implementation using
Integer() and Float() + rescue ArgumentError.

And about camelCase, it's true, almost no one in Ruby uses
camelCase. I'd recommend just going with the flow and adoption
lowercase_and_underscored.

marcel
 
T

Tim Hunter

ole said:
Hello again folks,

I'm really starting to like this language. I'm working towards building
a simple expression evaluator. I couldn't seem to find any methods for
testing whether a string contains an integer or float. In PHP (where I'm
from) you've got your is_numeric(). Is there such a method in Ruby?

The Integer() method raises an exception if its argument isn't an integer:

Integer("1") is okay.
Integer("1.0") raises ArgumentError.

Similarly Float() raises an exception if its argument isn't a Float:

Float("1.0") is okay.
Float("1") is okay.
Float("x") raises ArgumentError.
 
O

ole __

Thanks Tim and Marcel.

Would you have thought String.i? and String.f? would make more sense
than Integer() and Float(). But yeah they will probably make for a
better implementation then the regexps.
And about camelCase, it's true, almost no one in Ruby uses
camelCase. I'd recommend just going with the flow and adoption
lowercase_and_underscored.

I won't be so easily converted. It's more characters, the character is a
stretch on the keyboard and they are harder to read. Underscores seem
backward to me.
 
S

Sammy Larbi

ole __ wrote, On 6/20/2007 5:51 PM:
Thanks Tim and Marcel.

Would you have thought String.i? and String.f? would make more sense
than Integer() and Float(). But yeah they will probably make for a
better implementation then the regexps.



I won't be so easily converted. It's more characters, the character is a
stretch on the keyboard and they are harder to read. Underscores seem
backward to me.

I found that you pick them up quickly and it isn't any harder than
reaching for shift after a while - it's just repetition that's needed to
memorize it. Besides that, generally I think its good to stick to the
conventions of a particular community. So, when I write Java, I use
Java conventions, and when I write Ruby, I use Ruby conventions.

It was weird at first, but I picked it up in no time.
 
D

dblack

Hi --

ole __ wrote, On 6/20/2007 5:51 PM:

I found that you pick them up quickly and it isn't any harder than reaching
for shift after a while - it's just repetition that's needed to memorize it.
Besides that, generally I think its good to stick to the conventions of a
particular community. So, when I write Java, I use Java conventions, and
when I write Ruby, I use Ruby conventions.

That's really the main point. It's not a matter of being converted to
using or not using camelCase -- it's a matter of being converted to
the practice of following the stylistic conventions and traditions,
whatever they may be. As a cellist I like using a bow, but when I
play the piano I use my fingers :)


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
R

Robert Dober

Thanks Tim and Marcel.

Would you have thought String.i? and String.f? would make more sense
than Integer() and Float().
They are just not the same,
String#i? and String#f? which I would call String#int? and
String#float? might be nice for you. You can search the Ruby Change
Requests if this was braught up already.
It might be a nice thing to have a String#int? without converting actually.
But yeah they will probably make for a
better implementation then the regexps.

Hmm not sure at all, let us see

637/137 > cat conversions.rb && ruby conversions.rb
# vim: sts=2 sw=2 tw=0 expandtab nu:

require 'benchmark'

class String
def int?
/^\d+/ === self
end

def int1?
Integer(self) rescue false
end
end
N=10_000
Benchmark.bmbm do
|bench|
bench.report( "reg" ) { N.times{ |n| n.to_s.int?; "#{n}x".int? } }
bench.report( "Int" ) { N.times{ |n| n.to_s.int1?; "#{n}x".int1? } }
end

Rehearsal ---------------------------------------
reg 0.160000 0.000000 0.160000 ( 0.201496)
Int 0.420000 0.000000 0.420000 ( 0.466641)
------------------------------ total: 0.580000sec

user system total real
reg 0.180000 0.000000 0.180000 ( 0.238369)
Int 0.420000 0.010000 0.430000 ( 0.513518)


actually the arithmetic part is too costy ;)


Cheers
Robert
--You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw
 
R

Robert Dober

Yes but /^\d+/ isn't the same as /^-?\d+$/.
oops, well spotted, but that will not change a lot...

640/140 > cat conversions.rb && ruby conversions.rb
# vim: sts=2 sw=2 tw=0 expandtab nu:

require 'benchmark'

class String
def int?
/^-?\d+$/ === self
end

def int1?
Integer(self) rescue false
end
end
N=10_000
Benchmark.bmbm do
|bench|
bench.report( "reg" ) { N.times{ |n| n.to_s.int?; "#{n}x".int? } }
bench.report( "Int" ) { N.times{ |n| n.to_s.int1?; "#{n}x".int1? } }
end

Rehearsal ---------------------------------------
reg 0.160000 0.000000 0.160000 ( 0.188396)
Int 0.440000 0.000000 0.440000 ( 0.467686)
------------------------------ total: 0.600000sec

user system total real
reg 0.160000 0.000000 0.160000 ( 0.193306)
Int 0.430000 0.010000 0.440000 ( 0.465137)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top