¿Cuáles son las trampas de Rubí de las que un novato debe ser advertido? [cerrado]


Recientemente he aprendido el lenguaje de programación Ruby, y en general es un buen lenguaje. Pero me sorprendió bastante ver que no era tan simple como esperaba. Más precisamente, la" regla de la menor sorpresa " no me pareció muy respetada (por supuesto, esto es bastante subjetivo). Por ejemplo:

x = true and false
puts x  # displays true!

Y los famosos:

puts "zero is true!" if 0  # zero is true!

¿Cuáles son las otras "trampas" sobre las que advertirías a un novato de Ruby?

 103
Author: MiniQuark, 2008-12-16

25 answers

Wikipedia Ruby gotchas

Del artículo:

  • Los nombres que comienzan con una letra mayúscula se tratan como constantes, por lo que las variables locales deben comenzar con una letra minúscula.
  • Los caracteres $ y @ no indican el tipo de datos variables como en Perl, sino que funcionan como operadores de resolución de alcance.
  • Para denotar números en coma flotante, se debe seguir con un dígito cero (99.0) o una conversión explícita (99.to_f). Es insuficiente para añadir un punto (99.), porque los números son susceptibles a la sintaxis del método.
  • La evaluación booleana de datos no booleanos es estricta: 0, "" y [] son todos evaluados a true. En C, la expresión 0 ? 1 : 0 se evalúa como 0 (es decir, false). En Ruby, sin embargo, rinde 1, ya que todos los números evalúan a true; solo nil y false evalúan a false. Un corolario de esta regla es que los métodos Ruby por convención-por ejemplo, búsquedas de expresiones regulares - devuelven números, cadenas, listas u otros valores no falsos en caso de éxito, pero nil en caso de error (p. ej., desajuste). Esta convención también se usa en Smalltalk, donde solo los objetos especiales true y false se pueden usar en una expresión booleana.
  • Las versiones anteriores a la 1.9 carecen de un tipo de datos de caracteres (en comparación con C, que proporciona el tipo char para los caracteres). Esto puede causar sorpresas al cortar cadenas: "abc"[0] produce 97 (un entero, que representa el código ASCII del primer carácter en el string); para obtener "a" use "abc"[0,1] (una subcadena de longitud 1) o "abc"[0].chr.
  • La notación statement until expression, a diferencia de las declaraciones equivalentes de otros lenguajes (por ejemplo, do { statement } while (not(expression)); en C/C++/...), en realidad nunca ejecuta la sentencia si la expresión ya es true. Esto es porque statement until expression es en realidad azúcar sintáctica sobre

    until expression
      statement
    end
    

    , cuyo equivalente en C / C++ es while (not(expression)) statement; al igual que statement if expression es un equivalente a

    if expression
      statement
    end
    

    Sin embargo, la notación

    begin
      statement
    end until expression
    

    En Ruby se fact ejecute la sentencia una vez incluso si la expresión ya es verdadera.

  • Debido a que las constantes son referencias a objetos, cambiar a lo que una constante se refiere genera una advertencia, pero modificar el objeto en sí no lo hace. Por ejemplo, Greeting << " world!" if Greeting == "Hello" no genera un error o una advertencia. Esto es similar a las variables final en Java, pero Ruby también tiene la funcionalidad de "congelar" un objeto, a diferencia de Java.

Algunas características que difieren notablemente de otras idiomas:

  • Los operadores usuales para expresiones condicionales, and y or, no siguen las reglas normales de precedencia: and no enlaza más fuerte que or. Ruby también tiene operadores de expresión || y && que funcionan como se espera.

  • def inside def no hace lo que un programador Python podría esperar:

    def a_method
        x = 7
        def print_x; puts x end
        print_x
    end
    

    Esto da un error acerca de que x no está definido. Necesita usar un Proc.

Idioma características

  • La omisión de paréntesis alrededor de los argumentos del método puede conducir a resultados inesperados si los métodos toman múltiples parámetros. Los desarrolladores de Ruby han declarado que la omisión de paréntesis en los métodos multiparamétricos puede ser rechazada en futuras versiones de Ruby; el intérprete Ruby actual (noviembre de 2007) lanza una advertencia que anima al escritor a no omitir (), para evitar un significado ambiguo del código. No usar () sigue siendo una práctica común, y puede ser especialmente agradable para utilice Ruby como un lenguaje de programación específico de dominio legible por humanos, junto con el método llamado method_missing().
 56
Author: Andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-07 15:54:34

