Неопределенный метод `-'для nil:NilClass (NoMethodError)
Я не могу понять, как это исправить, поэтому от переменной класса здоровья уходит десять, так как там написано, что это ошибка.
/home/will/Code/Rubygame/objects.rb:61:in `attacked': undefined method `-' for nil:NilClass (NoMethodError)
from ./main.rb:140:in `update'
from /var/lib/gems/2.3.0/gems/gosu-0.10.8/lib/gosu/patches.rb:140:in `tick'
from /var/lib/gems/2.3.0/gems/gosu-0.10.8/lib/gosu/patches.rb:140:in `tick'
from ./main.rb:197:in `<main>'
Вот код в основном:
def update
@player.left if Gosu::button_down? Gosu::KbA
@player.right if Gosu::button_down? Gosu::KbD
@player.up if Gosu::button_down? Gosu::KbW
@player.down if Gosu::button_down? Gosu::KbS
if Gosu::button_down? Gosu::KbK
@player.shot if @player_type == "Archer" or @player_type == "Mage"
if @object.collision(@xshot, @yshot) == true
x, y, health = YAML.load_file("Storage/info.yml")
@object.attacked #LINE 140
end
end
end
И вот где @object.attacked приводит к:
def attacked
puts "attacked"
@health -= 10 #LINE 61
@xy.insert(@health)
File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
@xy.delete_at(2)
if @health == 0
@dead = true
end
end
И файл yaml, если необходимо:
---
- 219.0
- 45.0
- 100.0
Я попытался поставить.to_i после @health так:
@health.to_i -= 10
Но это просто вызывает еще одну ошибку, говоря:
undefined method `to_i=' for nil:NilClass (NoMethodError)
2 ответа
Как уже упоминалось @omnikron, ваш @health
неинициализирован, следовательно -=
выдает исключение при попытке вычесть из nil
, Если вместо этого мы воспользуемся методом initialize, я представляю, как выглядит ваш класс объектов:
Class Object
attr_accessor :health
def initialize
@health = 100
end
end
def attacked
puts "attacked"
@object.health -= 10 #LINE 61
@xy.insert(@object.health)
File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
@xy.delete_at(2)
if @health == 0
@dead = true
end
end
Сообщение об ошибке говорит вам, что @health == nil
в вашем attacked
метод. Вам нужно где-то инициализировать это значение! Обычно это было бы в точно названном initialize
метод вашего класса. В качестве альтернативы можно перейти к предоставленному вами коду, если при первом нападении на кого-либо вы хотите установить @health
переменная экземпляра в значение по умолчанию, вы можете изменить его на:
def attacked
@health ||= 100 # or whatever
puts "attacked"
@health -= 10 #LINE 61
@xy.insert(@health)
File.open("Storage/info.yml", "w") {|f| f.write(@xy.to_yaml) }
@xy.delete_at(2)
if @health == 0
@dead = true
end
end
Обратите внимание ||=
Синтаксис - это оператор условного присваивания ruby - это означает, что @health
до 100, если @health уже не определено.