【问题标题】:To access class variables, can you only have a setter method with no getter method?要访问类变量,你可以只有一个没有getter方法的setter方法吗?
【发布时间】:2016-11-06 10:45:03
【问题描述】:

给定以下代码:

class Man
  def self.noise=(noise)
    @@noise = noise
  end
end

puts Man.noise = ("YO")

我使用了 setter 方法 self.noise,但实际上并没有使用 getter 方法并且它有效。我很想知道类变量是否需要 getter 和 setter 方法才能工作?

所有这些中令人困惑的元素是实例变量似乎需要同时访问 getter 和 setter 方法。如果您只有一个 setter 方法来访问实例变量,那么如果您调用 setter 方法,该变量将不会被返回。

我的问题是,对于类变量,你可以只有一个setter方法并调用它,而没有getter方法来访问类变量吗?在这种情况下,getter 方法是:

self.noise
  @@noise
end 

【问题讨论】:

  • stackoverflow.com/questions/8737421/… - 问基本相同的问题,但关于实例变量 - 是否有助于澄清事情?特别是回答stackoverflow.com/a/8737438/117424 可能会有所帮助。
  • 我完全明白实例变量需要同时使用getter和setter方法,想知道类变量也是一样的。是否有必要同时拥有两者才能使程序正常工作。

标签: ruby


【解决方案1】:

您没有在这里调用“getter”方法,因为Man.noise 位于赋值运算符的左侧。这会调用 Man.noise= 并且您已经定义了它。

如果你尝试调用它,你会得到:

Man.noise
#! NoMethodError: undefined method `noise' for Man:Class

您可以这样做让您的生活更轻松:

class Man
  class << self
    attr_accessor :noise
  end
end

Man.noise = 'Hello world!'
Man.noise
# => "Hello world!"

在 Rails 环境中,cattr_accessor 用于类,mattr_accessor 用于模块,无需class &lt;&lt; self 等即可为您执行此操作。

需要注意的一点是尽可能使用常规实例变量。此处无需使用@@

【讨论】:

  • 我知道我在这个类变量的情况下使用了“setter”方法,但它似乎在没有“getter”方法的情况下也能正常工作。这与实例变量相比,如果我在没有“getter”方法的情况下直接调用“setter 方法”,则不会返回实例变量。只是想确认我是否正确理解您不需要 getter 和 setter 方法来访问类变量(在这种情况下只是 setter),而不是实例变量。这是真的吗?
  • 只有一个setter(mutator)是不寻常的。通常你会成对创建这些,这样你就可以读取写入。在您的情况下,您只定义了一个 mutator,而不是一个 reader,所以您只完成了一半的工作。它基本上是一个只写类属性。
  • 我意识到同时拥有 reader 和 writer 方法更好。只是想确认您可以为类变量(如果您愿意的话)只使用一个 setter 方法并调用它来访问类变量吗?
【解决方案2】:

编写类变量已正确完成。您可以按如下方式阅读它们:

class Man
  def self.noise=(noise)
    @@noise = noise
  end
  def self.noise
     @@noise ||= nil
  end
end

puts "Hello world!"
puts Man.noise
puts Man.noise = ("YO")
puts Man.noise

输出:

Hello world!

YO
YO 

但是,在继承方面你应该非常小心。

class Man
  def self.noise=(noise)
    @@noise = noise
  end
  def self.noise
     @@noise ||= nil
  end
end


class Man1 < Man

end

Man.noise = ("YO")
Man1.noise = ("XYZ")
puts Man1.noise
puts Man.noise

输出:

XYZ
XYZ

请注意,更改子类的noise 也会更改父类的noise

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多