В моем контроллере приложения есть следующее:
def is_number?(object)
true if Float(object) rescue false
end
и следующее условие в моем контроллере:
if mystring.is_number?
end
Состояние вызывает undefined method
ошибку. Я предполагаю, что определил не is_number
в том месте ...?
ruby-on-rails
ruby
string
integer
Джейми Бьюкенен
источник
источник
Ответы:
Создать
is_number?
метод.Создайте вспомогательный метод:
А потом назовите это так:
Расширить
String
класс.Если вы хотите иметь возможность вызывать
is_number?
непосредственно строку вместо того, чтобы передавать ее в качестве параметра вашей вспомогательной функции, вам необходимо определитьis_number?
как расширениеString
класса, например:И тогда вы можете вызвать это с помощью:
источник
to_f
приведенном выше нет, и Float () не демонстрирует такого поведения:Float("330.346.11")
raisesArgumentError: invalid value for Float(): "330.346.11"
lib/core_ext/string.rb
.is_number?(string)
работает с Ruby 1.9. Может быть, это часть Rails или 1.8?String.is_a?(Numeric)
работает. См. Также stackoverflow.com/questions/2095493/… .Вот эталон распространенных способов решения этой проблемы. Обратите внимание, какой из них вам следует использовать, вероятно, зависит от ожидаемого количества ложных случаев.
Если производительность не имеет значения, используйте то, что вам нравится. :-)
Детали проверки целых чисел:
Детали проверки поплавка:
источник
источник
/^\d+$/
не является безопасным регулярным выражением в Ruby,/\A\d+\Z/
это. (например, "42 \ nsome text" вернетсяtrue
)/^\d+$/
при работе со строками, но в этом случае речь идет о начале и конце строки, таким образом/\A\d+\Z/
.Полагаться на возникшее исключение - не самое быстрое, удобочитаемое и надежное решение.
Я бы сделал следующее:
источник
expect(my_string).to match(/^[0-9]+$/)
my_string =~ /\A-?(\d+)?\.?\d+\Z/
он позволяет делать «.1», «-0,1» или «12», но не «», или «-», или «».Начиная с Ruby 2.6.0, числовые методы преобразования имеют необязательный
exception
аргумент [1] . Это позволяет нам использовать встроенные методы без использования исключений в качестве потока управления:Следовательно, вам не нужно определять свой собственный метод, но вы можете напрямую проверять такие переменные, как, например,
источник
вот как я это делаю, но я тоже думаю, что должен быть способ получше
источник
object = "1.2e+35"; object.to_f.to_s == object
и это сработалонет, ты просто неправильно его используешь. ваш is_number? есть аргумент. вы назвали это без аргументов
вы должны делать is_number? (mystring)
источник
mystring
действительно String,mystring.is_a?(Integer)
всегда будет false. Похоже, он хочет результата вродеis_number?("12.4") #=> true
Tl; dr: используйте подход регулярного выражения. Это в 39 раз быстрее, чем метод спасения в принятом ответе, а также обрабатывает такие случаи, как «1000».
-
Принятый ответ @Jakob S работает по большей части, но перехват исключений может быть очень медленным. Кроме того, метод спасения не работает на строке типа «1000».
Определим методы:
А теперь несколько тестовых примеров:
И немного кода для запуска тестовых случаев:
Вот результат тестов:
Пришло время сделать несколько тестов производительности:
И результаты:
источник
5.4e-29
. Я предполагаю, что ваше регулярное выражение можно настроить, чтобы принять и их.В rails 4 вам нужно поместить
require File.expand_path('../../lib', __FILE__) + '/ext/string'
в свой config / application.rbисточник
Если вы предпочитаете не использовать исключения как часть логики, вы можете попробовать следующее:
Или, если вы хотите , чтобы работать по всем классам объектов, заменить
class String
сclass Object
на новообращенной себя в строку:!!(self.to_s =~ /^-?\d+(\.\d*)?$/)
источник
nil?
обнуления, это правда на Ruby, так что вы можете сделать просто!!(self =~ /^-?\d+(\.\d*)?$/)
!!
конечно работает. По крайней мере, в одном руководстве по стилю Ruby ( github.com/bbatsov/ruby-style-guide ) предлагалось избегать!!
в пользу.nil?
удобочитаемости, но я видел, как он!!
используется в популярных репозиториях, и я думаю, что это прекрасный способ преобразования в логическое значение. Я отредактировал ответ.используйте следующую функцию:
так,
is_numeric? "1.2f"
= ложьis_numeric? "1.2"
= правдаis_numeric? "12f"
= ложьis_numeric? "12"
= правдаисточник
"0"
. Также обратите внимание, что этот метод.try
не является частью основной библиотеки Ruby и доступен только в том случае, если вы включаете ActiveSupport."12"
, поэтому ваш четвертый пример в этом вопросе неверен."12.10"
и"12.00"
тоже потерпят неудачу.Насколько глупо это решение?
источник