编写一个ruby命令行应用程序;最好的办法吗?

时间:2008-10-30 19:33:55

标签: ruby idioms

我正在开发一个命令行Ruby应用程序,我希望允许它的用户提供代码,该代码将作为过程的一部分进行过滤。基本上,应用程序执行此操作:

  1. 读入一些数据
  2. 如果指定了过滤器,则使用它来过滤数据
  3. 处理数据
  4. 我希望过滤过程(第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中有更好的成语吗?

3 个答案:

答案 0 :(得分:4)

我只是使用命令行和约定的组合。

  

如果指定了过滤器,请使用它来过滤数据

我假设你在命令行上指定了一个过滤器?那你要像这样调用这个应用程序吗?

ruby dataprocessor.rb custom_filter

如果是这样,你可以定义一个“api”,其中一个类名必须与传入的内容相匹配 - 几乎就是你在你的例子中所描述的。

为了更进一步,你可以使用ruby的CustomFilter获得一些寻找defined?类的逻辑,如果找不到,请去寻找custom_filter.rb(或任何合适的变体)并尝试加载该文件,然后重试。

这为您提供了极大的可扩展性,因为您可以编写任意数量的过滤器类,将它们放在自己的.rb文件中,并将它们放在ruby可以找到的任何位置。您也不必具有预定义的常量,唯一的约束是

  1. 类名必须匹配(文件名的一个变体) - 这是ruby中的惯例,所以你可能已经在做了。
  2. 必须有一些预定义的方法,例如do_filter方法
  3. 顺便提一下,这非常类似于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)