Estoy usando replit porque aún no tengo Ruby configurado legítimamente. Soy muy nuevo en la codificación y tengo un conocimiento mínimo (todo lo que mi amigo me enseñó en aproximadamente 3 horas) y estoy bastante confundido. Estaba escribiendo un código para probar algo, pero cuando lo ejecuté, no me dio ningún resultado.
class Hands attr_reader :name, :element, :skill, :mana, :attack, :fire, :water, :lyfe def initialize(name, element, skill) @mana = 100 @name = name @element = element @skill = skill end def attack if @element = fire puts "25" elsif @element = water puts "15" elsif @element = lyfe puts "10" end end end player1 = Hands.new('Boyd', 'Fire', 'Craft') player1.attack
Este es mi código hasta ahora, y por lo que sé, debería funcionar. Sin embargo, cuando se ejecuta, no me da nada a pesar de que el comando puts está en su lugar.
Has cometido tres errores comunes.
Primero, usando =
(asignación) en lugar de ==
(prueba de igualdad). Esto funciona porque asignar un valor a una variable (en este caso, una variable de instancia) devuelve ese valor, que luego se prueba para determinar si es cierto o no, pero no prueba si las dos cosas son iguales.
if @element = fire puts "25"
Es básicamente lo mismo que escribir:
@element = fire if @element puts "25"
En segundo lugar, usó attr_reader
para crear un método de fire
para leer el valor en el método de @fire
, pero no ha inicializado esa variable @fire
, por lo que es nil
.
En consecuencia, todas sus ramas if
y elsif
solo se activan si nil
es verdadero, pero dado que nil
nunca es verdadero, ninguna de estas ramas se ejecuta. Es por eso que no ves nada impreso.
En tercer lugar, su expresión condicional no es exhaustiva. No se activa else
si ninguna de las otras condiciones es verdadera. En el caso de que no se ejecute ninguna de las ramas de una expresión condicional, la expresión condicional devuelve nil
, lo que puede ver que sucede en su caso si ejecuta el código en irb
.
Como nota de diseño, parece que tiene la intención de comparar @element
con una constante. Lo más probable es que quieras algo como lo siguiente:
def attack if @element == "fire" puts "25" elsif @element == "water" puts "15" elsif @element == "lyfe" puts "10" end end
O usando símbolos:
def attack if @element == :fire puts "25" elsif @element == :water puts "15" elsif @element == :lyfe puts "10" end end
Podría simplificarlos un poco usando case
.
def attack case @element when :fire puts "25" when :water puts "15" when :lyfe puts "10" end end
Pero para asegurarnos de que podemos comparar @element
correctamente, primero debemos reducirlo y convertirlo en un símbolo. De esta manera, no tenemos que comparar todas las ortografías posibles ni preocuparnos de que estamos haciendo una comparación de cadena a símbolo que se volverá falsa.
def attack case @element.downcase.to_sym when :fire puts "25" when :water puts "15" when :lyfe puts "10" end end
solo cambia a
def attack if @element == "Fire" puts "25" ....