【问题标题】:undefined method `-' for nil:NilClass (NoMethodError)nil:NilClass (NoMethodError) 的未定义方法“-”
【发布时间】:2017-10-02 09:24:27
【问题描述】:

我不知道如何修复它,所以它会从健康类变量中删除十个,因为它说这是一个错误。

/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>'

这是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)

【问题讨论】:

  • 我认为您的问题实际上是x, y, health = YAML.load_file("Storage/info.yml") 我假设这应该是@x, @y, @health = YAML.load_file("Storage/info.yml") 实例变量而不是局部变量。

标签: ruby methods undefined libgosu


【解决方案1】:

错误消息告诉您@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 已经定义。

【讨论】:

    【解决方案2】:

    正如@omnikron 所述,您的@health 未初始化,因此-= 在尝试从nil 中减去时会引发异常。如果我们改用初始化方法,我想你的对象类看起来像:

    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
    

    【讨论】:

    • 在不同的主题上,使用Object 作为类名将会给你带来一些有趣的问题,因为每一个ruby 对象都继承自Object 类!所以这将覆盖每个 ruby​​ 对象的初始化方法。你可以在irb中试试这个,你会看到上面的代码打印出"warning: redefining Object#initialize may cause infinite loop"
    猜你喜欢
    • 2013-11-14
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多