在调用上下文中访问局部变量

时间:2019-01-11 15:28:30

标签: ruby metaprogramming

在我的代码中,我有几种使用以下模式的方法

def my_method only: [], ignore: []
  something('textvalue') if (only.empty? && ignore.empty?) || (only.any? && only.include?('textvalue')) || (ignore.any? && !ignore.include?('textvalue'))
end

换句话说,我可以选择通过指定onlyignore来过滤结果,具体取决于上下文中哪个更方便。

我想要一种声明助手want的方法,该助手可以访问onlyignore局部参数,而不必每次都指定它们,理想的结果是这样的: / p>

def my_method only: [], ignore: []
  something('textvalue') if want('textvalue')
end

此帮助程序将用在几种不同的方法,类等中。它将以某种方式在调用点检查局部变量,验证onlyignore是否存在,然后检查参数是否是否被通缉。

是否可以访问调用堆栈并查看其中的局部变量?

3 个答案:

答案 0 :(得分:4)

有一个宝石binding_of_caller可以做到这一点。安装gem,然后执行

require 'binding_of_caller'

def my_method only: [], ignore: []
  something('textvalue') if want('textvalue')
end

def want(value)
  only = binding.of_caller(1).local_variable_get(:only)
  ignore = binding.of_caller(1).local_variable_get(:ignore)
  (only.empty? && ignore.empty?) || (only.any? && only.include?(value)) || (ignore.any? && !ignore.include?(value))
end

但这是一件坏事,因为它会产生很高的耦合。这真的不是一个好的设计。如果您想进行实验和试玩,这很公平,但不要在生产中进行。

答案 1 :(得分:2)

您可以使用ruby方法定义

def my_method val, only: [], ignore: [], want: ->(val) { ((only.empty? && ignore.empty?) || (only.any? && only.include?(val))) }
 something(val) if want.call(val)
end

my_method 'value', only: ['value2']
=> false

答案 2 :(得分:2)

在这样的情况下,您不能仅将args传递给want吗?

def my_method only: [], ignore: []
  something('textvalue') if want?('textvalue', only, ignore)
end

def want?(string, only, ignore)
  (only.empty? && ignore.empty?) || (only.any? && only.include?(string)) || (ignore.any? && !ignore.include?(string))
end

似乎没有必要使它更复杂吗?

那是一个很多,更易于管理,其他人也可以继续处理-我认为这比避免将几个args传递给方法更重要。