【问题标题】:Where are these "without" methods in Rails gems getting defined?Rails gem 中的这些“没有”方法在哪里定义?
【发布时间】:2011-04-30 23:20:23
【问题描述】:

我看到一些地方在 gems 中引用了 *_without_* 方法,但我看不到它们是在哪里定义的。以下是来自 validationgroupdelayed_jobs gem 的两个示例。

  1. validation_group.rb 中,定义了一个方法add_with_validation_group,在其最后一行引用add_without_validation_group;但是,add_without_validation_group 似乎没有在任何地方定义。

    def add_with_validation_group(attribute,
                                  msg = @@default_error_messages[:invalid], *args,
                                  &block)
      add_error = true
      if @base.validation_group_enabled?
        current_group = @base.current_validation_group
        found = ValidationGroup::Util.current_and_ancestors(@base.class).
          find do |klass|
            klasses = klass.validation_group_classes
            klasses[klass] && klasses[klass][current_group] &&
            klasses[klass][current_group].include?(attribute)
          end
        add_error = false unless found
      end
      add_without_validation_group(attribute, msg, *args,&block) if add_error
    end
    
  2. 在DelayedJob 的message_sending.rb 中,动态传递的方法参数被称为#{method}_without_send_later。但是,我只看到 #{method}_with_send_later 在此 gem 中的任何位置定义。

    def handle_asynchronously(method)
      without_name = "#{method}_without_send_later"
      define_method("#{method}_with_send_later") do |*args|
        send_later(without_name, *args)
      end
      alias_method_chain method, :send_later
    end
    

所以我相信这些“没有”方法缺少一些 Rails 魔法。但是,我似乎无法弄清楚在 Google 中搜索什么来自己回答这个问题。

【问题讨论】:

    标签: ruby-on-rails gem rubygems metaprogramming


    【解决方案1】:

    这就是alias_method_chain 为您提供的。

    基本上当你说

    alias_method_chain :some_method, :feature
    

    为您提供了两种方法:

    some_method_with_feature
    some_method_without_feature
    

    发生的情况是,当调用原来的some_method 时,它实际上调用了some_method_with_feature。然后,您将获得对 some_method_without_feature 的引用,这是您的原始方法声明(即用于回退/默认行为)。因此,您需要定义 some_method_with_feature 来实际执行操作,正如我所说,当您调用 some_method 时会调用它

    例子:

    def do_something
      "Do Something!!"
    end
    
    def do_something_with_upcase
      do_something_without_upcase.upcase
    end
    
    alias_method_chain :do_something, :upcase
    
    do_something # => "DO SOMETHING!!"
    

    查看文档here

    【讨论】:

      猜你喜欢
      • 2020-07-05
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      • 2012-11-11
      • 2014-11-30
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多