【问题标题】:simple ruby plugin/extension architecture简单的 ruby​​ 插件/扩展架构
【发布时间】:2011-04-07 20:02:06
【问题描述】:

我目前正在编写一个小程序,它监视一个目录并将视频文件添加到转换队列中。我已经能够实现这一点(使用 resque)。

但在添加到转换队列之前,我想根据文件名触发特定操作。

例如:

  • 根据文件名删除(不添加到队列中)特定文件
  • 重命名文件
  • 复制某些文件

因此,我想在添加之前运行几个助手。我希望它们按特定顺序执行,并且我希望添加其他帮助程序变得容易。

我的想法是这样的:

每个助手都是一个带有一组方法的 ruby​​ 类:

  • 运行(执行助手)
  • new_name(如果更改,则返回新文件名)
  • stop(阻止跟随助手运行并阻止添加到 队列)

所有帮助程序都应存储在一个目录中,并按字母顺序运行(ext/00_helper1.rb、ext/01_helper2.rb...)。

伪代码如下所示:

filename = <parameter>
stop = false

for each file in ext/*.rb
 obj = asClass(file).new_instance(filename)
 obj.run
 if (obj.new_name) filename = obj.new_name
 if (obj.stop) 
  stop = true 
  break
 end
end

if not stop add_to_queue(filename)

所以我的问题是:

有没有优雅的红宝石方式?

【问题讨论】:

    标签: ruby scripting plugins


    【解决方案1】:

    在我的脑海中,我可以说一种可能的方法是拥有每个文件附加到的 Proc/lambda 对象的全局数组。所以一个帮助文件的例子是:

    $helpers << Proc.new do |filename|
      case filename
        when /.foo$/ then :stop
        when /.bar$/ then filename.sub(/.bar$/, '.baz') # and presumably rename the actual file as well ...
      end
    end
    

    然后你的主文件会是这样的:

    $helpers = []
    
    filename = <parameter>
    stop = false
    
    Dir.new(<helperdir>).entries.each do |name|
      require name
      result = $helpers.last.call(name)
      if result == :stop
        stop = true
        break
      end
      # using respond_to? :to_s would probably be better, but in this example :stop would match this criteria as well as strings
      filename = result if result.is_a? String
    end
    

    我还没有测试过这些,但希望你能大致了解一下。我也不知道你在 Ruby 上的流利程度,所以如果你不明白我使用的语法,请直说。

    【讨论】:

    • 是的,我明白了。但是我想知道这是否是线程安全的。当多个线程同时启动转换时,写入全局变量听起来不是一个好主意。
    猜你喜欢
    • 2010-12-17
    • 1970-01-01
    • 2020-11-07
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 2012-03-12
    相关资源
    最近更新 更多