【问题标题】:Setter doesn't work with -=, +=, etc? [duplicate]Setter 不适用于 -=、+= 等? [复制]
【发布时间】:2014-07-19 08:46:06
【问题描述】:

我不明白为什么会出现 nil 错误。我正确地创建了setter。但它不接受 -=、+= 或 = 运算符后面的自身。为什么?

class Test
  def var; @var || 0; end
  def var=(value)
    @var = value
  end

  def initialize
    @var = 2.4 # Sample value
  end

  def test
    puts var
    var -= 1 # <<< crash: undefined method for nil class
    puts var
    var = var - 1 # <<< crash: undefined method for nil class
    puts var
  end
end

a = Test.new
a.test

【问题讨论】:

    标签: ruby


    【解决方案1】:

    写成

    def test
        puts var
        self.var -= 1
        puts var
        self.var = var - 1
        puts var
    end
    

    如果您不使用self,那么Ruby 会将那些var 视为局部变量,而不是setter 方法调用。

    请记住,在 Ruby 中,方法调用永远不能没有接收器(隐式/显式)。现在如果你写var = 1,Ruby 将被视为local variable assignment。但是如果你写了self.var,Ruby 会将它解析为一个方法调用,并且会尝试调用你的 setter 方法,如果你定义了的话。还要记住self.var = 1self.var=(1)语法糖

    还有更多有趣的讨论,值得一读Private setters can be called by self, why not getters?

    最近发现了一个关于 private setter错误。这是Bug 票,现在也已修复。

    【讨论】:

    • 这似乎确实是问题所在。但是为什么在这种情况下我必须添加 self 呢?它与方法在同一个类中(不是静态的或任何东西)。
    • 所以只有 @var 或 self.var 来自类本身。我更习惯于 C#,所以我猜这就是我如此困惑的原因。感谢您的快速解决方案。
    • @Napoleon ofcourse self.var 如果你想调用 setter 方法。
    【解决方案2】:

    更新:尚不清楚您是否需要“var”的实例变量或类变量。下面的例子是一个实例变量。

    如果您想在类外部执行此操作,我会使用 attr_reader 或 attr_accessor。

    class Test
       attr_reader :var
    
       def initialize
          @var=2.4
       end
    
       def test
         puts @var
         @var -= 1
         puts @var
         @var = @var - 1
         puts @var
       end
    end
    
    t=Test.new
    t.test
    puts t.var
    
    $ /tmp/t.rb
    2.4
    1.4
    0.3999999999999999
    0.3999999999999999
    

    【讨论】:

      【解决方案3】:

      因为 var 为零。你需要先给它赋值

      def test
          puts var
          var=0 
          var -= 1 # <<< crash: undefined method for nil class
          puts var
          var=0
          var = var - 1 # <<< crash: undefined method for nil class
          puts var
        end
      

      【讨论】:

      • "|| 0" 应该确保它返回 0 如果它是 nil。并且初始化也设置了它。
      猜你喜欢
      • 1970-01-01
      • 2022-06-10
      • 2017-06-24
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      相关资源
      最近更新 更多