我想知道这个语法{: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
库中列出的匹配器添加gt
、gte
等方法(请参阅strategies.rb
文件和matchers/
文件夹)。
继续寻找...
。定义DSL范围的方法包括
- 猴子贴片可以直接
Symbol
或Object
- 添加
method_missing
并解析名称的含义