1
我正在嘗試編寫一個DSL來包裝Mongoid的聚合管道(即Mongo DB)。根據實例eval將實例變量傳遞給DSL
我做了一個模塊,當包含它時,添加一個類方法,接受一個塊,它交給一個將請求傳遞給Mongoid的對象(通過缺少方法)。
所以我可以做:
class Project
include MongoidAggregationHelper
end
result = Project.pipeline do
match dept_id: 1
end
#...works!
「匹配」是Mongoid的聚合管道,這是攔截和傳遞的方法。
但在塊外部設置的實例變量不可用,因爲它在代理類的上下文中執行。
dept_id = 1
result = Project.pipeline do
match dept_id: dept_id
end
#...fails, dept_id not found :(
任何方式來傳遞/重新定義外部實例變量與塊?
下面是修剪代碼:
module MongoidAggregationHelper
def self.included base
base.extend ClassMethods
end
module ClassMethods
def pipeline &block
p = Pipeline.new self
p.instance_eval &block
return p.execute
end
end
class Pipeline
attr_accessor :cmds, :mongoid_class
def initialize klass
self.mongoid_class = klass
end
def method_missing name, opts={}
#...proxy to mongoid...
end
def execute
#...execute pipeline, return the results...
end
end
end
你可以試一下'def pipeline(* args,&block)'和'Project.pipeline dept_id:dept_id do'嗎? – MrYoshiji
好的建議@MrYoshiji,在生產代碼中我這樣做,它的工作原理。我希望避免必須將變量作爲選項散列傳遞,然後使用之前聲明的變量(如果有的話)。 –
我發佈了一個替代答案 – MrYoshiji