Ruby向JSON数组追加元素报push方法nil类错误解决
问题原因
报错核心是Ruby Hash键类型不匹配:
network_sg.properties返回的Hash所有键均为字符串类型,从打印的输出可见securityRules是带双引号的字符串键,并非符号(Symbol)类型键。- Ruby Hash的字符串键和符号键是完全独立的两个键,执行
test[:securityRules]时实际查找的是键为符号:securityRules的值,该键不存在,因此返回nil。 - 对
nil值调用数组专属的push方法,就会抛出undefined method 'push' for nil:NilClass (NoMethodError)错误。
另外当前定义的新规则new_rule全部使用符号键,和原有规则的字符串键格式不一致,就算解决了访问报错,后续调用Azure接口更新安全组时也可能出现参数格式不兼容问题。
可行解决方案
方案1:直接使用字符串键访问(最推荐,无额外依赖)
直接用和返回结构一致的字符串键取securityRules数组,追加规则即可,同时把新规则的键统一改成字符串,和原有结构对齐:
# 新规则统一使用字符串键,和Azure返回结构格式一致 new_rule = { 'name' => 'rule_2', 'properties' => { 'protocol' => 'TCP', 'sourceAddressPrefix' => '*', 'destinationAddressPrefix' => '*', 'access' => 'Allow', 'destinationPortRange' => '22', 'sourcePortRange' => '*', 'priority' => '301', 'direction' => 'Inbound' } } # 用字符串键访问数组后追加 test["securityRules"] ||= [] # 兜底处理:如果该字段不存在则初始化为空数组,避免极端场景报错 test["securityRules"].push(new_rule)
方案2:转换Hash为不区分键类型的结构(适合Rails环境)
如果运行环境是Rails,可以直接把返回的属性Hash转换成不区分字符串/符号键的结构,之后用符号键访问也能正常取值:
# 转换为HashWithIndifferentAccess结构 test = test.with_indifferent_access # 此时用:securityRules或者"securityRules"都能正常取到数组 test[:securityRules].push(new_rule)
注意:纯Ruby环境没有with_indifferent_access方法,需要自行引入active_support组件才能使用。
内容的提问来源于stack exchange,提问作者user630702
相关产品推荐
相关产品推荐

