要求一个文件也是一个程序,它有自己的选项解析器

时间:2016-11-04 17:53:51

标签: ruby require optparse

我的问题是:所需的文件拦截了选项解析器。

我正在用3个文件编写一个ruby程序,一个(connect.rb)处理与某个站点的连接,另一个2(populate.rb和update.rb)需要第一个从中收集数据站点。

可以运行connect.rb来配置和测试连接,如下所示:

$ruby connect.rb --adduser myuser -p 1234 --test
Created user myuser
Connecting as myuser...
Connection test OK

另一方面,populate.rb有一个'require connect.rb'行,但它也可以运行并拥有它自己的选项。

过去,connect.rb没有选项,而且一切正常,但是由于我将connect.rb的选项添加到optparse,populate.rb和update.rb中的选项解析器不再起作用了。如果我运行'ruby populate.rb -h',它会显示connect.rb可用的选项,而不是populate.rb中的选项。如果我使用connect.rb接受的选项,比如'-t',则执行该选项就好像在connect.rb中一样。如果我使用connect.rb不接受的选项,但populate.rb应该,它会显示“无效选项”错误并退出。

基本上,我希望connect.rb在我从另一个文件中需要时单独运行时表现不同。当我单独运行它时,我希望它接受选项并做事;但是当它在另一个文件中需要时,我只想要方法可用,我想要一组不同的选项。

这甚至可能吗?有没有办法告诉它是如何被调用的,或者其他一些方法来防止选项拦截?我在我的所有文件中都使用了optparse。

3 个答案:

答案 0 :(得分:0)

我解决类似问题的方法是检查文件是否像这样单独运行:

# connect.rb    

# wrap logic in a module
module Connect
  def self.run(args: ARGV)
    args # access to command line options
  end
end

# run if solo
Connect.run if $0 == __FILE__

在最后一个条件$0中,Ruby全局设置为已执行文件的名称,__FILE__是当前文件的名称。如果两者相同,则表示文件正在单独运行,即ruby connect.rb

使用该设置,您可以运行connect.rb solo并且它可以正常工作。然后,当您在其他文件populate.rb中需要它时,您需要明确地运行它:

# popoulate.rb
require 'connect'
Connect.run ARGV.dup # dup the commandline options in case other files mutate them

希望有所帮助。

答案 1 :(得分:0)

好的,所以当我写我的问题时,我意识到我知道一个答案!

在解析选项后,基本上将'require connect.rb'行移至。所以我的populate.rb现在是这样的:

str1 <- c("Apr 11", "Apr 11 2015")
str2 <- c("Apr 11", "11 Apr 2015")

这是有效的,因为我通过将选项存储在数组中而将选项解析与大部分代码分离,并且因为如果没有任何选项调用connect.rb则不需要执行任何操作。我真的不明白为什么首先调用的选项解析器是唯一有效的解析器。

我觉得距离文件头部的'require'行感到不舒服,所以我希望有更好的解决方案。

答案 2 :(得分:0)

在测试了之前答案中提出的解决方案之后,我找到了一个简单的解决方案:

您可以使用

测试文件正在单独运行
if $0 == __FILE__

所以我把所有的解析都放到这样的if块中:

# connect.rb
# code to be ran when required
...
class connect
    ....
end

# the following will only be executed if this script is ran solo
if $0 == __FILE__
    # code to be ran solo here
    ...
    # also parse options here
    options = {}
    optparse = OptionParser.new do |opts|
        ...
    end
    optparse.parse!
    # more code
    ...
 end

这个解决方案基本上是diego答案的准系统版本。