Test if string is a number in Ruby on Rails





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







91















I have the following in my application controller:



def is_number?(object)
true if Float(object) rescue false
end


and the following condition in my controller:



if mystring.is_number?

end


The condition is throwing an undefined method error. I'm guessing I've defined is_number in the wrong place...?










share|improve this question




















  • 4





    I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

    – boulder_ruby
    Feb 28 '13 at 19:33











  • The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

    – pthamm
    Feb 19 '16 at 23:10


















91















I have the following in my application controller:



def is_number?(object)
true if Float(object) rescue false
end


and the following condition in my controller:



if mystring.is_number?

end


The condition is throwing an undefined method error. I'm guessing I've defined is_number in the wrong place...?










share|improve this question




















  • 4





    I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

    – boulder_ruby
    Feb 28 '13 at 19:33











  • The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

    – pthamm
    Feb 19 '16 at 23:10














91












91








91


22






I have the following in my application controller:



def is_number?(object)
true if Float(object) rescue false
end


and the following condition in my controller:



if mystring.is_number?

end


The condition is throwing an undefined method error. I'm guessing I've defined is_number in the wrong place...?










share|improve this question
















I have the following in my application controller:



def is_number?(object)
true if Float(object) rescue false
end


and the following condition in my controller:



if mystring.is_number?

end


The condition is throwing an undefined method error. I'm guessing I've defined is_number in the wrong place...?







ruby-on-rails ruby string integer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 3 '14 at 2:58









user664833

11k1771114




11k1771114










asked Apr 14 '11 at 9:56









Jamie BuchananJamie Buchanan

2,24821622




2,24821622








  • 4





    I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

    – boulder_ruby
    Feb 28 '13 at 19:33











  • The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

    – pthamm
    Feb 19 '16 at 23:10














  • 4





    I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

    – boulder_ruby
    Feb 28 '13 at 19:33











  • The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

    – pthamm
    Feb 19 '16 at 23:10








4




4





I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

– boulder_ruby
Feb 28 '13 at 19:33





I know a lot of people are here because of codeschool's Rails for Zombies Testing class. Just wait for him to keep explaining. The tests aren't supposed to pass --- its OK to have you test fail in error, you can always patch rails to invent methods such as self.is_number?

– boulder_ruby
Feb 28 '13 at 19:33













The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

– pthamm
Feb 19 '16 at 23:10





The accepted answer fails on cases like "1,000" and is a 39x slower than using a regex approach. See my answer below.

– pthamm
Feb 19 '16 at 23:10












12 Answers
12






active

oldest

votes


















175














Create is_number? Method.



Create a helper method:



def is_number? string
true if Float(string) rescue false
end


And then call it like this:



my_string = '12.34'

is_number?( my_string )
# => true


Extend String Class.



If you want to be able to call is_number? directly on the string instead of passing it as a param to your helper function, then you need to define is_number? as an extension of the String class, like so:



class String
def is_number?
true if Float(self) rescue false
end
end


And then you can call it with:



my_string.is_number?
# => true





share|improve this answer





















  • 2





    This is a bad idea. "330.346.11".to_f # => 330.346

    – epochwolf
    Nov 2 '11 at 23:15






  • 11





    There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

    – Jakob S
    Nov 3 '11 at 10:29








  • 6





    If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

    – Konrad Reiche
    Jun 24 '12 at 18:34






  • 9





    Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

    – Jakob S
    Aug 7 '12 at 8:48






  • 1





    I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

    – Ross Attrill
    Jun 16 '14 at 7:10





















29














class String
def numeric?
return true if self =~ /Ad+Z/
true if Float(self) rescue false
end
end

p "1".numeric? # => true
p "1.2".numeric? # => true
p "5.4e-29".numeric? # => true
p "12e20".numeric? # true
p "1a".numeric? # => false
p "1.2.3.4".numeric? # => false





share|improve this answer





















  • 11





    /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

    – Timothee A
    Sep 1 '14 at 15:18











  • To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

    – Julio
    Oct 9 '14 at 20:09








  • 1





    Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

    – jaydel
    Jul 20 '16 at 15:43











  • Where should I put these codes?

    – zx1986
    Jul 7 '17 at 4:10






  • 2





    Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

    – SunnyMagadan
    Aug 14 '17 at 9:14



















26














Here's a benchmark for common ways to address this problem. Note which one you should use probably depends on the ratio of false cases expected.




  1. If they are relatively uncommon casting is definitely fastest.

  2. If false cases are common and you are just checking for ints, comparison vs a transformed state is a good option.

  3. If false cases are common and you are checking floats, regexp is probably the way to go


If performance doesn't matter use what you like. :-)



Integer checking details:



# 1.9.3-p448
#
# Calculating -------------------------------------
# cast 57485 i/100ms
# cast fail 5549 i/100ms
# to_s 47509 i/100ms
# to_s fail 50573 i/100ms
# regexp 45187 i/100ms
# regexp fail 42566 i/100ms
# -------------------------------------------------
# cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
# cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
# to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
# to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
# regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
# regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s

require 'benchmark/ips'

int = '220000'
bad_int = '22.to.2'

Benchmark.ips do |x|
x.report('cast') do
Integer(int) rescue false
end

x.report('cast fail') do
Integer(bad_int) rescue false
end

x.report('to_s') do
int.to_i.to_s == int
end

x.report('to_s fail') do
bad_int.to_i.to_s == bad_int
end

x.report('regexp') do
int =~ /^d+$/
end

x.report('regexp fail') do
bad_int =~ /^d+$/
end
end


Float checking details:



# 1.9.3-p448
#
# Calculating -------------------------------------
# cast 47430 i/100ms
# cast fail 5023 i/100ms
# to_s 27435 i/100ms
# to_s fail 29609 i/100ms
# regexp 37620 i/100ms
# regexp fail 32557 i/100ms
# -------------------------------------------------
# cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
# cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
# to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
# to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
# regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
# regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s

require 'benchmark/ips'

float = '12.2312'
bad_float = '22.to.2'

Benchmark.ips do |x|
x.report('cast') do
Float(float) rescue false
end

x.report('cast fail') do
Float(bad_float) rescue false
end

x.report('to_s') do
float.to_f.to_s == float
end

x.report('to_s fail') do
bad_float.to_f.to_s == bad_float
end

x.report('regexp') do
float =~ /^[-+]?[0-9]*.?[0-9]+$/
end

x.report('regexp fail') do
bad_float =~ /^[-+]?[0-9]*.?[0-9]+$/
end
end





