I am using replit because I don't have ruby legitimately set up yet. I'm very new to coding and have minimal knowledge (everything my friend taught me in about 3 hours) and am quite confused. I was typing a code to test something, but when I ran it, it gave me no output.
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
This is my code so far, and from what I know it should work. However when it runs it gives me nothing despite the puts command being in place.
You've made three common mistakes.
First, using =
(assignment) rather than ==
(test for equality). This works because assigning a value to a variable (in this case an instance variable) returns that value, which is then tested for whether it is true or not, but it does not test if the two things are equal.
if @element = fire
puts "25"
Is basically the same as writing:
@element = fire
if @element
puts "25"
Secondly, you have used attr_reader
to create a fire
method to read the value in the @fire
instaance method, but you have not initialized that @fire
variable, so it is nil
.
Consequently, all of your if
and elsif
branches are only triggered is nil
is true, but since nil
is never true, none of these branches are executed. This is why you see nothing printed.
Thirdly, your conditional expression is not exhaustive. There's no else
triggered if none of the other conditions are true. In the event none of the branches of a conditional expression are executed, the conditional expression returns nil
, which you can see happen in your case if you run the code in irb
.
As a design note, it seems you intend to compare @element
to a constant. You more likely want something like the following:
def attack
if @element == "fire"
puts "25"
elsif @element == "water"
puts "15"
elsif @element == "lyfe"
puts "10"
end
end
Or using symbols:
def attack
if @element == :fire
puts "25"
elsif @element == :water
puts "15"
elsif @element == :lyfe
puts "10"
end
end
You could streamline these a bit by using case
.
def attack
case @element
when :fire
puts "25"
when :water
puts "15"
when :lyfe
puts "10"
end
end
But to ensure we can compare @element
properly, we should first downcase it and convert to a symbol. This way we don't have to compare to all possible spellings or worry that we're doing a string to symbol comparison that will turn false.
def attack
case @element.downcase.to_sym
when :fire
puts "25"
when :water
puts "15"
when :lyfe
puts "10"
end
end
just change to
def attack
if @element == "Fire"
puts "25"
....