Неопределенный метод `-'для 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 уже не определено.

Другие вопросы по тегам