Ruby 语法 '{:age.gt => 60}',它是如何工作的?



我想知道这个语法{:age.gt => 60},我从mongoid中找到了这种语法。它是如何工作的?我正在检查mongoid的源代码,它没有扩展Symbol类,并且有一个包含gt.rb,lt.rb,...的matchers目录。这些文件用于条件逻辑:大于,小于...。我不明白它与Symbol类有什么关系。

在普通 irb 会话中,它显示错误:

NoMethodError: undefined method `gt' for :age:Symbol

有人能解释我吗?

这是

由mongoid本身完成的,作为此符号变形文件中Mongoid::Criterion::Complex的一部分。奇怪的是,这个文件不再存在于 master 分支中,但我在我的项目中使用 2.4.7 并且它存在在那里(它可能刚刚移动,但我在 master 中找不到它)。

非常有趣的魔法。魔法我不会认为所有必要的,:field => { :$gt => 5 }对我来说看起来很好,但无论如何:)

看起来相关代码在这里(Mongoid::Extensions::Symbol::Inflections)。有时使用Tracer在运行时深入研究这些内容是最容易的:

require 'tracer'
require 'mongoid'
Tracer.on {
  :test.gt
}

输出

#0:(irb):9:Object:-: -
#0:(eval):1:Mongoid::Extensions::Symbol::Inflections:>: -
#0:(eval):2:Mongoid::Extensions::Symbol::Inflections:-: -
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:21:Mongoid::Criterion::Complex:>:       def initialize(opts = {})
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:22:Mongoid::Criterion::Complex:-:         @key, @operator = opts[:key], opts[:operator]
#0:/home/abe/.rvm/gems/ruby-1.9.3-p125@deleteme/gems/mongoid-2.4.10/lib/mongoid/criterion/complex.rb:23:Mongoid::Criterion::Complex:<:       end
#0:(eval):3:Mongoid::Extensions::Symbol::Inflections:<: -

请参阅@rfunduk对当前发布的 2.4.10 版本的回答。

在主分支中,它已更改。现在,您将在mongoid需要的origin库中找到以下内容:

https://github.com/mongoid/origin/blob/master/lib/origin/extensions/symbol.rb,具体来说,这种方法:

module Origin
  module Extensions
    module Symbol
      # ...
      module ClassMethods
        # Adds a method on symbol as a convenience for the MongoDB operator.
        #
        # @example Add the $in method.
        #   Symbol.add_key(:in, "$in")
        #
        # @param [ Symbol ] name The name of the method.
        # @param [ Symbol ] strategy The name of the merge strategy.
        # @param [ String ] operator The MongoDB operator.
        # @param [ String ] additional The additional MongoDB operator.
        #
        # @since 1.0.0
        def add_key(name, strategy, operator, additional = nil, &block)
          define_method(name) do
            method = "__#{strategy}__".to_sym
            Key.new(self, method, operator, additional, &block)
          end
        end
        # ...
      end
    end
  end
end

它根据主mongoid库中列出的匹配器添加gtgte等方法(请参阅strategies.rb文件和matchers/文件夹)。

继续寻找...

。定义DSL范围的方法包括

  • 猴子贴片可以直接SymbolObject
  • 添加method_missing并解析名称的含义

相关内容

  • 没有找到相关文章