Ruby 为什么忽略了最上面的if条件?

Ruby 为什么忽略了最上面的if条件?,ruby,conditional,optparse,Ruby,Conditional,Optparse,我承认我对Ruby还是新手,所以我还不熟悉gotcha's,还在学习 我在谷歌上搜索了很多次,但都没有找到确切的答案。大多数结果都讨论“嵌套的”if/else语句。这不是我要尝试的。我从SO那里找到了另一个答案,谈到了基于条件映射数组,但我觉得这会让我回到我已经遇到的问题 如果有人感兴趣,请链接到有关合并嵌套数组的SO文章: 我的问题: 在ruby中设计一个简单的CLI脚本时,使用optpass根据条件控制输出。我遇到了一个问题,我无法执行多个顺序if语句,无法将多个数组合并到一个数组中以传递

我承认我对Ruby还是新手,所以我还不熟悉gotcha's,还在学习

我在谷歌上搜索了很多次,但都没有找到确切的答案。大多数结果都讨论“嵌套的”if/else语句。这不是我要尝试的。我从SO那里找到了另一个答案,谈到了基于条件映射数组,但我觉得这会让我回到我已经遇到的问题

如果有人感兴趣,请链接到有关合并嵌套数组的SO文章:

我的问题:

在ruby中设计一个简单的CLI脚本时,使用optpass根据条件控制输出。我遇到了一个问题,我无法执行多个顺序if语句,无法将多个数组合并到一个数组中以传递给另一个函数

出于某种原因,只有最后一个块被执行。最后一个前的所有if块返回nil

有没有人能告诉我我做错了什么,并提供一些关于我的问题的相关文档。比如为什么会出现这样的问题

我希望有一个可行的解决方案可以学习,但参考资料也可以,因为我的目标是从这个问题中学习

我的测试结果:

$ ruby servers.rb
#=> ["server1", "server2", "server3"]
$ ruby servers.rb -m
#=> nil
$ ruby servers.rb -h
#=> nil
$ ruby servers.rb -s server6
#=> ["server6"]
$ ruby servers.rb -m -h
#=> nil
以下是我的脚本:

#!/usr/bin/env ruby
require 'optparse'

@servers = {
  'primary' => %w[server1 server2 server3],
  'inhouse' => %w[server4 server5],
  'mlm' => %w[server6]
}

@options = {
  inhouse: false,
  server: [],
  mlm: false
}

# Parse options passed to medusabackup.rb
optparse = OptionParser.new do |opts|
  opts.on('-h', '--inhouse', 'Limit results to inhouse results') do
    @options[:inhouse] = true
  end
  opts.on('-m', '--mlm', 'Include mlm results') do
    @options[:mlm] = true
  end
  opts.on('-s', '--server=SERVER', 'Limit results to SERVER') do |f|
    @options[:server] << f
  end
  opts.on_tail('--help', 'Display this screen') { puts opts, exit }
end

begin
  optparse.parse!
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
  puts $ERROR_INFO.to_s
  puts optparse
  exit
end

def selected_servers
  # Setup Selected variable as an array
  selected = []
  # If @options[:server]  array is not empty and @options[:server]
  # add @options[:server] servers to [selected] array
  if @options[:server].empty?
    # If @options[:mlm] is true add @server['mlm'] servers to [selected] array
    selected.concat @servers['mlm'] if @options[:mlm]
    # If @options[:inhouse] is true add @server['inhouse'] servers to [selected] array
    selected.concat @servers['inhouse'] if @options[:inhouse]
    # If @options[:mlm], @options[:inhouse] is true add @server['mlm'] servers to [selected] array
    selected.concat @servers['primary'] unless @options[:mlm] || @options[:inhouse]
  else
    selected.concat @options[:server]
  end
end
puts selected_servers.inspect
#/usr/bin/env ruby
需要“optpass”
@服务器={
“主服务器”=>%w[server1 server2 server3],
“内部”=>%w[server4 server5],
“传销”=>%w[server6]
}
@选项={
内部:错误,
服务器:[],
传销:假
}
#解析传递到medusabackup.rb的选项
optparse=OptionParser.new do | opts|
选项on('-h','-inhouse',将结果限制为inhouse结果)do
@选项[:内部]=真
结束
选项('-m','-mlm',包括mlm结果)do
@选项[:传销]=真
结束
opts.on('-s','-server=server','limitresultstoserver')do | f|

@选项[:server]在所选的
服务器中没有显式返回,因此它返回它运行的最后一个表达式的值,这通常是失败的
,除非
。失败的if/除非返回
nil

请查看网站的“帮助”部分,了解A的概念。这是演示您的问题的最短示例吗?此代码的行为与您在“使用”部分中显示的不同。提示:您的
所选的\u服务器
返回一些内容,但不是您期望的内容。@pjs-我道歉。我在代码中留下了一个未使用的条件块。移除它。将代码简化为仅受影响的函数。@SergioTulentsev对此表示抱歉。(让每个人都开心是很难的。)添加回原始的optsparse代码。可以确认原样是可以复制粘贴运行的。(将在下次学习)当所讨论的
if
被伪装成
除非
,这不是有点误导吗?@muistooshort:对我个人来说,
除非总是让我停下来重新阅读几次条件。这真的是我想的吗?真正地多次被双重否定灼伤:)@SergioTulentsev同样,我必须重写
,除非cond
如果!cond
在我的脑海中,所以我不使用它(除了
excel::method\u name
表单和各种Rails宏,但即使这样,我也倾向于编写一个额外的方法,以便我可以使用
if:
)。这种特殊情况甚至更为隐蔽,因为在
if
中有一个后缀
except
,而整个表达式最终是方法调用的值。