Los novatos tendrán problemas con métodos de igualdad :

  • a == b: comprueba si a y b son iguales. Este es el más útil.
  • a.eql? b : también comprueba si a y b son iguales, pero a veces es más estricto (puede comprobar que a y b tienen el mismo tipo, por ejemplo). Se utiliza principalmente en Hashes.
  • a. ¿igual? b : comprueba si a y b son el mismo objeto (comprobación de identidad).
  • a === b : usado en las declaraciones de caso (lo leo como " a coincide con b ").

Estos ejemplos deberían aclarar los primeros 3 métodos:

a = b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # true (a.object_id == b.object_id)

a = "joe"
b = "joe"

a==b       # true
a.eql? b   # true
a.equal? b # false (a.object_id != b.object_id)

a = 1
b = 1.0

a==b       # true
a.eql? b   # false (a.class != b.class)
a.equal? b # false

Tenga en cuenta que ==, eql? y igual? siempre debe ser simétrico: si a==b entonces b==a.

También tenga en cuenta que == y eql? se implementan ambos en el Objeto de clase como alias a igual?, así que si crea una nueva clase y desea == y eql? para significar algo más que simple identidad, entonces necesitas anularlos a ambos. Por ejemplo:

class Person
    attr_reader name
    def == (rhs)
      rhs.name == self.name  # compare person by their name
    end
    def eql? (rhs)
      self == rhs
    end
    # never override the equal? method!
end

El === el método se comporta de manera diferente. Primero de todo es no simétrica (a===b ¿ no implica que b===a). Como dije, puedes leer a = = = b como "a coincide con b". He aquí algunos ejemplos:

# === is usually simply an alias for ==
"joe" === "joe"  # true
"joe" === "bob"  # false

# but ranges match any value they include
(1..10) === 5        # true
(1..10) === 19       # false
(1..10) === (1..10)  # false (the range does not include itself)

# arrays just match equal arrays, but they do not match included values!
[1,2,3] === [1,2,3] # true
[1,2,3] === 2       # false

# classes match their instances and instances of derived classes
String === "joe"   # true
String === 1.5     # false (1.5 is not a String)
String === String  # false (the String class is not itself a String)

La declaración case se basa en === método:

case a
  when "joe": puts "1"
  when 1.0  : puts "2"
  when (1..10), (15..20): puts "3"
  else puts "4"
end

Es equivalente a esto:

if "joe" === a
  puts "1"
elsif 1.0 === a
  puts "2"
elsif (1..10) === a || (15..20) === a
  puts "3"
else
  puts "4"
end

Si define una nueva clase cuyas instancias representar algún tipo de contenedor o rango (si tiene algo como un include?o una coincidencia? método), entonces usted podría encontrar útil para anular el === método como este:

class Subnet
  [...]
  def include? (ip_address_or_subnet)
    [...]
  end
  def === (rhs)
    self.include? rhs
  end
end

case destination_ip
  when white_listed_subnet: puts "the ip belongs to the white-listed subnet"
  when black_listed_subnet: puts "the ip belongs to the black-listed subnet"
  [...]
end
 38
Author: MiniQuark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-25 12:19:45
 20
Author: Dan Vinton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-16 22:01:32

El siguiente código me sorprendió. Creo que es una trampa peligrosa: fácil de encontrar y difícil de depurar.

