este problema se puede abordar de variadas maneras, sin embargo te enseñamos la respuesta más completa para nosotros.
Solución:
Utilizar rand(range)
De los números aleatorios de Ruby:
Si necesitara un número entero aleatorio para simular una tirada de un dado de seis caras, usaría:
1 + rand(6)
. Se podría simular una tirada de dados con2 + rand(6) + rand(6)
.Finalmente, si solo necesita un flotador aleatorio, simplemente llame
rand
sin argumentos.
Como Marc-André Lafortune menciona en su respuesta a continuación (ir a votar), Ruby 1.9.2 tiene su propio Random
class (que el propio Marc-André ayudó a depurar, de ahí el objetivo 1.9.2 para esa función).
Por ejemplo, en este juego donde necesitas adivinar 10 números, puedes inicializarlos con:
10.times.map 20 + Random.rand(11)
#=> [26, 26, 22, 20, 30, 26, 23, 23, 25, 22]
Nota:
-
Utilizando
Random.new.rand(20..30)
(utilizandoRandom.new
) generalmente no sería una buena idea, como explica en detalle (nuevamente) Marc-André Lafortune, en su respuesta (nuevamente). -
Pero si no usas
Random.new
entonces el método de claserand
solo toma unmax
valor, no unRange
como señala banister (enérgicamente) en el comentario (y como se documenta en los documentos paraRandom
). Sólo el método de instancia puede tomar unaRange
como se ilustra en generar un número aleatorio con 7 dígitos.
Por eso el equivalente de Random.new.rand(20..30)
sería 20 + Random.rand(11)
ya que Random.rand(int)
devuelve “un entero aleatorio mayor o igual a cero y menos que el argumento.” 20..30
incluye 30, necesito encontrar un número aleatorio entre 0 y 11, excluyendo 11.
Si bien puedes usar rand(42-10) + 10
para obtener un número aleatorio entre 10
y 42
(donde 10 es inclusivo y 42 exclusivo), hay una mejor manera desde Ruby 1.9.3, donde puedes llamar:
rand(10...42) # => 13
Disponible para todas las versiones de Ruby al requerir mi backports
joya.
Ruby 1.9.2 también introdujo la Random
class para que pueda crear sus propios objetos generadores de números aleatorios y tiene una buena API:
r = Random.new
r.rand(10...42) # => 22
r.bytes(3) # => "rnd"
los Random
la clase en sí misma actúa como un generador aleatorio, por lo que llama directamente:
Random.rand(10...42) # => same as rand(10...42)
Notas sobre Random.new
En la mayoría de los casos, lo más sencillo es utilizar rand
o Random.rand
. Crear un nuevo generador aleatorio cada vez que desee un número aleatorio es un muy mala idea. Si hace esto, obtendrá las propiedades aleatorias del algoritmo de siembra inicial que son atroces en comparación con las propiedades del generador aleatorio en sí.
Si utiliza Random.new
así deberías llamarlo tan raramente como sea posiblepor ejemplo una vez como MyApp::Random = Random.new
y úsalo en cualquier otro lugar.
Los casos donde Random.new
es útil son los siguientes:
- estás escribiendo una joya y no quieres interferir con la secuencia de
rand
/Random.rand
que los principales programas podrían depender de - desea secuencias reproducibles separadas de números aleatorios (digamos uno por hilo)
- desea poder guardar y reanudar una secuencia reproducible de números aleatorios (fácil como
Random
los objetos pueden ordenarse)
Si no solo está buscando un número, sino también hexadecimal o uuid, vale la pena mencionar que el SecureRandom
módulo encontró su camino desde ActiveSupport
al núcleo de Ruby en 1.9.2+. Entonces, sin la necesidad de un marco completo:
require 'securerandom'
p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88
p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409
p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
Está documentado aquí: Ruby 1.9.3 – Módulo: SecureRandom (lib/securerandom.rb)