Ruby使用params实现可选函数调用

时间:2015-11-28 03:06:14

标签: ruby-on-rails ruby

我需要一个函数来检查是否符合某些判断,判断是一些需要参数的函数。如:

Something.is_close_to?(:sky)

我已经根据here中学到的内容制作了一个。

def get_somethings(options = {})
  somethings = []
  Something.all.each do |something|
    this_is_it = true

    options.each_pair do |key, value|
      expected_result = value.pop
      this_is_it = false if !(Something.first.send(key, *value) == expected_result)
    end

    somethings << something if this_is_it
  end
  return somethings
end

我可以通过以下方式调用此函数:

options = {is_close_to?: ["sky", true], is_higher_than?: [2000, true]}
get_somethings()

我认为我的方式是扭曲的,所以我想知道是否有更好的方法来做到这一点。

2 个答案:

答案 0 :(得分:0)

让我们分几步:

  1. 从集合中选择符合条件的项目
  2. 根据您的情况匹配所有条件
  3. 从哈希中提取元素(称为解构)
  4. 调用对象上的check方法
  5. 代码

    def get_somethings(collection, conditions = {})
      # Step 1
      collection.find_all do |item|
        matches_conditions item, conditions
      end
    end
    
    # Step 2
    def matches_conditions(item, conditions)
      # Step 2           Step 3
      conditions.all? do |predicate, (argument, expected)|
        # Step 4
        item.public_send(predicate, argument) == expected
      end
    end
    
    conditions = {is_close_to?: ["sky", true], is_higher_than?: [2000, true]}
    get_somethings(Something.all, conditions)
    

答案 1 :(得分:0)

有问题的代码存在一些错误,对不起,工作版应如下所示:

def get_somethings(options = {})
  somethings = []
  Something.all.each do |something|
    found_one = true
    options.each_pair do |key, value|
      expected_result = value.first

      if something.send(key, *value.drop(1)) != expected_result
        found_one = false
      end

    end
    somethings << something if found_one
  end
  return somethings
end