Ruby 何时应使用别名方法?-红宝石
我已经看了一遍,还没有找到答案: 您会使用什么别名方法Ruby 何时应使用别名方法?-红宝石,ruby,alias-method,Ruby,Alias Method,我已经看了一遍,还没有找到答案: 您会使用什么别名方法 class Vampire attr_reader :name, :thirsty alias_method :thirsty?, :thirsty end 我使用问号的唯一原因是为了能够在我定义的任何方法中使用问号吗?我相信不能在实例变量中使用问号。我想这是我之前回答的一个问题,我建议使用alias\u方法,所以我有一点额外的上下文来解释它在该上下文中的用法 在代码片段中,有一段代码读取attr\u reader:quirty,它
class Vampire
attr_reader :name, :thirsty
alias_method :thirsty?, :thirsty
end
我使用问号的唯一原因是为了能够在我定义的任何方法中使用问号吗?我相信不能在实例变量中使用问号。我想这是我之前回答的一个问题,我建议使用
alias\u方法
,所以我有一点额外的上下文来解释它在该上下文中的用法
在代码片段中,有一段代码读取attr\u reader:quirty
,它基本上是同名实例变量的getter(@quirty
)
在原始代码段中,您有一个断言:
refute vampire.thirsty?
您还有一些代码只是为quirty?
方法返回了true
,这使您的断言失败
至少有两种方法可以修改代码,以使对口渴?
的调用起作用并传递断言:
创建一个调用口渴
读取器的方法,或访问@口渴
实例变量本身:
def thirsty?
thirsty # or @thirsty
end
另一种方法是使用alias_方法
,其功能等同于上述方法。它将口渴?
别名为口渴
,这是一个属性读取器
,它从@口渴
实例变量读取
对于我给出的另一个答案
您最好不要使用attr_阅读器,而只是按照Sergio在评论中指出的那样:
class Vampire
def initialize(name)
@name = name
@thirsty = true
end
def thirsty?
@thirsty
end
def drink
@thirsty = false
end
end
我想这是我之前回答的一个问题,我建议使用
alias\u方法
,所以我有一点额外的上下文来解释它在该上下文中的用法
在代码片段中,有一段代码读取attr\u reader:quirty
,它基本上是同名实例变量的getter(@quirty
)
在原始代码段中,您有一个断言:
refute vampire.thirsty?
您还有一些代码只是为quirty?
方法返回了true
,这使您的断言失败
至少有两种方法可以修改代码,以使对口渴?
的调用起作用并传递断言:
创建一个调用口渴
读取器的方法,或访问@口渴
实例变量本身:
def thirsty?
thirsty # or @thirsty
end
另一种方法是使用alias_方法
,其功能等同于上述方法。它将口渴?
别名为口渴
,这是一个属性读取器
,它从@口渴
实例变量读取
对于我给出的另一个答案
您最好不要使用attr_阅读器,而只是按照Sergio在评论中指出的那样:
class Vampire
def initialize(name)
@name = name
@thirsty = true
end
def thirsty?
@thirsty
end
def drink
@thirsty = false
end
end
有两个理由可以使用,一个是当前有效的,另一个是过时的,实际上从来没有必要 第一个原因是,您只想让两个名称不同的方法执行完全相同的操作。这样做的一个原因可能是,对于同一个操作,有两个同样广泛使用的术语,您希望让人们更容易编写社区可以理解的代码。(Ruby core库中的一些示例是collection方法,这些方法的名称来自函数式编程语言,如
map
,reduce
,来自Smalltalk编程语言家族的人,如collect
,inject
,select
,以及standard英文名称,如find_all
)另一种可能是您构建了一个流畅的界面,并希望其阅读更流畅,如下所示:
play this
and that
and something_else
class SomeClass
def some_method
"Hello World"
end
end
class SomeClass
alias_method :__some_method_without_shouting :some_method
def __some_method_with_shouting
__some_method_without_shouting.upcase
end
alias_method :some_method :__some_method_with_shouting
end
在这种情况下,和
可以是播放
的别名
另一个相关的原因(我们称之为原因1.5)是您想要实现某个协议,并且您已经有了一个正确实现该协议语义的方法,但是它的名称错误。让我们假设一个假设的集合框架,它有两个方法map\u seq
和map\u nonseq
。第一种方法执行map
并保证副作用的顺序,而第二种方法不保证副作用的顺序,甚至可以异步、并发或并行地执行映射操作。这两种方法实际上具有不同的语义,但是如果您的数据结构不适合并行化,那么您可以简单地实现map\u seq
并将map\u nonseq
作为别名
在这种情况下,驱动程序并不是要为同一个操作提供两个名称,而是要为两个名称提供相同的实现(如果这句话有意义的话:-D)
过去使用alias_method
的第二个主要原因与它的语义的一个重要细节有关:当覆盖或修补这两个方法中的任何一个时,这只会影响该名称,而不会影响另一个名称。这在过去用于包装方法的行为,如下所示:
play this
and that
and something_else
class SomeClass
def some_method
"Hello World"
end
end
class SomeClass
alias_method :__some_method_without_shouting :some_method
def __some_method_with_shouting
__some_method_without_shouting.upcase
end
alias_method :some_method :__some_method_with_shouting
end
这有点无聊。我们要用我们的方法喊!但是,我们不想只是复制和重新实现这个方法,我们想重新使用它的内部实现,而不必知道它是如何在内部实现的。我们希望对其进行修补,以便此方法的所有客户端都有叫喊行为。流行的方法是这样的:
play this
and that
and something_else
class SomeClass
def some_method
"Hello World"
end
end
class SomeClass
alias_method :__some_method_without_shouting :some_method
def __some_method_with_shouting
__some_method_without_shouting.upcase
end
alias_method :some_method :__some_method_with_shouting
end
在本例中,我们使用alias_method
为我们正在进行猴子补丁的方法创建一个“备份”,以便我们可以从该方法的猴子补丁版本中调用它。(否则,该方法将消失。)这实际上是alias_method
文档中给出的用例
这个习语如此流行和广泛使用,以至于一些图书馆甚至提供了