可以在 Ruby 中重写别名方法吗?
在 Ruby 中,当一个方法有别名时,别名指向原始方法的主体。所以即使你重新定义了原来的方法,别名也会继续使用原来的定义。
class Foo
def bar
"bar"
end
alias :saloon :bar
end
class Foo
def bar
"BAR"
end
end
puts Foo.new.saloon
将返回“bar”而不是“BAR”。有什么办法让沙龙使用酒吧的新定义吗?
编辑:我应该更清楚。该示例只是问题的说明 - 这不是我需要解决的实际问题。当您有链接别名时,例如在 Rails 的核心中,问题会更加复杂。例如,perform_action 由基准测试模块别名,然后也由闪存模块别名。所以现在对perform_action的调用实际上是调用perform_action_with_flash来完成它的事情,然后有效地调用perform_action_with_benchmarking,然后再调用原始的perform_action。如果我想覆盖perform_action_with_benchmarking(即使我同意这是一个坏主意 - 请让我们不要对此进行讨论,因为它超出了重点),我不能,因为它已被别名,并且据我所知别名本质上指向原始 Perform_action_with_benchmarking 的副本,因此即使我重新定义它,也没有效果。
In Ruby, when a method is aliased, the alias points to the body of the original method. So even if you redefine the original method, the alias will continue to use the original definition.
class Foo
def bar
"bar"
end
alias :saloon :bar
end
class Foo
def bar
"BAR"
end
end
puts Foo.new.saloon
will return 'bar' and not 'BAR'. Is there any way to get saloon to use the new definition of bar?
EDIT: I should have been more clear. The example was just an illustration of the issue - it's not the actual problem I need to solve. The issue is more complex when you have chained aliases, for example, in rails' core. E.g. perform_action is aliased by benchmarking module, and then also by flash module. So now a call to perform_action is actually calling perform_action_with_flash which does it's thing, then effectively calls perform_action_with_benchmarking which then calls the original perform_action. If I want to override perform_action_with_benchmarking (even though I agree it's a bad idea - please let's not get into a discussion of that as it's besides the point), I can't because it has been aliased, and as far as I can tell the alias is pointing to what is essentially a copy of the original perform_action_with_benchmarking, so even if I redefine it, there's no effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只需重新建立别名即可:
Just re-establish the alias:
这根本不是别名,但它可以按照您的意愿工作。
This is not an alias at all, but it works as you want.
是和不是。 coreyward 或 Sony Santos 的解决方案都可以正常工作。您需要知道的是为什么您的编码没有按照您的方式工作。
alias
为函数创建一个新名称,就像调用方法时出现的那样。这不是指针,而是一种引用某事物的新方式。它允许我们做这样的事情:旧的酒吧仍然存在,只是现在访问起来有点困难。
Yes and no. Either coreyward or Sony Santos's solutions work fine. What you need to know is why your coded didn't work the way you though.
alias
makes a new name for the function as is appears when the method is invoked. This is not a pointer, but a new way of referring to something. It allows us to do something like this:The old bar still exists, it just a little harder to access now.
这是另一个答案,但您必须执行一些额外的步骤:在覆盖之前收集别名,并在覆盖之后收集真实别名:
顺便说一句,如果有人可以删除其中一个步骤,我可以知道吗! :)
Here is another answer, but you have to do some additional steps: collect the aliases before overriding, and realias after:
BTW, if anyone can strip off one of that steps, may I know it! :)