share|improve this answer































    14














    Relying on the raised exception is not the fastest, readable nor reliable solution.

    I'd do the following :



    my_string.should =~ /^[0-9]+$/





    share|improve this answer



















    • 1





      This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

      – Jakob S
      Apr 14 '11 at 11:03






    • 10





      From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

      – Morten
      Aug 17 '12 at 20:09











    • NoMethodError: undefined method `should' for "asd":String

      – sergserg
      Oct 9 '14 at 22:08











    • In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

      – Damien MATHIEU
      Oct 10 '14 at 8:55











    • I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

      – Josh
      Sep 2 '16 at 0:05



















    6














    no you're just using it wrong. your is_number? has an argument. you called it without the argument



    you should be doing is_number?(mystring)






    share|improve this answer


























    • Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

      – Jakob S
      Apr 14 '11 at 10:15













    • mmm good point, lemme update that

      – corroded
      Apr 14 '11 at 10:20











    • Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

      – Jamie Buchanan
      Apr 14 '11 at 10:23



















    5














    Tl;dr: Use a regex approach. It is 39x faster than the rescue approach in the accepted answer and also handles cases like "1,000"



    def regex_is_number? string
    no_commas = string.gsub(',', '')
    matches = no_commas.match(/-?d+(?:.d+)?/)
    if !matches.nil? && matches.size == 1 && matches[0] == no_commas
    true
    else
    false
    end
    end


    --



    The accepted answer by @Jakob S works for the most part, but catching exceptions can be really slow. In addition, the rescue approach fails on a string like "1,000".



    Let's define the methods:



    def rescue_is_number? string
    true if Float(string) rescue false
    end

    def regex_is_number? string
    no_commas = string.gsub(',', '')
    matches = no_commas.match(/-?d+(?:.d+)?/)
    if !matches.nil? && matches.size == 1 && matches[0] == no_commas
    true
    else
    false
    end
    end


    And now some test cases:



    test_cases = {
    true => ["5.5", "23", "-123", "1,234,123"],
    false => ["hello", "99designs", "(123)456-7890"]
    }


    And a little code to run the test cases:



    test_cases.each do |expected_answer, cases|
    cases.each do |test_case|
    if rescue_is_number?(test_case) != expected_answer
    puts "**rescue_is_number? got #{test_case} wrong**"
    else
    puts "rescue_is_number? got #{test_case} right"
    end

    if regex_is_number?(test_case) != expected_answer
    puts "**regex_is_number? got #{test_case} wrong**"
    else
    puts "regex_is_number? got #{test_case} right"
    end
    end
    end


    Here is the output of the test cases:



    rescue_is_number? got 5.5 right
    regex_is_number? got 5.5 right
    rescue_is_number? got 23 right
    regex_is_number? got 23 right
    rescue_is_number? got -123 right
    regex_is_number? got -123 right
    **rescue_is_number? got 1,234,123 wrong**
    regex_is_number? got 1,234,123 right
    rescue_is_number? got hello right
    regex_is_number? got hello right
    rescue_is_number? got 99designs right
    regex_is_number? got 99designs right
    rescue_is_number? got (123)456-7890 right
    regex_is_number? got (123)456-7890 right


    Time to do some performance benchmarks:



    Benchmark.ips do |x|

    x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } }
    x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } }

    x.compare!
    end


    And the results:



    Calculating -------------------------------------
    rescue 128.000 i/100ms
    regex 4.649k i/100ms
    -------------------------------------------------
    rescue 1.348k (±16.8%) i/s - 6.656k
    regex 52.113k (± 7.8%) i/s - 260.344k

    Comparison:
    regex: 52113.3 i/s
    rescue: 1347.5 i/s - 38.67x slower





    share|improve this answer
























    • Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

      – Jodi
      Feb 24 '16 at 16:27






    • 1





      Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

      – James Moore
      Feb 25 '17 at 18:59



















    4














    this is how i do it, but i think too there must be a better way



    object.to_i.to_s == object || object.to_f.to_s == object





    share|improve this answer



















    • 4





      It does not recognize floating notation, e.g. 1.2e+35.

      – hipertracker
      Jul 25 '12 at 16:13



















    4














    In rails 4, you need to put
    require File.expand_path('../../lib', __FILE__) + '/ext/string'
    in your config/application.rb






    share|improve this answer



















    • 1





      actually you don't need to do this, you could just put string.rb in "initializers" and it works!

      – mahatmanich
      Jun 16 '14 at 8:32











    • That's it! so cool!

      – zx1986
      Jul 7 '17 at 6:14



















    3














    If you prefer not to use exceptions as part of the logic, you might try this:



    class String
    def numeric?
    !!(self =~ /^-?d+(.d*)?$/)
    end
    end


    Or, if you want it to work across all object classes, replace class String with class Object an convert self to a string: !!(self.to_s =~ /^-?d+(.d*)?$/)






    share|improve this answer


























    • Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

      – Arnold Roa
      Apr 11 '17 at 14:37











    • Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

      – Mark Schneider
      Apr 13 '17 at 2:52



















    0














    As of Ruby 2.6.0, the numeric cast-methods have an optional exception-argument [1]. This enables us to use the built-in methods without using exceptions as control flow:



    Float('x') # => ArgumentError (invalid value for Float(): "x")
    Float('x', exception: false) # => nil


    Therefore, you don't have to define your own method, but can directly check variables like e.g.



    if Float(my_var, exception: false)
    # do something if my_var is a float
    end





    share|improve this answer































      -2














      use the following function:



      def is_numeric? val
      return val.try(:to_f).try(:to_s) == val
      end


      so,



      is_numeric? "1.2f" = false



      is_numeric? "1.2" = true



      is_numeric? "12f" = false



      is_numeric? "12" = true






      share|improve this answer
























      • This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

        – GMA
        Sep 17 '15 at 12:51











      • In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

        – GMA
        Sep 17 '15 at 12:52



















      -5














      How dumb is this solution?



      def is_number?(i)
      begin
      i+0 == i
      rescue TypeError
      false
      end
      end





      share|improve this answer



















      • 1





        This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

        – Sqeaky
        Apr 28 '14 at 17:17












      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5661466%2ftest-if-string-is-a-number-in-ruby-on-rails%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      12 Answers
      12






      active

      oldest

      votes








      12 Answers
      12






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      175














      Create is_number? Method.



      Create a helper method:



      def is_number? string
      true if Float(string) rescue false
      end


      And then call it like this:



      my_string = '12.34'

      is_number?( my_string )
      # => true


      Extend String Class.



      If you want to be able to call is_number? directly on the string instead of passing it as a param to your helper function, then you need to define is_number? as an extension of the String class, like so:



      class String
      def is_number?
      true if Float(self) rescue false
      end
      end


      And then you can call it with:



      my_string.is_number?
      # => true





      share|improve this answer





















      • 2





        This is a bad idea. "330.346.11".to_f # => 330.346

        – epochwolf
        Nov 2 '11 at 23:15






      • 11





        There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

        – Jakob S
        Nov 3 '11 at 10:29








      • 6





        If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

        – Konrad Reiche
        Jun 24 '12 at 18:34






      • 9





        Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

        – Jakob S
        Aug 7 '12 at 8:48






      • 1





        I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

        – Ross Attrill
        Jun 16 '14 at 7:10


















      175














      Create is_number? Method.



      Create a helper method:



      def is_number? string
      true if Float(string) rescue false
      end


      And then call it like this:



      my_string = '12.34'

      is_number?( my_string )
      # => true


      Extend String Class.



      If you want to be able to call is_number? directly on the string instead of passing it as a param to your helper function, then you need to define is_number? as an extension of the String class, like so:



      class String
      def is_number?
      true if Float(self) rescue false
      end
      end


      And then you can call it with:



      my_string.is_number?
      # => true





      share|improve this answer





















      • 2





        This is a bad idea. "330.346.11".to_f # => 330.346

        – epochwolf
        Nov 2 '11 at 23:15






      • 11





        There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

        – Jakob S
        Nov 3 '11 at 10:29








      • 6





        If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

        – Konrad Reiche
        Jun 24 '12 at 18:34






      • 9





        Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

        – Jakob S
        Aug 7 '12 at 8:48






      • 1





        I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

        – Ross Attrill
        Jun 16 '14 at 7:10
















      175












      175








      175







      Create is_number? Method.



      Create a helper method:



      def is_number? string
      true if Float(string) rescue false
      end


      And then call it like this:



      my_string = '12.34'

      is_number?( my_string )
      # => true


      Extend String Class.



      If you want to be able to call is_number? directly on the string instead of passing it as a param to your helper function, then you need to define is_number? as an extension of the String class, like so:



      class String
      def is_number?
      true if Float(self) rescue false
      end
      end


      And then you can call it with:



      my_string.is_number?
      # => true





      share|improve this answer















      Create is_number? Method.



      Create a helper method:



      def is_number? string
      true if Float(string) rescue false
      end


      And then call it like this:



      my_string = '12.34'

      is_number?( my_string )
      # => true


      Extend String Class.



      If you want to be able to call is_number? directly on the string instead of passing it as a param to your helper function, then you need to define is_number? as an extension of the String class, like so:



      class String
      def is_number?
      true if Float(self) rescue false
      end
      end


      And then you can call it with:



      my_string.is_number?
      # => true






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jul 3 '15 at 11:44









      Joshua Pinter

      25.5k9145174




      25.5k9145174










      answered Apr 14 '11 at 10:13









      Jakob SJakob S

      16.1k23535




      16.1k23535








      • 2





        This is a bad idea. "330.346.11".to_f # => 330.346

        – epochwolf
        Nov 2 '11 at 23:15






      • 11





        There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

        – Jakob S
        Nov 3 '11 at 10:29








      • 6





        If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

        – Konrad Reiche
        Jun 24 '12 at 18:34






      • 9





        Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

        – Jakob S
        Aug 7 '12 at 8:48






      • 1





        I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

        – Ross Attrill
        Jun 16 '14 at 7:10
















      • 2





        This is a bad idea. "330.346.11".to_f # => 330.346

        – epochwolf
        Nov 2 '11 at 23:15






      • 11





        There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

        – Jakob S
        Nov 3 '11 at 10:29








      • 6





        If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

        – Konrad Reiche
        Jun 24 '12 at 18:34






      • 9





        Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

        – Jakob S
        Aug 7 '12 at 8:48






      • 1





        I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

        – Ross Attrill
        Jun 16 '14 at 7:10










      2




      2





      This is a bad idea. "330.346.11".to_f # => 330.346

      – epochwolf
      Nov 2 '11 at 23:15





      This is a bad idea. "330.346.11".to_f # => 330.346

      – epochwolf
      Nov 2 '11 at 23:15




      11




      11





      There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

      – Jakob S
      Nov 3 '11 at 10:29







      There is no to_f in the above, and Float() doesn't exhibit that behavior: Float("330.346.11") raises ArgumentError: invalid value for Float(): "330.346.11"

      – Jakob S
      Nov 3 '11 at 10:29






      6




      6





      If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

      – Konrad Reiche
      Jun 24 '12 at 18:34





      If you use that patch, I'd rename it to numeric?, to stay in line with ruby naming conventions (Numeric classes inherit from Numeric, is_ prefixes are javaish).

      – Konrad Reiche
      Jun 24 '12 at 18:34




      9




      9





      Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

      – Jakob S
      Aug 7 '12 at 8:48





      Not really relevant to the original question, but I'd probably put the code in lib/core_ext/string.rb.

      – Jakob S
      Aug 7 '12 at 8:48




      1




      1





      I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

      – Ross Attrill
      Jun 16 '14 at 7:10







      I don't think the is_number?(string) bit works Ruby 1.9. Maybe that is part of Rails or 1.8? String.is_a?(Numeric) works. See also stackoverflow.com/questions/2095493/….

      – Ross Attrill
      Jun 16 '14 at 7:10















      29














      class String
      def numeric?
      return true if self =~ /Ad+Z/
      true if Float(self) rescue false
      end
      end

      p "1".numeric? # => true
      p "1.2".numeric? # => true
      p "5.4e-29".numeric? # => true
      p "12e20".numeric? # true
      p "1a".numeric? # => false
      p "1.2.3.4".numeric? # => false





      share|improve this answer





















      • 11





        /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

        – Timothee A
        Sep 1 '14 at 15:18











      • To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

        – Julio
        Oct 9 '14 at 20:09








      • 1





        Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

        – jaydel
        Jul 20 '16 at 15:43











      • Where should I put these codes?

        – zx1986
        Jul 7 '17 at 4:10






      • 2





        Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

        – SunnyMagadan
        Aug 14 '17 at 9:14
















      29














      class String
      def numeric?
      return true if self =~ /Ad+Z/
      true if Float(self) rescue false
      end
      end

      p "1".numeric? # => true
      p "1.2".numeric? # => true
      p "5.4e-29".numeric? # => true
      p "12e20".numeric? # true
      p "1a".numeric? # => false
      p "1.2.3.4".numeric? # => false





      share|improve this answer





















      • 11





        /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

        – Timothee A
        Sep 1 '14 at 15:18











      • To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

        – Julio
        Oct 9 '14 at 20:09








      • 1





        Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

        – jaydel
        Jul 20 '16 at 15:43











      • Where should I put these codes?

        – zx1986
        Jul 7 '17 at 4:10






      • 2





        Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

        – SunnyMagadan
        Aug 14 '17 at 9:14














      29












      29








      29







      class String
      def numeric?
      return true if self =~ /Ad+Z/
      true if Float(self) rescue false
      end
      end

      p "1".numeric? # => true
      p "1.2".numeric? # => true
      p "5.4e-29".numeric? # => true
      p "12e20".numeric? # true
      p "1a".numeric? # => false
      p "1.2.3.4".numeric? # => false





      share|improve this answer















      class String
      def numeric?
      return true if self =~ /Ad+Z/
      true if Float(self) rescue false
      end
      end

      p "1".numeric? # => true
      p "1.2".numeric? # => true
      p "5.4e-29".numeric? # => true
      p "12e20".numeric? # true
      p "1a".numeric? # => false
      p "1.2.3.4".numeric? # => false






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 1 '15 at 20:40









      Marius Butuc

      10.2k1868107




      10.2k1868107










      answered Jul 25 '12 at 16:02









      hipertrackerhipertracker

      2,1182212




      2,1182212








      • 11





        /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

        – Timothee A
        Sep 1 '14 at 15:18











      • To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

        – Julio
        Oct 9 '14 at 20:09








      • 1





        Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

        – jaydel
        Jul 20 '16 at 15:43











      • Where should I put these codes?

        – zx1986
        Jul 7 '17 at 4:10






      • 2





        Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

        – SunnyMagadan
        Aug 14 '17 at 9:14














      • 11





        /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

        – Timothee A
        Sep 1 '14 at 15:18











      • To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

        – Julio
        Oct 9 '14 at 20:09








      • 1





        Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

        – jaydel
        Jul 20 '16 at 15:43











      • Where should I put these codes?

        – zx1986
        Jul 7 '17 at 4:10






      • 2





        Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

        – SunnyMagadan
        Aug 14 '17 at 9:14








      11




      11





      /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

      – Timothee A
      Sep 1 '14 at 15:18





      /^d+$/ is not a safe regexp in Ruby, /Ad+Z/ is. (e.g. "42nsome text" would return true)

      – Timothee A
      Sep 1 '14 at 15:18













      To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

      – Julio
      Oct 9 '14 at 20:09







      To clarify on @TimotheeA's comment, it is safe to use /^d+$/ if dealing with lines but in this case it's about beginning and end of a string, thus /Ad+Z/.

      – Julio
      Oct 9 '14 at 20:09






      1




      1





      Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

      – jaydel
      Jul 20 '16 at 15:43





      Shouldn't answers be edited to change the actual answer BY the responder? changing the answer in an edit if you're not the responder seems...possibly underhanded and should be out of bounds.

      – jaydel
      Jul 20 '16 at 15:43













      Where should I put these codes?

      – zx1986
      Jul 7 '17 at 4:10





      Where should I put these codes?

      – zx1986
      Jul 7 '17 at 4:10




      2




      2





      Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

      – SunnyMagadan
      Aug 14 '17 at 9:14





      Z allows to have n at the end of the string, so "123n" will pass validation, regardless that it's not fully numeric. But if you use z then it will be more correct regexp: /Ad+z/

      – SunnyMagadan
      Aug 14 '17 at 9:14











      26














      Here's a benchmark for common ways to address this problem. Note which one you should use probably depends on the ratio of false cases expected.




      1. If they are relatively uncommon casting is definitely fastest.

      2. If false cases are common and you are just checking for ints, comparison vs a transformed state is a good option.

      3. If false cases are common and you are checking floats, regexp is probably the way to go


      If performance doesn't matter use what you like. :-)



      Integer checking details:



      # 1.9.3-p448
      #
      # Calculating -------------------------------------
      # cast 57485 i/100ms
      # cast fail 5549 i/100ms
      # to_s 47509 i/100ms
      # to_s fail 50573 i/100ms
      # regexp 45187 i/100ms
      # regexp fail 42566 i/100ms
      # -------------------------------------------------
      # cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
      # cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
      # to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
      # to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
      # regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
      # regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s

      require 'benchmark/ips'

      int = '220000'
      bad_int = '22.to.2'

      Benchmark.ips do |x|
      x.report('cast') do
      Integer(int) rescue false
      end

      x.report('cast fail') do
      Integer(bad_int) rescue false
      end

      x.report('to_s') do
      int.to_i.to_s == int
      end

      x.report('to_s fail') do
      bad_int.to_i.to_s == bad_int
      end

      x.report('regexp') do
      int =~ /^d+$/
      end

      x.report('regexp fail') do
      bad_int =~ /^d+$/
      end
      end


      Float checking details:



      # 1.9.3-p448
      #
      # Calculating -------------------------------------
      # cast 47430 i/100ms
      # cast fail 5023 i/100ms
      # to_s 27435 i/100ms
      # to_s fail 29609 i/100ms
      # regexp 37620 i/100ms
      # regexp fail 32557 i/100ms
      # -------------------------------------------------
      # cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
      # cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
      # to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
      # to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
      # regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
      # regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s

      require 'benchmark/ips'

      float = '12.2312'
      bad_float = '22.to.2'

      Benchmark.ips do |x|
      x.report('cast') do
      Float(float) rescue false
      end

      x.report('cast fail') do
      Float(bad_float) rescue false
      end

      x.report('to_s') do
      float.to_f.to_s == float
      end

      x.report('to_s fail') do
      bad_float.to_f.to_s == bad_float
      end

      x.report('regexp') do
      float =~ /^[-+]?[0-9]*.?[0-9]+$/
      end

      x.report('regexp fail') do
      bad_float =~ /^[-+]?[0-9]*.?[0-9]+$/
      end
      end





      share|improve this answer




























        26














        Here's a benchmark for common ways to address this problem. Note which one you should use probably depends on the ratio of false cases expected.




        1. If they are relatively uncommon casting is definitely fastest.

        2. If false cases are common and you are just checking for ints, comparison vs a transformed state is a good option.

        3. If false cases are common and you are checking floats, regexp is probably the way to go


        If performance doesn't matter use what you like. :-)



        Integer checking details:



        # 1.9.3-p448
        #
        # Calculating -------------------------------------
        # cast 57485 i/100ms
        # cast fail 5549 i/100ms
        # to_s 47509 i/100ms
        # to_s fail 50573 i/100ms
        # regexp 45187 i/100ms
        # regexp fail 42566 i/100ms
        # -------------------------------------------------
        # cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
        # cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
        # to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
        # to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
        # regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
        # regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s

        require 'benchmark/ips'

        int = '220000'
        bad_int = '22.to.2'

        Benchmark.ips do |x|
        x.report('cast') do
        Integer(int) rescue false
        end

        x.report('cast fail') do
        Integer(bad_int) rescue false
        end

        x.report('to_s') do
        int.to_i.to_s == int
        end

        x.report('to_s fail') do
        bad_int.to_i.to_s == bad_int
        end

        x.report('regexp') do
        int =~ /^d+$/
        end

        x.report('regexp fail') do
        bad_int =~ /^d+$/
        end
        end


        Float checking details:



        # 1.9.3-p448
        #
        # Calculating -------------------------------------
        # cast 47430 i/100ms
        # cast fail 5023 i/100ms
        # to_s 27435 i/100ms
        # to_s fail 29609 i/100ms
        # regexp 37620 i/100ms
        # regexp fail 32557 i/100ms
        # -------------------------------------------------
        # cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
        # cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
        # to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
        # to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
        # regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
        # regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s

        require 'benchmark/ips'

        float = '12.2312'
        bad_float = '22.to.2'

        Benchmark.ips do |x|
        x.report('cast') do
        Float(float) rescue false
        end

        x.report('cast fail') do
        Float(bad_float) rescue false
        end

        x.report('to_s') do
        float.to_f.to_s == float
        end

        x.report('to_s fail') do
        bad_float.to_f.to_s == bad_float
        end

        x.report('regexp') do
        float =~ /^[-+]?[0-9]*.?[0-9]+$/
        end

        x.report('regexp fail') do
        bad_float =~ /^[-+]?[0-9]*.?[0-9]+$/
        end
        end





        share|improve this answer


























          26












          26








          26







          Here's a benchmark for common ways to address this problem. Note which one you should use probably depends on the ratio of false cases expected.




          1. If they are relatively uncommon casting is definitely fastest.

          2. If false cases are common and you are just checking for ints, comparison vs a transformed state is a good option.

          3. If false cases are common and you are checking floats, regexp is probably the way to go


          If performance doesn't matter use what you like. :-)



          Integer checking details:



          # 1.9.3-p448
          #
          # Calculating -------------------------------------
          # cast 57485 i/100ms
          # cast fail 5549 i/100ms
          # to_s 47509 i/100ms
          # to_s fail 50573 i/100ms
          # regexp 45187 i/100ms
          # regexp fail 42566 i/100ms
          # -------------------------------------------------
          # cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
          # cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
          # to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
          # to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
          # regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
          # regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s

          require 'benchmark/ips'

          int = '220000'
          bad_int = '22.to.2'

          Benchmark.ips do |x|
          x.report('cast') do
          Integer(int) rescue false
          end

          x.report('cast fail') do
          Integer(bad_int) rescue false
          end

          x.report('to_s') do
          int.to_i.to_s == int
          end

          x.report('to_s fail') do
          bad_int.to_i.to_s == bad_int
          end

          x.report('regexp') do
          int =~ /^d+$/
          end

          x.report('regexp fail') do
          bad_int =~ /^d+$/
          end
          end


          Float checking details:



          # 1.9.3-p448
          #
          # Calculating -------------------------------------
          # cast 47430 i/100ms
          # cast fail 5023 i/100ms
          # to_s 27435 i/100ms
          # to_s fail 29609 i/100ms
          # regexp 37620 i/100ms
          # regexp fail 32557 i/100ms
          # -------------------------------------------------
          # cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
          # cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
          # to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
          # to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
          # regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
          # regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s

          require 'benchmark/ips'

          float = '12.2312'
          bad_float = '22.to.2'

          Benchmark.ips do |x|
          x.report('cast') do
          Float(float) rescue false
          end

          x.report('cast fail') do
          Float(bad_float) rescue false
          end

          x.report('to_s') do
          float.to_f.to_s == float
          end

          x.report('to_s fail') do
          bad_float.to_f.to_s == bad_float
          end

          x.report('regexp') do
          float =~ /^[-+]?[0-9]*.?[0-9]+$/
          end

          x.report('regexp fail') do
          bad_float =~ /^[-+]?[0-9]*.?[0-9]+$/
          end
          end





          share|improve this answer













          Here's a benchmark for common ways to address this problem. Note which one you should use probably depends on the ratio of false cases expected.




          1. If they are relatively uncommon casting is definitely fastest.

          2. If false cases are common and you are just checking for ints, comparison vs a transformed state is a good option.

          3. If false cases are common and you are checking floats, regexp is probably the way to go


          If performance doesn't matter use what you like. :-)



          Integer checking details:



          # 1.9.3-p448
          #
          # Calculating -------------------------------------
          # cast 57485 i/100ms
          # cast fail 5549 i/100ms
          # to_s 47509 i/100ms
          # to_s fail 50573 i/100ms
          # regexp 45187 i/100ms
          # regexp fail 42566 i/100ms
          # -------------------------------------------------
          # cast 2353703.4 (±4.9%) i/s - 11726940 in 4.998270s
          # cast fail 65590.2 (±4.6%) i/s - 327391 in 5.003511s
          # to_s 1420892.0 (±6.8%) i/s - 7078841 in 5.011462s
          # to_s fail 1717948.8 (±6.0%) i/s - 8546837 in 4.998672s
          # regexp 1525729.9 (±7.0%) i/s - 7591416 in 5.007105s
          # regexp fail 1154461.1 (±5.5%) i/s - 5788976 in 5.035311s

          require 'benchmark/ips'

          int = '220000'
          bad_int = '22.to.2'

          Benchmark.ips do |x|
          x.report('cast') do
          Integer(int) rescue false
          end

          x.report('cast fail') do
          Integer(bad_int) rescue false
          end

          x.report('to_s') do
          int.to_i.to_s == int
          end

          x.report('to_s fail') do
          bad_int.to_i.to_s == bad_int
          end

          x.report('regexp') do
          int =~ /^d+$/
          end

          x.report('regexp fail') do
          bad_int =~ /^d+$/
          end
          end


          Float checking details:



          # 1.9.3-p448
          #
          # Calculating -------------------------------------
          # cast 47430 i/100ms
          # cast fail 5023 i/100ms
          # to_s 27435 i/100ms
          # to_s fail 29609 i/100ms
          # regexp 37620 i/100ms
          # regexp fail 32557 i/100ms
          # -------------------------------------------------
          # cast 2283762.5 (±6.8%) i/s - 11383200 in 5.012934s
          # cast fail 63108.8 (±6.7%) i/s - 316449 in 5.038518s
          # to_s 593069.3 (±8.8%) i/s - 2962980 in 5.042459s
          # to_s fail 857217.1 (±10.0%) i/s - 4263696 in 5.033024s
          # regexp 1383194.8 (±6.7%) i/s - 6884460 in 5.008275s
          # regexp fail 723390.2 (±5.8%) i/s - 3613827 in 5.016494s

          require 'benchmark/ips'

          float = '12.2312'
          bad_float = '22.to.2'

          Benchmark.ips do |x|
          x.report('cast') do
          Float(float) rescue false
          end

          x.report('cast fail') do
          Float(bad_float) rescue false
          end

          x.report('to_s') do
          float.to_f.to_s == float
          end

          x.report('to_s fail') do
          bad_float.to_f.to_s == bad_float
          end

          x.report('regexp') do
          float =~ /^[-+]?[0-9]*.?[0-9]+$/
          end

          x.report('regexp fail') do
          bad_float =~ /^[-+]?[0-9]*.?[0-9]+$/
          end
          end






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 8 '13 at 1:22









          Matt SandersMatt Sanders

          4,0772133




          4,0772133























              14














              Relying on the raised exception is not the fastest, readable nor reliable solution.

              I'd do the following :



              my_string.should =~ /^[0-9]+$/





              share|improve this answer



















              • 1





                This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

                – Jakob S
                Apr 14 '11 at 11:03






              • 10





                From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

                – Morten
                Aug 17 '12 at 20:09











              • NoMethodError: undefined method `should' for "asd":String

                – sergserg
                Oct 9 '14 at 22:08











              • In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

                – Damien MATHIEU
                Oct 10 '14 at 8:55











              • I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

                – Josh
                Sep 2 '16 at 0:05
















              14














              Relying on the raised exception is not the fastest, readable nor reliable solution.

              I'd do the following :



              my_string.should =~ /^[0-9]+$/





              share|improve this answer



















              • 1





                This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

                – Jakob S
                Apr 14 '11 at 11:03






              • 10





                From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

                – Morten
                Aug 17 '12 at 20:09











              • NoMethodError: undefined method `should' for "asd":String

                – sergserg
                Oct 9 '14 at 22:08











              • In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

                – Damien MATHIEU
                Oct 10 '14 at 8:55











              • I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

                – Josh
                Sep 2 '16 at 0:05














              14












              14








              14







              Relying on the raised exception is not the fastest, readable nor reliable solution.

              I'd do the following :



              my_string.should =~ /^[0-9]+$/





              share|improve this answer













              Relying on the raised exception is not the fastest, readable nor reliable solution.

              I'd do the following :



              my_string.should =~ /^[0-9]+$/






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Apr 14 '11 at 10:20









              Damien MATHIEUDamien MATHIEU

              24k126586




              24k126586








              • 1





                This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

                – Jakob S
                Apr 14 '11 at 11:03






              • 10





                From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

                – Morten
                Aug 17 '12 at 20:09











              • NoMethodError: undefined method `should' for "asd":String

                – sergserg
                Oct 9 '14 at 22:08











              • In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

                – Damien MATHIEU
                Oct 10 '14 at 8:55











              • I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

                – Josh
                Sep 2 '16 at 0:05














              • 1





                This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

                – Jakob S
                Apr 14 '11 at 11:03






              • 10





                From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

                – Morten
                Aug 17 '12 at 20:09











              • NoMethodError: undefined method `should' for "asd":String

                – sergserg
                Oct 9 '14 at 22:08











              • In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

                – Damien MATHIEU
                Oct 10 '14 at 8:55











              • I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

                – Josh
                Sep 2 '16 at 0:05








              1




              1





              This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

              – Jakob S
              Apr 14 '11 at 11:03





              This only works for positive integers, however. Values like '-1', '0.0', or '1_000' all return false even though they are valid numeric values. You're looking at something like /^[-.0-9]+$/, but that erroneously accepts '--'.

              – Jakob S
              Apr 14 '11 at 11:03




              10




              10





              From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

              – Morten
              Aug 17 '12 at 20:09





              From Rails 'validates_numericality_of': raw_value.to_s =~ /A[+-]?d+Z/

              – Morten
              Aug 17 '12 at 20:09













              NoMethodError: undefined method `should' for "asd":String

              – sergserg
              Oct 9 '14 at 22:08





              NoMethodError: undefined method `should' for "asd":String

              – sergserg
              Oct 9 '14 at 22:08













              In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

              – Damien MATHIEU
              Oct 10 '14 at 8:55





              In the latest rspec, this becomes expect(my_string).to match(/^[0-9]+$/)

              – Damien MATHIEU
              Oct 10 '14 at 8:55













              I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

              – Josh
              Sep 2 '16 at 0:05





              I like: my_string =~ /A-?(d+)?.?d+Z/ it lets you do '.1', '-0.1', or '12' but not '' or '-' or '.'

              – Josh
              Sep 2 '16 at 0:05











              6














              no you're just using it wrong. your is_number? has an argument. you called it without the argument



              you should be doing is_number?(mystring)






              share|improve this answer


























              • Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

                – Jakob S
                Apr 14 '11 at 10:15













              • mmm good point, lemme update that

                – corroded
                Apr 14 '11 at 10:20











              • Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

                – Jamie Buchanan
                Apr 14 '11 at 10:23
















              6














              no you're just using it wrong. your is_number? has an argument. you called it without the argument



              you should be doing is_number?(mystring)






              share|improve this answer


























              • Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

                – Jakob S
                Apr 14 '11 at 10:15













              • mmm good point, lemme update that

                – corroded
                Apr 14 '11 at 10:20











              • Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

                – Jamie Buchanan
                Apr 14 '11 at 10:23














              6












              6








              6







              no you're just using it wrong. your is_number? has an argument. you called it without the argument



              you should be doing is_number?(mystring)






              share|improve this answer















              no you're just using it wrong. your is_number? has an argument. you called it without the argument



              you should be doing is_number?(mystring)







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 14 '11 at 10:22

























              answered Apr 14 '11 at 9:58









              corrodedcorroded

              15k1772128




              15k1772128













              • Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

                – Jakob S
                Apr 14 '11 at 10:15













              • mmm good point, lemme update that

                – corroded
                Apr 14 '11 at 10:20











              • Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

                – Jamie Buchanan
                Apr 14 '11 at 10:23



















              • Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

                – Jakob S
                Apr 14 '11 at 10:15













              • mmm good point, lemme update that

                – corroded
                Apr 14 '11 at 10:20











              • Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

                – Jamie Buchanan
                Apr 14 '11 at 10:23

















              Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

              – Jakob S
              Apr 14 '11 at 10:15







              Based on the is_number? method in the question, using is_a? is not giving the correct answer. If mystring is indeed a String, mystring.is_a?(Integer) will always be false. It looks like he wants a result like is_number?("12.4") #=> true

              – Jakob S
              Apr 14 '11 at 10:15















              mmm good point, lemme update that

              – corroded
              Apr 14 '11 at 10:20





              mmm good point, lemme update that

              – corroded
              Apr 14 '11 at 10:20













              Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

              – Jamie Buchanan
              Apr 14 '11 at 10:23





              Jakob S is correct. mystring is indeed always a string, but may be comprise of just numbers. perhaps my question should have been is_numeric? so as not to confuse the datatype

              – Jamie Buchanan
              Apr 14 '11 at 10:23











              5














              Tl;dr: Use a regex approach. It is 39x faster than the rescue approach in the accepted answer and also handles cases like "1,000"



              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              --



              The accepted answer by @Jakob S works for the most part, but catching exceptions can be really slow. In addition, the rescue approach fails on a string like "1,000".



              Let's define the methods:



              def rescue_is_number? string
              true if Float(string) rescue false
              end

              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              And now some test cases:



              test_cases = {
              true => ["5.5", "23", "-123", "1,234,123"],
              false => ["hello", "99designs", "(123)456-7890"]
              }


              And a little code to run the test cases:



              test_cases.each do |expected_answer, cases|
              cases.each do |test_case|
              if rescue_is_number?(test_case) != expected_answer
              puts "**rescue_is_number? got #{test_case} wrong**"
              else
              puts "rescue_is_number? got #{test_case} right"
              end

              if regex_is_number?(test_case) != expected_answer
              puts "**regex_is_number? got #{test_case} wrong**"
              else
              puts "regex_is_number? got #{test_case} right"
              end
              end
              end


              Here is the output of the test cases:



              rescue_is_number? got 5.5 right
              regex_is_number? got 5.5 right
              rescue_is_number? got 23 right
              regex_is_number? got 23 right
              rescue_is_number? got -123 right
              regex_is_number? got -123 right
              **rescue_is_number? got 1,234,123 wrong**
              regex_is_number? got 1,234,123 right
              rescue_is_number? got hello right
              regex_is_number? got hello right
              rescue_is_number? got 99designs right
              regex_is_number? got 99designs right
              rescue_is_number? got (123)456-7890 right
              regex_is_number? got (123)456-7890 right


              Time to do some performance benchmarks:



              Benchmark.ips do |x|

              x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } }
              x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } }

              x.compare!
              end


              And the results:



              Calculating -------------------------------------
              rescue 128.000 i/100ms
              regex 4.649k i/100ms
              -------------------------------------------------
              rescue 1.348k (±16.8%) i/s - 6.656k
              regex 52.113k (± 7.8%) i/s - 260.344k

              Comparison:
              regex: 52113.3 i/s
              rescue: 1347.5 i/s - 38.67x slower





              share|improve this answer
























              • Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

                – Jodi
                Feb 24 '16 at 16:27






              • 1





                Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

                – James Moore
                Feb 25 '17 at 18:59
















              5














              Tl;dr: Use a regex approach. It is 39x faster than the rescue approach in the accepted answer and also handles cases like "1,000"



              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              --



              The accepted answer by @Jakob S works for the most part, but catching exceptions can be really slow. In addition, the rescue approach fails on a string like "1,000".



              Let's define the methods:



              def rescue_is_number? string
              true if Float(string) rescue false
              end

              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              And now some test cases:



              test_cases = {
              true => ["5.5", "23", "-123", "1,234,123"],
              false => ["hello", "99designs", "(123)456-7890"]
              }


              And a little code to run the test cases:



              test_cases.each do |expected_answer, cases|
              cases.each do |test_case|
              if rescue_is_number?(test_case) != expected_answer
              puts "**rescue_is_number? got #{test_case} wrong**"
              else
              puts "rescue_is_number? got #{test_case} right"
              end

              if regex_is_number?(test_case) != expected_answer
              puts "**regex_is_number? got #{test_case} wrong**"
              else
              puts "regex_is_number? got #{test_case} right"
              end
              end
              end


              Here is the output of the test cases:



              rescue_is_number? got 5.5 right
              regex_is_number? got 5.5 right
              rescue_is_number? got 23 right
              regex_is_number? got 23 right
              rescue_is_number? got -123 right
              regex_is_number? got -123 right
              **rescue_is_number? got 1,234,123 wrong**
              regex_is_number? got 1,234,123 right
              rescue_is_number? got hello right
              regex_is_number? got hello right
              rescue_is_number? got 99designs right
              regex_is_number? got 99designs right
              rescue_is_number? got (123)456-7890 right
              regex_is_number? got (123)456-7890 right


              Time to do some performance benchmarks:



              Benchmark.ips do |x|

              x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } }
              x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } }

              x.compare!
              end


              And the results:



              Calculating -------------------------------------
              rescue 128.000 i/100ms
              regex 4.649k i/100ms
              -------------------------------------------------
              rescue 1.348k (±16.8%) i/s - 6.656k
              regex 52.113k (± 7.8%) i/s - 260.344k

              Comparison:
              regex: 52113.3 i/s
              rescue: 1347.5 i/s - 38.67x slower





              share|improve this answer
























              • Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

                – Jodi
                Feb 24 '16 at 16:27






              • 1





                Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

                – James Moore
                Feb 25 '17 at 18:59














              5












              5








              5







              Tl;dr: Use a regex approach. It is 39x faster than the rescue approach in the accepted answer and also handles cases like "1,000"



              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              --



              The accepted answer by @Jakob S works for the most part, but catching exceptions can be really slow. In addition, the rescue approach fails on a string like "1,000".



              Let's define the methods:



              def rescue_is_number? string
              true if Float(string) rescue false
              end

              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              And now some test cases:



              test_cases = {
              true => ["5.5", "23", "-123", "1,234,123"],
              false => ["hello", "99designs", "(123)456-7890"]
              }


              And a little code to run the test cases:



              test_cases.each do |expected_answer, cases|
              cases.each do |test_case|
              if rescue_is_number?(test_case) != expected_answer
              puts "**rescue_is_number? got #{test_case} wrong**"
              else
              puts "rescue_is_number? got #{test_case} right"
              end

              if regex_is_number?(test_case) != expected_answer
              puts "**regex_is_number? got #{test_case} wrong**"
              else
              puts "regex_is_number? got #{test_case} right"
              end
              end
              end


              Here is the output of the test cases:



              rescue_is_number? got 5.5 right
              regex_is_number? got 5.5 right
              rescue_is_number? got 23 right
              regex_is_number? got 23 right
              rescue_is_number? got -123 right
              regex_is_number? got -123 right
              **rescue_is_number? got 1,234,123 wrong**
              regex_is_number? got 1,234,123 right
              rescue_is_number? got hello right
              regex_is_number? got hello right
              rescue_is_number? got 99designs right
              regex_is_number? got 99designs right
              rescue_is_number? got (123)456-7890 right
              regex_is_number? got (123)456-7890 right


              Time to do some performance benchmarks:



              Benchmark.ips do |x|

              x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } }
              x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } }

              x.compare!
              end


              And the results:



              Calculating -------------------------------------
              rescue 128.000 i/100ms
              regex 4.649k i/100ms
              -------------------------------------------------
              rescue 1.348k (±16.8%) i/s - 6.656k
              regex 52.113k (± 7.8%) i/s - 260.344k

              Comparison:
              regex: 52113.3 i/s
              rescue: 1347.5 i/s - 38.67x slower





              share|improve this answer













              Tl;dr: Use a regex approach. It is 39x faster than the rescue approach in the accepted answer and also handles cases like "1,000"



              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              --



              The accepted answer by @Jakob S works for the most part, but catching exceptions can be really slow. In addition, the rescue approach fails on a string like "1,000".



              Let's define the methods:



              def rescue_is_number? string
              true if Float(string) rescue false
              end

              def regex_is_number? string
              no_commas = string.gsub(',', '')
              matches = no_commas.match(/-?d+(?:.d+)?/)
              if !matches.nil? && matches.size == 1 && matches[0] == no_commas
              true
              else
              false
              end
              end


              And now some test cases:



              test_cases = {
              true => ["5.5", "23", "-123", "1,234,123"],
              false => ["hello", "99designs", "(123)456-7890"]
              }


              And a little code to run the test cases:



              test_cases.each do |expected_answer, cases|
              cases.each do |test_case|
              if rescue_is_number?(test_case) != expected_answer
              puts "**rescue_is_number? got #{test_case} wrong**"
              else
              puts "rescue_is_number? got #{test_case} right"
              end

              if regex_is_number?(test_case) != expected_answer
              puts "**regex_is_number? got #{test_case} wrong**"
              else
              puts "regex_is_number? got #{test_case} right"
              end
              end
              end


              Here is the output of the test cases:



              rescue_is_number? got 5.5 right
              regex_is_number? got 5.5 right
              rescue_is_number? got 23 right
              regex_is_number? got 23 right
              rescue_is_number? got -123 right
              regex_is_number? got -123 right
              **rescue_is_number? got 1,234,123 wrong**
              regex_is_number? got 1,234,123 right
              rescue_is_number? got hello right
              regex_is_number? got hello right
              rescue_is_number? got 99designs right
              regex_is_number? got 99designs right
              rescue_is_number? got (123)456-7890 right
              regex_is_number? got (123)456-7890 right


              Time to do some performance benchmarks:



              Benchmark.ips do |x|

              x.report("rescue") { test_cases.values.flatten.each { |c| rescue_is_number? c } }
              x.report("regex") { test_cases.values.flatten.each { |c| regex_is_number? c } }

              x.compare!
              end


              And the results:



              Calculating -------------------------------------
              rescue 128.000 i/100ms
              regex 4.649k i/100ms
              -------------------------------------------------
              rescue 1.348k (±16.8%) i/s - 6.656k
              regex 52.113k (± 7.8%) i/s - 260.344k

              Comparison:
              regex: 52113.3 i/s
              rescue: 1347.5 i/s - 38.67x slower






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Feb 19 '16 at 23:07









              pthammpthamm

              1,5421814




              1,5421814













              • Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

                – Jodi
                Feb 24 '16 at 16:27






              • 1





                Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

                – James Moore
                Feb 25 '17 at 18:59



















              • Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

                – Jodi
                Feb 24 '16 at 16:27






              • 1





                Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

                – James Moore
                Feb 25 '17 at 18:59

















              Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

              – Jodi
              Feb 24 '16 at 16:27





              Thanks for the benchmark. The accepted answer has the advantage of accepting inputs like 5.4e-29. I guess your regex could be tweaked to accept those also.

              – Jodi
              Feb 24 '16 at 16:27




              1




              1





              Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

              – James Moore
              Feb 25 '17 at 18:59





              Handling cases like 1,000 is really hard, since it depends on user intention. There are many, many ways for humans to format numbers. Is 1,000 about equal to 1000, or about equal to 1? Most of the world says it's about 1, not a way to show the integer 1000.

              – James Moore
              Feb 25 '17 at 18:59











              4














              this is how i do it, but i think too there must be a better way



              object.to_i.to_s == object || object.to_f.to_s == object





              share|improve this answer



















              • 4





                It does not recognize floating notation, e.g. 1.2e+35.

                – hipertracker
                Jul 25 '12 at 16:13
















              4














              this is how i do it, but i think too there must be a better way



              object.to_i.to_s == object || object.to_f.to_s == object





              share|improve this answer



















              • 4





                It does not recognize floating notation, e.g. 1.2e+35.

                – hipertracker
                Jul 25 '12 at 16:13














              4












              4








              4







              this is how i do it, but i think too there must be a better way



              object.to_i.to_s == object || object.to_f.to_s == object





              share|improve this answer













              this is how i do it, but i think too there must be a better way



              object.to_i.to_s == object || object.to_f.to_s == object






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Apr 14 '11 at 9:58









              antpawantpaw

              10k84278




              10k84278








              • 4





                It does not recognize floating notation, e.g. 1.2e+35.

                – hipertracker
                Jul 25 '12 at 16:13














              • 4





                It does not recognize floating notation, e.g. 1.2e+35.

                – hipertracker
                Jul 25 '12 at 16:13








              4




              4





              It does not recognize floating notation, e.g. 1.2e+35.

              – hipertracker
              Jul 25 '12 at 16:13





              It does not recognize floating notation, e.g. 1.2e+35.

              – hipertracker
              Jul 25 '12 at 16:13











              4














              In rails 4, you need to put
              require File.expand_path('../../lib', __FILE__) + '/ext/string'
              in your config/application.rb






              share|improve this answer



















              • 1





                actually you don't need to do this, you could just put string.rb in "initializers" and it works!

                – mahatmanich
                Jun 16 '14 at 8:32











              • That's it! so cool!

                – zx1986
                Jul 7 '17 at 6:14
















              4














              In rails 4, you need to put
              require File.expand_path('../../lib', __FILE__) + '/ext/string'
              in your config/application.rb






              share|improve this answer



















              • 1





                actually you don't need to do this, you could just put string.rb in "initializers" and it works!

                – mahatmanich
                Jun 16 '14 at 8:32











              • That's it! so cool!

                – zx1986
                Jul 7 '17 at 6:14














              4












              4








              4







              In rails 4, you need to put
              require File.expand_path('../../lib', __FILE__) + '/ext/string'
              in your config/application.rb






              share|improve this answer













              In rails 4, you need to put
              require File.expand_path('../../lib', __FILE__) + '/ext/string'
              in your config/application.rb







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered May 19 '14 at 4:57









              jcyejcye

              515




              515








              • 1





                actually you don't need to do this, you could just put string.rb in "initializers" and it works!

                – mahatmanich
                Jun 16 '14 at 8:32











              • That's it! so cool!

                – zx1986
                Jul 7 '17 at 6:14














              • 1





                actually you don't need to do this, you could just put string.rb in "initializers" and it works!

                – mahatmanich
                Jun 16 '14 at 8:32











              • That's it! so cool!

                – zx1986
                Jul 7 '17 at 6:14








              1




              1





              actually you don't need to do this, you could just put string.rb in "initializers" and it works!

              – mahatmanich
              Jun 16 '14 at 8:32





              actually you don't need to do this, you could just put string.rb in "initializers" and it works!

              – mahatmanich
              Jun 16 '14 at 8:32













              That's it! so cool!

              – zx1986
              Jul 7 '17 at 6:14





              That's it! so cool!

              – zx1986
              Jul 7 '17 at 6:14











              3














              If you prefer not to use exceptions as part of the logic, you might try this:



              class String
              def numeric?
              !!(self =~ /^-?d+(.d*)?$/)
              end
              end


              Or, if you want it to work across all object classes, replace class String with class Object an convert self to a string: !!(self.to_s =~ /^-?d+(.d*)?$/)






              share|improve this answer


























              • Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

                – Arnold Roa
                Apr 11 '17 at 14:37











              • Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

                – Mark Schneider
                Apr 13 '17 at 2:52
















              3














              If you prefer not to use exceptions as part of the logic, you might try this:



              class String
              def numeric?
              !!(self =~ /^-?d+(.d*)?$/)
              end
              end


              Or, if you want it to work across all object classes, replace class String with class Object an convert self to a string: !!(self.to_s =~ /^-?d+(.d*)?$/)






              share|improve this answer


























              • Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

                – Arnold Roa
                Apr 11 '17 at 14:37











              • Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

                – Mark Schneider
                Apr 13 '17 at 2:52














              3












              3








              3







              If you prefer not to use exceptions as part of the logic, you might try this:



              class String
              def numeric?
              !!(self =~ /^-?d+(.d*)?$/)
              end
              end


              Or, if you want it to work across all object classes, replace class String with class Object an convert self to a string: !!(self.to_s =~ /^-?d+(.d*)?$/)






              share|improve this answer















              If you prefer not to use exceptions as part of the logic, you might try this:



              class String
              def numeric?
              !!(self =~ /^-?d+(.d*)?$/)
              end
              end


              Or, if you want it to work across all object classes, replace class String with class Object an convert self to a string: !!(self.to_s =~ /^-?d+(.d*)?$/)







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Apr 13 '17 at 2:50

























              answered Jun 7 '13 at 4:20









              Mark SchneiderMark Schneider

              13519




              13519













              • Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

                – Arnold Roa
                Apr 11 '17 at 14:37











              • Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

                – Mark Schneider
                Apr 13 '17 at 2:52



















              • Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

                – Arnold Roa
                Apr 11 '17 at 14:37











              • Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

                – Mark Schneider
                Apr 13 '17 at 2:52

















              Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

              – Arnold Roa
              Apr 11 '17 at 14:37





              Whats the purpose of negate and do nil? zero is trurthy on ruby, so you can do just !!(self =~ /^-?d+(.d*)?$/)

              – Arnold Roa
              Apr 11 '17 at 14:37













              Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

              – Mark Schneider
              Apr 13 '17 at 2:52





              Using !! certainly works. At least one Ruby style guide (github.com/bbatsov/ruby-style-guide) suggested avoiding !! in favor of .nil? for readability, but I've seen !! used in popular repositories, and I think it is a fine way to convert to boolean. I've edited the answer.

              – Mark Schneider
              Apr 13 '17 at 2:52











              0














              As of Ruby 2.6.0, the numeric cast-methods have an optional exception-argument [1]. This enables us to use the built-in methods without using exceptions as control flow:



              Float('x') # => ArgumentError (invalid value for Float(): "x")
              Float('x', exception: false) # => nil


              Therefore, you don't have to define your own method, but can directly check variables like e.g.



              if Float(my_var, exception: false)
              # do something if my_var is a float
              end





              share|improve this answer




























                0














                As of Ruby 2.6.0, the numeric cast-methods have an optional exception-argument [1]. This enables us to use the built-in methods without using exceptions as control flow:



                Float('x') # => ArgumentError (invalid value for Float(): "x")
                Float('x', exception: false) # => nil


                Therefore, you don't have to define your own method, but can directly check variables like e.g.



                if Float(my_var, exception: false)
                # do something if my_var is a float
                end





                share|improve this answer


























                  0












                  0








                  0







                  As of Ruby 2.6.0, the numeric cast-methods have an optional exception-argument [1]. This enables us to use the built-in methods without using exceptions as control flow:



                  Float('x') # => ArgumentError (invalid value for Float(): "x")
                  Float('x', exception: false) # => nil


                  Therefore, you don't have to define your own method, but can directly check variables like e.g.



                  if Float(my_var, exception: false)
                  # do something if my_var is a float
                  end





                  share|improve this answer













                  As of Ruby 2.6.0, the numeric cast-methods have an optional exception-argument [1]. This enables us to use the built-in methods without using exceptions as control flow:



                  Float('x') # => ArgumentError (invalid value for Float(): "x")
                  Float('x', exception: false) # => nil


                  Therefore, you don't have to define your own method, but can directly check variables like e.g.



                  if Float(my_var, exception: false)
                  # do something if my_var is a float
                  end






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 3 at 12:59









                  TimitryTimitry

                  431614




                  431614























                      -2














                      use the following function:



                      def is_numeric? val
                      return val.try(:to_f).try(:to_s) == val
                      end


                      so,



                      is_numeric? "1.2f" = false



                      is_numeric? "1.2" = true



                      is_numeric? "12f" = false



                      is_numeric? "12" = true






                      share|improve this answer
























                      • This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                        – GMA
                        Sep 17 '15 at 12:51











                      • In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                        – GMA
                        Sep 17 '15 at 12:52
















                      -2














                      use the following function:



                      def is_numeric? val
                      return val.try(:to_f).try(:to_s) == val
                      end


                      so,



                      is_numeric? "1.2f" = false



                      is_numeric? "1.2" = true



                      is_numeric? "12f" = false



                      is_numeric? "12" = true






                      share|improve this answer
























                      • This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                        – GMA
                        Sep 17 '15 at 12:51











                      • In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                        – GMA
                        Sep 17 '15 at 12:52














                      -2












                      -2








                      -2







                      use the following function:



                      def is_numeric? val
                      return val.try(:to_f).try(:to_s) == val
                      end


                      so,



                      is_numeric? "1.2f" = false



                      is_numeric? "1.2" = true



                      is_numeric? "12f" = false



                      is_numeric? "12" = true






                      share|improve this answer













                      use the following function:



                      def is_numeric? val
                      return val.try(:to_f).try(:to_s) == val
                      end


                      so,



                      is_numeric? "1.2f" = false



                      is_numeric? "1.2" = true



                      is_numeric? "12f" = false



                      is_numeric? "12" = true







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Dec 22 '14 at 12:19









                      Rajesh PaulRajesh Paul

                      3,88562743




                      3,88562743













                      • This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                        – GMA
                        Sep 17 '15 at 12:51











                      • In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                        – GMA
                        Sep 17 '15 at 12:52



















                      • This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                        – GMA
                        Sep 17 '15 at 12:51











                      • In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                        – GMA
                        Sep 17 '15 at 12:52

















                      This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                      – GMA
                      Sep 17 '15 at 12:51





                      This will fail if val is "0". Also note that the method .try isn't part of the Ruby core library and is only available if you're including ActiveSupport.

                      – GMA
                      Sep 17 '15 at 12:51













                      In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                      – GMA
                      Sep 17 '15 at 12:52





                      In fact, it also fails for "12", so your fourth example in this question is wrong. "12.10" and "12.00" fail too.

                      – GMA
                      Sep 17 '15 at 12:52











                      -5














                      How dumb is this solution?



                      def is_number?(i)
                      begin
                      i+0 == i
                      rescue TypeError
                      false
                      end
                      end





                      share|improve this answer



















                      • 1





                        This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                        – Sqeaky
                        Apr 28 '14 at 17:17
















                      -5














                      How dumb is this solution?



                      def is_number?(i)
                      begin
                      i+0 == i
                      rescue TypeError
                      false
                      end
                      end





                      share|improve this answer



















                      • 1





                        This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                        – Sqeaky
                        Apr 28 '14 at 17:17














                      -5












                      -5








                      -5







                      How dumb is this solution?



                      def is_number?(i)
                      begin
                      i+0 == i
                      rescue TypeError
                      false
                      end
                      end





                      share|improve this answer













                      How dumb is this solution?



                      def is_number?(i)
                      begin
                      i+0 == i
                      rescue TypeError
                      false
                      end
                      end






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Oct 6 '13 at 12:16









                      donvnielsendonvnielsen

                      837




                      837








                      • 1





                        This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                        – Sqeaky
                        Apr 28 '14 at 17:17














                      • 1





                        This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                        – Sqeaky
                        Apr 28 '14 at 17:17








                      1




                      1





                      This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                      – Sqeaky
                      Apr 28 '14 at 17:17





                      This is sub-optimal because using '.respond_to?(:+)' is always better then failing and catching an exception on a specific method (:+) call. This might also fail for a variety of reasons were the Regex and conversion methods don't.

                      – Sqeaky
                      Apr 28 '14 at 17:17


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5661466%2ftest-if-string-is-a-number-in-ruby-on-rails%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

                      SQL update select statement

                      'app-layout' is not a known element: how to share Component with different Modules