Code Critique: check if int or float

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-forum.com/.

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

···

On Thu, Jun 21, 2007 at 07:17:53AM +0900, ole __ wrote:
--
Marcel Molina Jr. <marcel@vernix.org>

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/projects/rmagick/\]
RMagick Hints & Tips [http://rubyforge.org/forum/forum.php?forum_id=1618\]
RMagick Installation FAQ [http://rmagick.rubyforge.org/install-faq.html\]

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-forum.com/\.

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.

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 :wink:

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

···

On 6/21/07, ole __ <oliver.saunders@gmail.com> wrote:

Hi --

···

On Thu, 21 Jun 2007, Sammy Larbi wrote:

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

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.

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 :slight_smile:

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)

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

···

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

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

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

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)

···

On 6/21/07, ole __ <oliver.saunders@gmail.com> wrote:

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