【问题标题】:Trying to learn / understand Ruby setter and getter methods尝试学习/理解 Ruby 的 setter 和 getter 方法
【发布时间】:2012-01-05 03:50:55
【问题描述】:

我刚刚学习编程并决定尝试 Ruby。我敢肯定这是一个愚蠢的问题,但是讲师正在谈论 setter 和 getter 方法,我很困惑。示例如下:

class Human
  def noise=(noise)
    @noise = noise
  end

  def noise
    @noise
  end
end

由此,类被实例化,我可以把它说出来:

man = Human.new
man.noise=("Howdie!")
puts man.noise

这导致Howdie!

现在让我感到困惑的是,讲师说没有 getter 方法(两种方法中的第 2 种),就无法与实例变量 @noise 进行交互。

但是当我删除 getter 方法时,我仍然可以访问@noise,参见示例:

class Human
  def noise=(noise)
    @noise = noise
  end
end

man = Human.new
puts man.noise=("Howdie!")

这与它使用的 getter 方法相同。

所以现在我很困惑。为什么需要吸气剂?没有它就无法访问实例变量是什么意思?有没有可能他使用的是旧版本的 Ruby?

提前感谢您的帮助。

【问题讨论】:

  • 你真的能够访问@noise,或者你看到的是你正在调用的函数的副作用......

标签: ruby


【解决方案1】:

即使没有 getter,您也可以通过属于该实例的其他方法与该实例变量进行交互:

def noise=(noise)
  @noise = noise
end

def last_noise
  @noise
end

不需要定义与方法同名的getter;两者完全没有联系。需要 getter 来“获取”实例变量的值,但仅限于 short 语法。

在您的示例中发生的情况是您正在初始化一个新对象 (Human.new),然后使用刚刚发生的方法 (noise=,是的方法名称包含 = 符号)定义一个实例变量(即,该实例的一个变量just),然后最后用另一个方法调用检索该实例变量。

您实际上可以使用instance_variable_get 来获取实例变量而无需定义任何 getter:

man = Human.new
man.noise = "Howdie"
man.instance_variable_get("@noise")

这将返回“Howdie”,即使没有定义 getter。

不,我不认为他使用的是旧版本的 Ruby。

【讨论】:

  • +1 瑞恩。像往常一样,你的专业知识很出色,我不知道 instance_variable_get !
  • 嘿,这不会覆盖 attr_protected 吗?
  • 回答了我自己的问题:- api 说“在这个宏中命名的属性受到保护,不会被批量赋值”
  • ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000350 for attr_accessible 和 aame for attr_accessible ar.rubyonrails.org/classes/ActiveRecord/Base.html#M000351 都不会阻止直接设置器
  • ok attr_readonly(*attributes) 列为只读的属性可以设置为新记录,但在之后的数据库更新中将被忽略。现在更像了!
【解决方案2】:

代码行

puts man.noise=("Howdie!")

不使用 getter 方法,因此无需定义 getter 方法即可工作。该行仅使用 setter 方法。 setter 方法的返回值自动等于等号右边的值,所以“Howdie!”被传递给puts

代码行

puts man.noise

确实使用 getter 方法,如果您删除 getter 方法,它将不起作用。

【讨论】:

  • 所以我想我的问题是,为什么要使用 getter 和 setter 方法?为什么不只使用 setter 方法(或让我将值传递给方法的基本方法)并对其进行“返回”?我不是在建议更好的做事方式,我真的在问为什么?我不明白。
  • 您需要 getter 方法,因为有时您希望获取变量的值而不更改它。 setter 方法总是将值设置为某个东西,所以不可能不修改就使用 setter 方法获取值!
  • 如果你希望变量可以被类外的方法读取,你只需要getter方法。如果你只是想从类中的方法中读取变量,你可以简单地使用@noise而不是getter方法。
  • 这个答案对我来说是最好的。 getter 与 setter 是答案的关键。如果我理解的话,只有在类中有默认的噪声值时,getter 方法才有用。如果没有默认值我们不需要它
  • 如果写man.noise ||= value,那么getter和setter方法都需要定义。我想这就是你可能要说的。
【解决方案3】:

当然,它们都返回一个值,但它们的行为不同。

假设已经有一个成员@a

使用getter,可以得到@a的当前值,无需修改。

使用setter,修改@a,并获取其新值作为返回值。

在考虑 setter 的行为时,请注意:

  1. @a 的旧值无法通过 setter 获取,被覆盖。

  2. setter返回的内容,其实在调用setter之前就已经知道了。

【讨论】:

  • 直到我阅读了其他人的回复,我才理解您的回复,现在我理解了(并且想了更多),我认为您的回答有助于将我的问题带回家。如果你加强你的答案,这样可以减少像我这样的新手首先阅读其他人的答案的需要,那么我想选择你的。
【解决方案4】:

getter 和 setter 可能需要注意的是,因为其他一些语言允许您直接访问类变量。蟒蛇:

class k:
    i = 100

print k.i # 100
k.i = 200
print k.i # 200

相比之下,Ruby 将其所有变量对类完全保密,并且仅通过访问器方法公开它们。

在您的示例中,如果您删除 getter,您确实可以通过 setter 与变量交互(即:更改它),但是当您需要它时,您无法(以常规方式)取回它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2017-09-09
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多