【问题标题】:Script a ruby command-line app; best way to do this?编写一个 ruby​​ 命令行应用程序;最好的方法是什么?
【发布时间】:2010-09-20 01:39:32
【问题描述】:

我有一个正在开发的命令行 Ruby 应用程序,我希望它的用户提供将作为过滤器运行在部分流程上的代码。基本上,应用程序会这样做:

  1. 读入一些数据
  2. 如果指定了过滤器,则使用它来过滤数据
  3. 处理数据

我希望过滤过程(第 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 中有更好的成语吗?

【问题讨论】:

    标签: ruby idioms


    【解决方案1】:

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

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

    我假设您会在命令行上指定一个过滤器?所以你会像这样调用应用程序?

    ruby dataprocessor.rb custom_filter
    

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

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

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

    1. 类名必须匹配文件名(的变体) - 这是 ruby​​ 中的约定,因此您可能已经在这样做了。
    2. 它必须有一些预定义的方法,例如你的do_filter 方法

    顺便说一句,这与 rails 对模型的要求非常相似,这就是为什么您可以只使用 SomeModel 而不必总是先使用 require app/models/some_model :-)`

    【讨论】:

    • 比我的一般答案实用得多。 +1
    【解决方案2】:
    # 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)
    

    【讨论】:

      【解决方案3】:

      看起来像 Strategy Pattern 的工作,由于 ruby​​ 有 functions as first-class objects,您可以传递过滤器函数以由数组存储,以便按需调用该自定义过滤器函数。

      【讨论】:

        猜你喜欢
        • 2011-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        • 2010-10-06
        • 2011-12-24
        • 1970-01-01
        相关资源
        最近更新 更多