在Ruby中,当方法有别名时,别名指向原始方法的主体。因此,即使重新定义原始方法,别名也将继续使用原始定义。
class Foo
def bar
"bar"
end
alias :saloon :bar
end
class Foo
def bar
"BAR"
end
end
puts Foo.new.saloon
将返回'bar'而不是'BAR'。有没有办法让轿车使用bar的新定义?
编辑:我应该更清楚。这个例子只是一个问题的例子 - 这不是我需要解决的实际问题。当你有链式别名时,问题就更复杂了,例如,在rails的核心中。例如。 perform_action由基准测试模块替代,然后由flash模块替代。所以现在对perform_action的调用实际上是调用perform_action_with_flash执行它的事情,然后有效地调用perform_action_with_benchmarking然后调用原始的perform_action。如果我想覆盖perform_action_with_benchmarking(即使我同意这是一个坏主意 - 请让我们不要讨论它,除了这一点),我不能,因为它已被别名,并且据我所知别名指向的是原始perform_action_with_benchmarking的副本,所以即使重新定义它,也没有效果。答案 0 :(得分:5)
重新建立别名:
class Foo
def bar
"bar"
end
alias :saloon :bar
end
class Foo
def bar
"BAR"
end
alias :saloon :bar
end
puts Foo.new.saloon # => "BAR"
答案 1 :(得分:3)
class Foo
def bar
"bar"
end
def saloon
bar
end
end
这根本不是别名,但可以按照您的意愿使用。
答案 2 :(得分:2)
这是另一个答案,但你必须做一些额外的步骤:在覆盖之前收集别名,并在之后收集realias:
class Class
def get_aliases method_name
original_proc = instance_method method_name
aliases = []
instance_methods.each do |meth|
# if the methods have different names but they're the same, they're aliased
if meth != method_name.to_s && original_proc == instance_method(meth)
aliases << meth
end
end
aliases
end
end
class Foo
def bar
"bar"
end
alias :saloon :bar
end
class Foo
aliases = get_aliases :bar
def bar
"BAR"
end
aliases.each { |a| alias_method a, :bar }
end
puts Foo.new.saloon #=> BAR
顺便说一句,如果有人可以剥离其中一个步骤,我可以知道吗! :)
答案 3 :(得分:1)
是和否。 coreyward或Sony Santos的解决方案都运行良好。您需要知道的是为什么您的编码不会像您那样工作。
alias
为调用方法时显示的函数创建一个新名称。这是不是指针,而是一种引用某种东西的新方法。它允许我们做这样的事情:
class Foo
def bar
"bar"
end
alias :speakeasy :bar
end
class Foo
def bar(secret_code = false)
return speakeasy if secret_code == "A friend of Al"
"Closed because of prohibition!"
end
end
puts Foo.new.bar #=> "Closed because of prohibition!"
puts Foo.new.bar "A friend of Al" #=> "bar"
旧酒吧仍然存在,现在只是稍微难以访问。