Rails宝石中的这些“无”方法在哪里被定义?

时间:2011-04-30 23:20:24

标签: ruby-on-rails gem rubygems metaprogramming

我已经看到了宝石中引用*_without_*方法的几个地方,我看不到它们被定义的位置。以下是validationgroupdelayed_jobs宝石中的两个示例。

  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。但是,我只看到此gem中任何位置#{method}_with_send_later被定义的位置。

    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
    
  3. 所以我的信念是,这些“没有”方法缺少一些Rails魔法。但是,我似乎无法弄清楚在谷歌搜索什么来自己回答这个问题。

1 个答案:

答案 0 :(得分:4)

这是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