需要一个文件,它也是一个带有自己的选项解析器的程序
Requiring a file that is also a program with it's own option parser
我的问题是:所需文件拦截了选项解析器。
我正在用 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没有选项,一切正常,但是自从我用optparse向connect.rb添加选项后,populate.rb中的选项解析器和update.rb 不再工作了。如果我 运行 'ruby populate.rb -h',它会显示 connect.rb 可用的选项,而不是 populate.rb 中的可用选项。如果我使用 connect.rb 接受的选项,例如“-t”,则该选项的执行就像在 connect.rb 中一样。如果我使用 connect.rb 不接受但 populate.rb 应该接受的选项,它会显示 "invalid option" 错误并退出。
基本上,我希望 connect.rb 当我 运行 它单独运行时与我在另一个文件中需要它时表现不同。当我 运行 它独奏时,我希望它接受选项并做事;但是当它在另一个文件中需要时,我只希望方法可用,并且我想要一组不同的选项。
这可能吗?有没有办法告诉它是如何被调用的,或者有其他方法来防止选项拦截?我在所有文件中都使用 optparse。
我解决类似问题的方法是检查文件是否像这样 运行 独奏:
# 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 [=10=] == __FILE__
最后一个条件 [=12=]
是一个 Ruby 全局设置为已执行文件的名称,__FILE__
是当前文件的名称。如果两者相同,那么您知道该文件是 运行ning solo,即 ruby connect.rb
。
使用该设置,您可以 运行 connect.rb
单人游戏,而且效果很好。然后,当您在其他文件中需要它时 populate.rb
您需要明确 运行 它:
# popoulate.rb
require 'connect'
Connect.run ARGV.dup # dup the commandline options in case other files mutate them
希望对您有所帮助。
好吧,当我写下我的问题时,我意识到我知道一个答案!
基本上将 'require connect.rb' 行移动到 在 选项被解析之后。所以我的 populate.rb 现在是这样的:
require "optparse"
Version = 1.4
# Parses command line arguments
options = {}
optparse = OptionParser.new do |opts|
# populate the options array according to the options
...
end
optparse.parse!
require "./connect_fb"
# start actual program
...
之所以可行,是因为我通过将选项存储在数组中将选项解析与大量代码分开,并且因为 connect.rb 如果在没有任何选项的情况下调用它,则不需要执行任何操作。我真的不明白为什么第一个调用的选项解析器是唯一有效的解析器。
我对离文件头部这么远的 'require' 行感到不舒服,所以我希望有更好的解决方案。
在测试了之前答案中的解决方案后,我得出了一个简单的解决方案:
您可以测试文件正在 运行 独奏
if [=10=] == __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 [=11=] == __FILE__
# code to be ran solo here
...
# also parse options here
options = {}
optparse = OptionParser.new do |opts|
...
end
optparse.parse!
# more code
...
end
这个解决方案基本上是 diego 答案的准系统版本。
我的问题是:所需文件拦截了选项解析器。
我正在用 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没有选项,一切正常,但是自从我用optparse向connect.rb添加选项后,populate.rb中的选项解析器和update.rb 不再工作了。如果我 运行 'ruby populate.rb -h',它会显示 connect.rb 可用的选项,而不是 populate.rb 中的可用选项。如果我使用 connect.rb 接受的选项,例如“-t”,则该选项的执行就像在 connect.rb 中一样。如果我使用 connect.rb 不接受但 populate.rb 应该接受的选项,它会显示 "invalid option" 错误并退出。
基本上,我希望 connect.rb 当我 运行 它单独运行时与我在另一个文件中需要它时表现不同。当我 运行 它独奏时,我希望它接受选项并做事;但是当它在另一个文件中需要时,我只希望方法可用,并且我想要一组不同的选项。
这可能吗?有没有办法告诉它是如何被调用的,或者有其他方法来防止选项拦截?我在所有文件中都使用 optparse。
我解决类似问题的方法是检查文件是否像这样 运行 独奏:
# 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 [=10=] == __FILE__
最后一个条件 [=12=]
是一个 Ruby 全局设置为已执行文件的名称,__FILE__
是当前文件的名称。如果两者相同,那么您知道该文件是 运行ning solo,即 ruby connect.rb
。
使用该设置,您可以 运行 connect.rb
单人游戏,而且效果很好。然后,当您在其他文件中需要它时 populate.rb
您需要明确 运行 它:
# popoulate.rb
require 'connect'
Connect.run ARGV.dup # dup the commandline options in case other files mutate them
希望对您有所帮助。
好吧,当我写下我的问题时,我意识到我知道一个答案!
基本上将 'require connect.rb' 行移动到 在 选项被解析之后。所以我的 populate.rb 现在是这样的:
require "optparse"
Version = 1.4
# Parses command line arguments
options = {}
optparse = OptionParser.new do |opts|
# populate the options array according to the options
...
end
optparse.parse!
require "./connect_fb"
# start actual program
...
之所以可行,是因为我通过将选项存储在数组中将选项解析与大量代码分开,并且因为 connect.rb 如果在没有任何选项的情况下调用它,则不需要执行任何操作。我真的不明白为什么第一个调用的选项解析器是唯一有效的解析器。
我对离文件头部这么远的 'require' 行感到不舒服,所以我希望有更好的解决方案。
在测试了之前答案中的解决方案后,我得出了一个简单的解决方案:
您可以测试文件正在 运行 独奏
if [=10=] == __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 [=11=] == __FILE__
# code to be ran solo here
...
# also parse options here
options = {}
optparse = OptionParser.new do |opts|
...
end
optparse.parse!
# more code
...
end
这个解决方案基本上是 diego 答案的准系统版本。