我正在开发一个命令行Ruby应用程序,我希望允许它的用户提供代码,该代码将作为过程的一部分进行过滤。基本上,应用程序执行此操作:
我希望过滤过程(第2步)尽可能灵活。
我的想法是用户可以提供一个Ruby文件,该文件设置一个已知常量来指向实现我定义的接口的对象,例如:
# user's filter
class MyFilter
def do_filter(array_to_filter)
filtered_array = Array.new
# do my filtering on array_to_filter
filtered_array
end
FILTER = MyFilter.new
我的应用程序代码会执行以下操作:
array_that_might_get_filtered = get_my_array()
if (options.filter_file)
require options.filter_file
array_that_might_get_filtered = FILTER.do_filter(array_that_might_get_filtered)
end
虽然这样可行但感觉很俗气,似乎应该有更好的方法。我还考虑让过滤器采用已知类的方法添加已知类的方法,但这似乎也不正确。
Ruby中有更好的成语吗?
答案 0 :(得分:4)
我只是使用命令行和约定的组合。
如果指定了过滤器,请使用它来过滤数据
我假设你在命令行上指定了一个过滤器?那你要像这样调用这个应用程序吗?
ruby dataprocessor.rb custom_filter
如果是这样,你可以定义一个“api”,其中一个类名必须与传入的内容相匹配 - 几乎就是你在你的例子中所描述的。
为了更进一步,你可以使用ruby的CustomFilter
获得一些寻找defined?
类的逻辑,如果找不到,请去寻找custom_filter.rb
(或任何合适的变体)并尝试加载该文件,然后重试。
这为您提供了极大的可扩展性,因为您可以编写任意数量的过滤器类,将它们放在自己的.rb文件中,并将它们放在ruby可以找到的任何位置。您也不必具有预定义的常量,唯一的约束是
do_filter
方法顺便提一下,这非常类似于rails需要你的模型,这就是为什么你可以只使用SomeModel
而不必总是require app/models/some_model
首先:-)`
答案 1 :(得分:0)
看起来像Strategy Pattern的作业,因为ruby有functions as first-class objects,您可以传递过滤器函数以便由数组记忆,以便按需调用该自定义过滤器函数。 / p>
答案 2 :(得分:0)
# user code
USER_FILTER = lambda { |value| value != 0xDEADBEEF }
# script code
load( user_code );
FILTER = ( const_defined?(:USER_FILTER) ? USER_FILTER : lambda { true } )
output_array = input_array.filter(&FILTER)