首页 > 解决方案 > ruby-snmp:如何自动将响应转换为正确的类型?

问题描述

在 ruby​​ 中,我阅读了一些 SNMP 寄存器。响应是一个对象数组。

有没有一种很好的方法可以将每个对象转换为正确的类型,从而避免case..when在下面的代码中出现?由于类型已知,因此必须手动转换它看起来很奇怪:

require 'snmp'

HOST = '127.0.0.1'.freeze

registers = ['sysContact.0', 'sysUpTime.0',
             'upsIdentManufacturer.0', 'upsIdentModel.0', 'upsIdentName.0']

params_array = {}
SNMP::Manager.open(host: HOST) do |manager|
  manager.load_module('UPS-MIB')
  response = manager.get(registers)
  response.each_varbind do |vb|

    ##################################
    # change from here...

    value = nil
    case vb.value.asn1_type
    when 'OCTET STRING'        # <==========
      value = vb.value        
    when 'INTEGER'             # <==========
      value = vb.value.to_i
    when 'TimeTicks'           # <==========
      value = vb.value.to_s
    else
      puts "Type '#{vb.value.asn1_type}' not recognized!"
      exit(1)
    end
    params_array[vb.name.to_s] = value

    # ... to here
    ##################################

    # with something like
    # params_array[vb.name.to_s] = vb.value._to_its_proper_type_

  end
end
pp params_array

标签: rubysnmp

解决方案


查看gem repo中的代码,看起来没有这样的方法。我想您可以尝试对其进行修补,但不确定是否值得麻烦。

如果你不喜欢 switch 语法,你可以像这样使用哈希查找:

require 'snmp'

HOST = '127.0.0.1'.freeze

TYPE_VALUES = {
  'OCTET STRING' => :to_s,
  'INTEGER' => :to_i,
  'TimeTicks' => :to_s
}.freeze

registers = ['sysContact.0', 'sysUpTime.0',
             'upsIdentManufacturer.0', 'upsIdentModel.0', 'upsIdentName.0']

params_array = {}

SNMP::Manager.open(host: HOST) do |manager|
  manager.load_module('UPS-MIB')
  response = manager.get(registers)
  response.each_varbind do |vb|
    if method = TYPE_VALUES[vb.value.ans1_type]
      params_array[vb.name.to_s] = vb.value.send(method)
    else
      puts "Type '#{vb.value.asn1_type}' not recognized!"
      exit(1)
    end
  end
end
pp params_array

推荐阅读