Ruby setter和带参数的方法

lymgl2op  于 2022-11-04  发布在  Ruby
关注(0)|答案(2)|浏览(173)

我希望你做得很好。我是Ruby的新手,我真的不明白setter方法和带参数的方法之间有什么区别。例如,假设我有下面的代码:

module Popy

  def self.friend
    @friend
  end

  def self.friend=(new_friend) 
    @friend = new_friend
  end

end

我知道用setter方法friend设置了Popy的@friend,但是如果我用这个方法,有什么区别呢?

def self.friend!(new_friend) 
  @friend = new_friend
end

我试着在网上搜索这个问题,但是没有找到答案。提前谢谢你!祝你有美好的一天。

7cwmlq89

7cwmlq891#

没有多大区别; =字符和!一样是方法名的一部分。可读性是一个问题--感叹号经常被用来引起对方法的注意:“当心,有潜在风险的事情即将发生。”如果friend!最终只是一个setter,我会感到失望和困惑。而且,=允许Ruby抛出一些方便的方法,如:

Popy.friend = "Ana"
Popy.friend += " maria"
p Popy.friend # => "Ana maria"
6yoyoihd

6yoyoihd2#

从语义的观点来看,名为foo的方法、名为bar的方法、名为friend的方法、名为friend!的方法或名为friend=的方法之间没有区别。
但是从语法的Angular 来看,一个以=结尾的方法可以用赋值的方式调用,换句话说,不同之处在于调用方法的语法:

Popy.friend = the_new_friend

Popy.friend!(the_new_friend)

但这是唯一的区别。
请注意,名为friend!的方法不是惯用的Ruby方法:方法名以bang结尾(!)只在有一对同名的方法做“大致相同的事情”时使用。2在这种情况下,这对方法中“更令人惊讶”的方法得到bang。
在你的例子中,你有一对同名的方法(friend),其中赋值示例变量的方法更令人惊讶,但问题是:这两种方法做的事情并不“大致相同”。事实上,它们做的事情正好相反:一个 * 获取 * 值,另一个 * 设置 * 值。
因此,它们的命名方式应该明确地表明它们是对立的。
在像Java这样的语言中,常用的习惯用法是将它们命名为getFriendsetFriend
但是在Ruby中,常用的习惯用法是将它们命名为friendfriend=
注意,Ruby有一些方法可以生成这些琐碎的编写器和读取器:

  • Module#attr_reader生成一个读取器方法,
  • Module#attr_writer生成一个编写器方法,并且
  • Module#attr_accessor会同时产生读取器和写入器方法。

因此,您问题中的代码最常用的编写方式是

class << Popy
  attr_accessor :friend
end

相关问题