Tengo lo siguiente en mi controlador de aplicación:
def is_number?(object)
true if Float(object) rescue false
end
y la siguiente condición en mi controlador:
if mystring.is_number?
end
La condición arroja un undefined method
error. ¿Supongo que lo he definido is_number
en el lugar equivocado ...?
ruby-on-rails
ruby
string
integer
Jamie Buchanan
fuente
fuente
Respuestas:
Crear
is_number?
método.Crea un método auxiliar:
Y luego llámalo así:
Ampliar
String
clase.Si desea poder llamar
is_number?
directamente a la cadena en lugar de pasarla como un parámetro a su función auxiliar, debe definiris_number?
como una extensión de laString
clase, así:Y luego puedes llamarlo con:
fuente
to_f
en lo anterior, y Float () no exhibe ese comportamiento:Float("330.346.11")
aumentaArgumentError: invalid value for Float(): "330.346.11"
lib/core_ext/string.rb
.is_number?(string)
bit funcione Ruby 1.9. ¿Quizás eso es parte de Rails o 1.8?String.is_a?(Numeric)
trabajos. Consulte también stackoverflow.com/questions/2095493/… .Aquí hay un punto de referencia para las formas comunes de abordar este problema. Tenga en cuenta cuál debe usar probablemente depende de la proporción de casos falsos esperados.
Si el rendimiento no importa, usa lo que te gusta. :-)
Detalles de verificación de enteros:
Detalles de verificación de flotación:
fuente
fuente
/^\d+$/
no es una expresión regular segura en Ruby, sí/\A\d+\Z/
. (por ejemplo, "42 \ nalgo de texto" volveríatrue
)/^\d+$/
si se trata de líneas, pero en este caso se trata del comienzo y el final de una cadena, por lo tanto/\A\d+\Z/
.Confiar en la excepción planteada no es la solución más rápida, legible ni confiable.
Haría lo siguiente:
fuente
expect(my_string).to match(/^[0-9]+$/)
my_string =~ /\A-?(\d+)?\.?\d+\Z/
te permite hacer '.1', '-0.1' o '12' pero no '' o '-' o '.'A partir de Ruby 2.6.0, los métodos de
exception
conversión numéricos tienen un argumento opcional [1] . Esto nos permite usar los métodos integrados sin usar excepciones como flujo de control:Por lo tanto, no tiene que definir su propio método, pero puede verificar directamente variables como, por ejemplo,
fuente
así es como lo hago, pero creo que también debe haber una mejor manera
fuente
object = "1.2e+35"; object.to_f.to_s == object
y funcionóno, solo lo estás usando mal. tu es_number? tiene un argumento. lo llamaste sin el argumento
deberías estar haciendo is_number? (mystring)
fuente
mystring
es un String,mystring.is_a?(Integer)
siempre será falso. Parece que quiere un resultado comois_number?("12.4") #=> true
Tl; dr: use un enfoque de expresiones regulares. Es 39 veces más rápido que el enfoque de rescate en la respuesta aceptada y también maneja casos como "1,000"
-
La respuesta aceptada por @Jakob S funciona en su mayor parte, pero detectar excepciones puede ser muy lento. Además, el enfoque de rescate falla en una cadena como "1,000".
Definamos los métodos:
Y ahora algunos casos de prueba:
Y un pequeño código para ejecutar los casos de prueba:
Aquí está el resultado de los casos de prueba:
Es hora de hacer algunas evaluaciones comparativas de rendimiento:
Y los resultados:
fuente
5.4e-29
. Supongo que su expresión regular podría modificarse para aceptarlos también.En rails 4, debe
require File.expand_path('../../lib', __FILE__) + '/ext/string'
ingresar su config / application.rbfuente
Si prefiere no usar excepciones como parte de la lógica, puede intentar esto:
O, si desea que funcione en todas las clases de objetos, reemplácelo
class String
conclass Object
un convert self en una cadena:!!(self.to_s =~ /^-?\d+(\.\d*)?$/)
fuente
nil?
cero es trurthy en ruby, para que pueda hacerlo solo?!!(self =~ /^-?\d+(\.\d*)?$/)
!!
ciertamente funciona. Al menos una guía de estilo de Ruby ( github.com/bbatsov/ruby-style-guide ) sugirió evitar!!
a favor de la.nil?
legibilidad, pero he visto que se!!
usa en repositorios populares, y creo que es una buena manera de convertir a booleano. Edité la respuesta.usa la siguiente función:
entonces,
is_numeric? "1.2f"
= falsois_numeric? "1.2"
= verdaderois_numeric? "12f"
= falsois_numeric? "12"
= verdaderofuente
"0"
. También tenga en cuenta que el método.try
no forma parte de la biblioteca principal de Ruby y solo está disponible si incluye ActiveSupport."12"
, por lo que su cuarto ejemplo en esta pregunta es incorrecto."12.10"
y"12.00"
fallar también.¿Qué tan tonta es esta solución?
fuente