是否有可能知道 Ruby 类何时完成链接方法?

问题描述 投票:0回答:1

我正在尝试确定是否有可能在 Ruby 中确定方法链何时完成调用。

假设我有一个从数据库中检索信息的类。我经常只想调用该类的一个实例来访问 all 包含的数据,但在许多情况下,我链接了应用过滤器等的附加方法。目前,实际的数据检索是由一个总是最后调用的方法执行的,比如所以:

all_data = data_retriever.run
filtered_data = data_retriever.condition({k1: v1}).run
filtered_data = data_retriever.condition({k1: v1}).condition({k2: v2}).run

这很好用,但我忍不住认为 Ruby 可能有办法做到这一点,而无需在每次使用结束时添加像

.run
这样的方法。当我完成链接方法时,我的班级是否有可能“知道”?比如在调用所有链式方法后执行的钩子?

class DataRetriever 
  @conditions = {}
  def initialize()
  end
 
  def condition(condition_hash)
    @conditions << condition_hash
  end

  #...

  def after_chains
    # run the data retrieval code using the contents of @conditions
  end
end
ruby method-chaining
1个回答
0
投票

不,链接方法等同于一个接一个地调用它们。呼叫者无法区分呼叫方式。这实际上很好,请考虑以下几点:

retriever = data_retriever.condition({k1: v1})
retriever.condition({k2: v2}) if something
retriever.condition({k3: v3}) if something_else
data = retriever.run

在上面的示例中,您可能不希望第一行已经触发数据检索。

但是,您可以使用更微妙的入口点来触发执行,而不是

run
,例如
each
是 Ruby 默认的枚举方法:

data = data_retriever.condition({k1: v1})

data.each do |entry|
  # ...
end

引擎盖下:

class DataRetriever
  def run
    @data = # retrieve actual data
  end

  def each(&block)
    run unless @data
    
    @data.each(&block)
  end
end

只需确保在添加更多条件时使

@data
无效(或者
freeze
run
之后的对象)。

你甚至可以从

each
调用
inspect
:(你可能想缩写长数据)

class DataRetriever
  def inspect
    "#<DataRetriever data=#{each.to_a.inspect}>"
  end
end

在 irb:

filtered_data = DataRetriever.new.condition({k1: v1})
#=> #<DataRetriever data=[1, 2, 3]>
© www.soinside.com 2019 - 2024. All rights reserved.