将元组传递给ruby hash

时间:2017-12-31 15:07:45

标签: ruby hash tuples

我目前正在使用案例陈述来确定正确的流量。 它看起来像这样:

case os
  when 'windows'
  # If Windows - Call code for WinRM connection
  when 'redhat'
  # If Redhat - Call code for SSH connection
    if env == 'pci'
      # Do stuff for PCI
      exec_pci
    else
      # Do stuff for non PCI
      exec_non_pci
    end
  else
    # Raise some exception
end

我知道哈希/词典使用单个键来查找值,但是是否可以设置查找哈希表,我可以将其传递给元组?

我希望做这样的事情:

os = 'redhat'
env = 'pci'

我要拨打以下内容:my_hash[(os, env)]并期望收到返回的值exec_pci

2 个答案:

答案 0 :(得分:3)

这里的怪物是原始代码中的else子句。如果你可以摆脱它,那么你可以为查找做一个哈希。

my_hash = {
  ['windows', nil] => -> { exec_windows },
  ['redhat', 'pci'] => -> { exec_pci },
  ['redhat', 'non_pci'] => -> { exec_non_pci }
}

os, env = 'windows', nil

my_hash[[os, env]].call

请注意,按键查询哈希值需要完全匹配,例如,如果os'windows',则env必须为nil,否则您需要&#39 ;得到NoMethodError告诉您nil没有名为call的方法。您可以使用Hash#fetch

更早地抛出此错误
my_hash.fetch([os, env]).call

另一个需要注意的是,您必须在应该调用作业(例如my_hash)的同一范围内定义exec_pci,否则您可能无法正确调用这些方法。

答案 1 :(得分:0)

我建议你这样做。

def doit(os, *ssh)
  case os
  when 'windows'
    puts "os = 'windows'" # remove when debugged
    raise ArgumentError unless ssh.empty?
    # Call code for WinRM connection
  when 'redhat'
    puts "os = 'redhat'" # remove when debugged
    puts "ssh = #{ssh}" # remove when debugged
    raise ArgumentError unless ssh.size == 1
    # Call code for SSH connection
    if ssh.first == 'pci'
      # Do stuff for PCI
      exec_pci
    else
      # Do stuff for non PCI
      exec_non_pci
    end
  else
    puts "os != 'windows' and os != 'redhat'" # remove when debugged
    # Raise an exception
    raise StandardError
  end
end

def exec_pci
  puts "exec_pic called"
end

def exec_non_pci
  puts "exec_non_pic called"
end

doit 'windows'
  #-> os = 'windows'
doit 'windows', 'cat'
  #-> os = 'windows'
  #=> ArgumentError: ArgumentError
doit 'redhat', 'pci'
  #-> os = 'redhat'
  #-> ssh = ["pci"]
  #-> exec_non_pic called
doit 'redhat', 'cat'
  #-> os = 'redhat'
  #-> ssh = ["cat"]
  #-> exec_non_pic called
doit 'redhat'
  #-> os = 'redhat'
  #-> ssh = []
  #=> ArgumentError: ArgumentError
doit 'redhat', 'cat', 'dog'
  #-> os = 'redhat'
  #=> ssh = ["cat", "dog"]
  #=> ArgumentError: ArgumentError
doit 'cat'
  #-> os != 'windows' and os != 'redhat'
  #=> StandardError: StandardError

如果假定exec_pciexec_non_pci是未说明的方法。如果它们是问题中未显示的局部变量,则需要修改方法doit以便调用它,例如,

doit 'redhat', 'pci', exec_pic

要调用doit('windows', arg),其中arg是未使用的人为值(例如,nil),在我看来是糟糕的编程习惯。