(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

Esto imprime:

1
2 is even
3
4 is even
5

Pero si solo añado comment =cualquier cosa antes del bloque...

comment = nil
(1..5).each do |number|
  comment = " is even" if number%2==0
  puts number.to_s + comment.to_s
end

Entonces obtengo:

1
2 is even
3 is even
4 is even
5 is even

Básicamente, cuando una variable solo se define dentro de un bloque, entonces se destruye al final del bloque, y luego se restablece a nil en cada iteración. Eso es normalmente lo que esperas. Pero si la variable se define antes del bloque, entonces la variable externa se usa dentro del bloque, y su valor es por lo tanto persistente entre iteraciones.

Una solución sería escribir esto en su lugar:

comment = number%2==0 ? " is even" : nil

Creo que mucha gente (incluyéndome) tiende a escribir "a = b if c" en lugar de "a = (c ? b : nil)", porque es más legible, pero obviamente tiene efectos secundarios.

 18
Author: MiniQuark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-13 19:01:00

Cuando se llama a super sin argumentos, el método sobreescrito se llama realmente con los mismos argumentos que el método sobreescrito.

class A
  def hello(name="Dan")
    puts "hello #{name}"
  end
end

class B < A
  def hello(name)
    super
  end
end

B.new.hello("Bob") #=> "hello Bob"

Para llamar realmente a super sin argumentos, debe decir super().

 16
Author: Daniel Lucraft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 08:27:14

Los bloques y métodos devuelven el valor de la última línea por defecto. Agregar puts instrucciones al final para fines de depuración puede causar efectos secundarios desagradables

 14
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-11 14:11:25
 13
Author: John Topley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-16 21:06:36

Tuve muchos problemas para entender las variables de clase, los atributos de clase y los métodos de clase. Este código podría ayudar a un novato:

class A
  @@classvar = "A1"
  @classattr = "A2"
  def self.showvars
    puts "@@classvar => "+@@classvar
    puts "@classattr => "+@classattr
  end
end

A.showvars
  # displays:
  # @@classvar => A1
  # @classattr => A2

class B < A
  @@classvar = "B1"
  @classattr = "B2"
end

B.showvars
  # displays:
  # @@classvar => B1
  # @classattr => B2

A.showvars
  # displays:
  # @@classvar => B1   #Class variables are shared in a class hierarchy!
  # @classattr => A2   #Class attributes are not
 11
Author: MiniQuark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 10:13:20

Una cosa que aprendí fue a usar el operador ||= con cuidado. y tenga especial cuidado si usted está tratando con booleanos. usualmente usé a / / = b como un catch all para dar a ' a 'un valor por defecto si todo lo demás fallaba y' a ' permanecía nil. pero si a es falso y b es verdadero, entonces a será asignado verdadero.

 8
Author: karina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-18 21:04:31
  • Los bloques son muy importantes de entender, se usan en todas partes.

  • No necesita paréntesis alrededor de los parámetros del método. Si los usa o no depende de usted. Algunos dicen que siempre debes usarlas .

  • Utilice raise y rescue para el manejo de excepciones, no lanzar y atrapar.

  • Puedes usar ; pero no tienes que hacerlo a menos que quieras poner varias cosas en una línea.

 8
Author: dylanfm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-09 22:17:57

Tuve problemas con los mixins que contienen métodos de instancia y métodos de clase. Este código podría ayudar a un novato:

module Displayable
  # instance methods here
  def display
    puts name
    self.class.increment_displays
  end
  def self.included(base)
    # This module method will be called automatically
    # after this module is included in a class.
    # We want to add the class methods to the class.
    base.extend Displayable::ClassMethods
  end
  module ClassMethods
    # class methods here
    def number_of_displays
      @number_of_displays # this is a class attribute
    end
    def increment_displays
      @number_of_displays += 1
    end
    def init_displays
      @number_of_displays = 0
    end
    # this module method will be called automatically
    # after this module is extended by a class.
    # We want to perform some initialization on a
    # class attribute.
    def self.extended(base)
      base.init_displays
    end
  end
end

class Person
  include Displayable
  def name; @name; end
  def initialize(name); @name=name; end
end

puts Person.number_of_displays # => 0
john = Person.new "John"
john.display # => John
puts Person.number_of_displays # => 1
jack = Person.new "Jack"
jack.display # => Jack
puts Person.number_of_displays # => 2

Al principio, pensé que podría tener módulos con ambos métodos de instancia y métodos de clase simplemente haciendo esto:

module Displayable
  def display
    puts name
    self.class.increment_displays
  end
  def self.number_of_displays  # WRONG!
    @number_of_displays
  end
  [...]
end

Desafortunadamente, method number_of_displays nunca se incluirá o extenderá porque es un "método de clase de módulo". Solo "module instance methods" se puede incluir en una clase (como métodos de instancia) o extendido en una clase (como métodos de clase). Esta es la razón por la que necesitas poner los métodos de instancia de tu mixin en un módulo, y los métodos de clase de tu mixin en otro módulo (normalmente pones los métodos de clase en un submódulo "ClassMethods"). Gracias al método mágico included , puede facilitar la inclusión de métodos de instancia y métodos de clase en una sola llamada "include Displayable" (como se muestra en el ejemplo anterior).

Este mixin contará cada pantalla en un por clase base. El contador es un atributo de clase, por lo que cada clase tendrá su propio (su programa probablemente fallará si deriva una nueva clase de la clase Person ya que el contador @number_of_displays para la clase derivada nunca se inicializará). Es posible que desee reemplazar @number_of_displays por @@number_of_displays para hacer un contador global. En este caso, cada jerarquía de clases tendrá su propio contador. Si quieres un entorno global y único contador, probablemente deberías convertirlo en un atributo de módulo.

Todo esto definitivamente no era intuitivo para mí cuando empecé con Ruby.

Todavía no puedo averiguar cómo hacer limpiamente que algunos de estos métodos mixin sean privados o protegidos (solo el método display y number_of_displays debe incluirse como métodos públicos).

 7
Author: MiniQuark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 11:45:25

Preste atención a la notación de rango.

(Al menos, presta más atención que I inicialmente!)

Hay una diferencia entre 0..10 (dos puntos) y 0...10 (tres puntos).

Disfruto mucho de Ruby. Pero esta cosa punto-punto versus punto-punto-punto me molesta. Creo que una "característica" de sintaxis dual tan sutil es:

  • fácil de escribir mal, y
  • fácil de perder con sus ojos mientras mira sobre el código

No debería ser capaz de causar devastadores errores off-by-one en mis programas.

 7
Author: que que,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-03 18:23:57

Creo que "and" y "or" son guiños a Perl, que es uno de los "padres" más obvios de Ruby (el otro más prominente es Smalltalk). Ambos tienen una precedencia mucho menor (menor que la asignación, de hecho, que es de donde proviene el comportamiento observado) que && y || que son los operadores que debe usar.

Otras cosas a tener en cuenta que no son inmediatamente obvias:

Realmente no llamas a métodos/funciones, aunque parece que es así. En cambio, como en Smalltalk, se envía un mensaje a un objeto. Así que method_missing es realmente más como message_not_understood.

some_object.do_something(args)

Es equivalente a

some_object.send(:do_something, args) # note the :

Los símbolos son muy utilizados. Esas son las cosas que comienzan con : y no son obvias de inmediato (bueno, no lo eran para mí), pero cuanto antes te familiarices con ellas, mejor.

Ruby es grande en "escribir pato", siguiendo el principio de que "si camina como un pato y grazna como un pato..."que permite la sustitución informal de objetos con un subconjunto común de métodos sin ninguna herencia explícita o relación mixin.

 6
Author: Mike Woodhouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 09:31:49

Si declara un setter (también conocido como mutador) usando attr_writer o attr_accessor (o def foo=), tenga cuidado de llamarlo desde dentro de la clase. Dado que las variables se declaran implícitamente, el intérprete siempre tiene que resolver foo = bar declarando una nueva variable llamada foo, en lugar de llamar al método self.foo=(bar).

class Thing
  attr_accessor :foo
  def initialize
    @foo = 1      # this sets @foo to 1
    self.foo = 2  # this sets @foo to 2
    foo = 3       # this does *not* set @foo
  end
end

puts Thing.new.foo #=> 2

Esto también se aplica a los objetos Rails ActiveRecord, que obtienen accesores definidos en función de los campos de la base de datos. Dado que ni siquiera son variables de instancia de estilo@, la forma adecuada de establecer esas los valores individualmente son con self.value = 123 o self['value'] = 123.

 6
Author: AlexChaffee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-16 18:21:25

Entendiendo la diferencia entre la clase Hora y Fecha. Ambos son diferentes y han creado problemas al usarlos en rails. La clase Time a veces entra en conflicto con otras bibliotecas de clases Time presentes en la biblioteca ruby/rails estándar. Personalmente me tomó mucho tiempo entender lo que estaba pasando exactamente en mi aplicación rails. Más tarde, pensé que cuando lo hice

Time.new

Se refería a una biblioteca en un lugar que ni siquiera conocía.

Lo siento si soy no está claro lo que quiero decir exactamente. Si otros se han enfrentado a problemas similares, por favor vuelva a explicar.

 5
Author: Chirantan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 02:31:08

Uno que me ha llamado la atención en el pasado es que la secuencia de escape del carácter de nueva línea (\n), entre otros, no es compatible con cadenas entre comillas simples. La barra invertida se escapa. Tienes que usar comillas dobles para que el escape funcione como se espera.

 4
Author: John Topley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-16 20:52:14
x = (true and false) # x is false

0 y " son verdaderas, como usted señaló.

Puede tener un método y un módulo/clase con el mismo nombre (lo cual tiene sentido, porque el método realmente se agrega al Objeto y por lo tanto tiene su propio espacio de nombres).

No hay herencia múltiple, pero con frecuencia los "módulos mixin" se usan para agregar métodos comunes a múltiples clases.

 4
Author: singpolyma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-16 21:46:33

Los métodos pueden ser redefinidos y pueden convertirse en un rascador mental hasta que descubras la causa. (Es cierto que este error es probablemente un poco "más difícil" de detectar cuando la acción de un controlador Ruby on Rails es redefinida por error!)

#demo.rb
class Demo

  def hello1
    p "Hello from first definition"
  end

  # ...lots of code here...
  # and you forget that you have already defined hello1

  def hello1
    p "Hello from second definition"
  end

end
Demo.new.hello1

Ejecutar:

$ ruby demo.rb
=> "Hello from second definition"

Pero llámelo con las advertencias activadas y puede ver la razón:

$ ruby -w demo.rb
demo.rb:10: warning: method redefined; discarding old hello1
=> "Hello from second definition"
 4
Author: Zabba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-01 02:52:05

Creo que siempre es bueno utilizar .longitud en las cosas... dado que el tamaño es soportado por casi todo y Ruby tiene tipos dinámicos, puedes obtener resultados muy extraños llamando .tamaño cuando se tiene el tipo equivocado... Preferiría obtener un NoMethodError: undefined method 'length', por lo que generalmente nunca llamo size a objetos en Ruby.

Me mordió más de una vez.

También recuerdo que los objetos tienen id, así que trato de no usar variables call id o object_id solo para evitar confusiones. Si necesito un id en un objeto Users es mejor llamarlo algo como user_id.

Sólo mis dos centavos

 3
Author: danmayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 18:57:55

Soy nuevo en ruby, y en mi primera ronda me encontré con un problema con respecto al cambio de flotadores/cadenas a un entero. Comencé con los flotadores y codifiqué todo como f.to_int. Pero cuando continué y usé el mismo método para las cadenas me arrojaron una curva cuando se trataba de ejecutar el programa.

Aparentemente una cadena no tiene un método to_int, pero floats e ints sí.

irb(main):003:0* str_val = '5.0'
=> "5.0"
irb(main):006:0> str_val.to_int
NoMethodError: undefined method `to_int' for "5.0":String
        from (irb):6
irb(main):005:0* str_val.to_i
=> 5


irb(main):007:0> float_val = 5.0
=> 5.0
irb(main):008:0> float_val.to_int
=> 5
irb(main):009:0> float_val.to_i
=> 5
irb(main):010:0>

Los paréntesis arbitrarios también me arrojaron al principio. Vi un código con y otro sin. Se me llevó un tiempo darme cuenta de que cualquiera de los estilos son aceptados.

 2
Author: monkut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 10:17:24

Relacionado con la respuesta de monkut, los métodos to_foo de Ruby indican cuán estricta será la conversión.

Cortos como to_i, to_s dile que sea perezoso y conviértelos al tipo de destino incluso si no pueden representarse con precisión en ese formato. Por ejemplo:

"10".to_i == 10
:foo.to_s == "foo"

Las funciones explícitas más largas como to_int, to_s significa que el objeto puede representarse de forma nativa como ese tipo de datos. Por ejemplo, la clase Rational representa todos los números racionales, por lo que puede ser representado directamente como un entero Fixnum (o Bignum) llamando a to_int.

Rational(20,4).to_int == 5

Si no puede llamar al método longer, significa que el objeto no se puede representar de forma nativa en ese tipo.

Así que básicamente, al convertir, si eres perezoso con los nombres de los métodos, Ruby será perezoso con la conversión.

 2
Author: Luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-24 11:54:21

Desde En Ruby ¿por qué no foo = true unless defined?(foo) hacer la asignación?

foo = true unless defined?(foo) #Leaves foo as nil

Porque foo se define como nil cuando se llama defined?(foo).

 2
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:33

La iteración sobre los hashes de ruby no está garantizada en ningún orden en particular. (No es un error, es una característica)

Hash#sort es útil si necesita un pedido en particular.

Pregunta relacionada: ¿Por qué la matriz de Ruby de 1000 pares de clave y valor de hashes siempre está en un orden particular?

 1
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:09:36

Este me volvió loco una vez:

1/2 == 0.5 #=> false
1/2 == 0   #=> true
 0
Author: Andrei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-09 16:39:30
1..5.each {|x| puts x}

No funciona. Tienes que poner el rango entre paréntesis, como

(1..5).each {|x| puts x}

Así que no cree que estés llamando 5.each. Creo que este es un tema de precedencia, al igual que el x = true and false gotcha.

 0
Author: Andrew Grimm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-09 22:17:16