如何选择在Ruby中动态包含哪个版本的模块? [英] How can I choose which version of a module to include dynamically in Ruby?

查看:100
本文介绍了如何选择在Ruby中动态包含哪个版本的模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个小型Ruby命令行应用程序,它使用标准库中的 fileutils 进行文件操作。根据用户调用应用程序的方式,我希望包含 FileUtils FileUtils :: DryRun FileUtils :: Verbose

I'm writing a small Ruby command-line application that uses fileutils from the standard library for file operations. Depending on how the user invokes the application, I will want to include either FileUtils, FileUtils::DryRun or FileUtils::Verbose.

由于 include 是私有的, ,我不能把逻辑选择到对象的 initialize 方法中。 (这是我的第一个想法,从那以后我可以将有关用户选择的信息作为参数传递给 new 。)我想出了两个看似似乎的选项工作,但我不满意:

Since include is private, though, I can't put the logic to choose into the object's initialize method. (That was my first thought, since then I could just pass the information about the user's choice as a parameter to new.) I've come up with two options that seem to work, but I'm not happy with either:


  1. 根据用户的选择在应用程序的命名空间中设置一个全局变量,然后在课堂上做一个条件包括:

  1. Set a global variable in the app's namespace based on the user's choice, and then do a conditional include in the class:

class Worker
  case App::OPTION
  when "dry-run"
    include FileUtils::DryRun
    etc.


  • 创建子类,唯一的区别是它们包含哪个版本的 FileUtils 。根据用户的选择选择合适的一个。

  • Create sub-classes, where the only difference is which version of FileUtils they include. Choose the appropriate one, depending on the user's choice.

    class Worker
      include FileUtils
      # shared Worker methods go here
    end
    class Worker::DryRun < Worker
      include FileUtils::DryRun
    end
    class Worker::Verbose < Worker
      include FileUtils::Verbose
    end
    


  • 第一种方法似乎是DRY-er,但我希望有一些我没有想过的更直接的东西。

    The first method seems DRY-er, but I'm hoping that there's something more straightforward that I haven't thought of.

    推荐答案

    那么如果它是私有的呢?

    So what if it's private?

    class Worker
      def initialize(verbose=false)
        if verbose
          (class <<self; include FileUtils::Verbose; end)
        else
          (class <<self; include FileUtils; end)
        end
        touch "test"
      end
    end
    

    这包括 FileUtils :: something 特别是 Worker 的元类 - 不在主工作者中 class。不同的工作人员可以这种方式使用不同的 FileUtils

    This includes FileUtils::something in particular's Worker's metaclass - not in the main Worker class. Different workers can use different FileUtils this way.

    这篇关于如何选择在Ruby中动态包含哪个版本的模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