首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >alias_method、alias_method_chain和self.included

alias_method、alias_method_chain和self.included
EN

Stack Overflow用户
提问于 2012-04-06 01:08:47
回答 1查看 1.8K关注 0票数 3

我对理解alias_method/alias_method_chain有一点困难。我有以下代码:

代码语言:javascript
复制
module ActionView::Helpers
  module FormHelper

    alias_method :form_for_without_cherries, :form_for

    def form_for(record, options = {}, &proc)
      output = 'with a cherry on top'.html_safe
      output.safe_concat form_for_without_cherries(record, options = {}, &proc)
    end
  end
end

这就是我想要做的--在任何form_for调用的顶部添加“上面有个樱桃”。

但我的理解是,由于几个原因,这不是好的代码。首先,它不会链接到form_for(?)的任何其他重写,所以如果我编写第二个form_for方法,并附加“在顶部又一个樱桃”,它就不会显示出来。其次,alias_methodalias_method_chain在某种程度上是过时的解决方案,我应该使用self.included &发送到模块。

但是我不能让self.included调用这个form_for方法-它只是一直调用父方法。这是我正在尝试的:

代码语言:javascript
复制
module CherryForm
  def self.included(base)
    base.extend(self)
  end

  def form_for(record, options = {}, &proc)
    output = 'with a cherry on top'.html_safe
    output.safe_concat super(record, options = {}, &proc)
  end 
end

ActionView::Helpers::FormHelper.send(:include, CherryForm)

我的上述解决方案是有效的,但我怀疑这是错误的做法。如果任何ruby老手能向我展示一种更优雅的方式来做这件事--或者为什么第二种解决方案没有被调用--我将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-06 04:08:34

当你用猴子打补丁的时候,你必须重新定义方法,因为没有超类可以继承(所以你不能使用第二个代码摘录)。

复制当前的方法实现并添加您自己的方法是自找麻烦的,所以这就是alias_method的用武之地。

代码语言:javascript
复制
alias_method :form_for_without_cherries, :form_for

它实际上创建了原始方法的克隆,您可以使用它而不是super。你不能链接猴子补丁的事实不是一个bug,而是一个特性。

rails的alias_method_chain方法确实被弃用了,但这仅仅是因为它从一开始就是一个糟糕的想法。然而,alias_method是一种纯粹的ruby方法,如果使用得当,它可以提供一种优雅的方式来修补您的代码,这就是为什么我非常确定它不会很快消失。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10032927

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档