[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Code Critique: check if int or float

Oliver Saunders

6/20/2007 10:18:00 PM

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?

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

8 Answers

Marcel Molina Jr.

6/20/2007 10:27:00 PM

0

On Thu, Jun 21, 2007 at 07:17:53AM +0900, ole __ wrote:
> 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.

>> '3s'.to_i
=> 3
>> Integer('3s')
ArgumentError: invalid value for Integer: "3s"
from (irb):3:in `Integer'
from (irb):3
>> '3s'.to_f
=> 3.0
>> Float('3s')
ArgumentError: invalid value for Float(): "3s"
from (irb):5:in `Float'
from (irb):5
>> '-8e3'.to_f
=> -8000.0
>> Float('-8e3')
=> -8000.0
>> '-8e3'.to_i
=> -8
>> Integer('-8e3')
ArgumentError: 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
--
Marcel Molina Jr. <marcel@vernix.org>

Tim Hunter

6/20/2007 10:35:00 PM

0

ole __ wrote:
> 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.

--
RMagick OS X Installer [http://rubyforge.org/project...]
RMagick Hints & Tips [http://rubyforge.org/forum/forum.php?for...]
RMagick Installation FAQ [http://rmagick.rubyforge.org/instal...]


Oliver Saunders

6/20/2007 10:51:00 PM

0

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.

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

Sammy Larbi

6/21/2007 2:52:00 PM

0

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.
>
>
>> 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.
>
>

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.


dblack

6/21/2007 3:11:00 PM

0

Robert Dober

6/21/2007 4:26:00 PM

0

On 6/21/07, ole __ <oliver.saunders@gmail.com> wrote:
> 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

Oliver Saunders

6/21/2007 4:44:00 PM

0

Yes but /^\d+/ isn't the same as /^-?\d+$/.

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

Robert Dober

6/21/2007 4:58:00 PM

0

On 6/21/07, ole __ <oliver.saunders@gmail.com> wrote:
> Yes but /^\d+/ isn't the same as /^-?\d+$/.
>
> --
> Posted via http://www.ruby-....
>
>
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)


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