OpsWorks Ruby返回nil进行有效的正则表达式测试

时间:2017-09-11 19:33:03

标签: ruby regex chef aws-opsworks

在OpsWorks中,我尝试在给定节点的主机名上测试数字后缀,如果不是,则提取该数字1.如果数字不是1,我是有这个正则表达式匹配数字:

/([\d]+)$­/

针对遵循此模式的节点命名方案运行:

  • 节点1
  • 节点2
  • 节点3
  • 节点(N ...)

我已使用Rubular验证了这项工作:http://rubular.com/r/Ei0kqjaxQn

但是,当我使用OpsWorks对一个实例运行此操作时,无论主机名在末尾有多少,此匹配都返回nil。 OpsWorks代理版本是撰写本文时的最新版本(4023),使用Chef 12.13.37。

这是使用匹配号码的食谱中的代码:

short_app_name.to_s + node['hostname'][/([\d]+)$­/, 1].to_s + '.' + app['domains'].first

运行失败,类型错误为no implicit conversion of nil into String。但是,在检查节点的数字后缀时,正则表达式会对配方中较早的属性进行搜索。我应该使用不同的方法来提取节点的后缀吗?

编辑:app['domains'].first已填充。如果与domain.com交换出来,此行仍然会失败并出现相同的类型错误。

3 个答案:

答案 0 :(得分:1)

根据菜谱代码和错误消息判断,问题可能是app['domains']在运行期间是一个空数组。因此,您可能需要验证其值是否正确。

答案 1 :(得分:1)

当我复制你的正则表达式并将其粘贴到我的终端进行测试时,在正则表达式末尾的美元符号之后有一个软连字符,删除它会使事情有效:

即使我从终端复制网站,该网站也没有显示,但屏幕截图显示了问题:

enter image description here

第二行(' irb(主要):002:0')是我从你的食谱代码中复制/粘贴的,字符是"\xc2\xad"

答案 2 :(得分:0)

你的错误与正则表达式无关。 问题是当您尝试将现有String

连接时
app['domains'].first

这是唯一可以引发此错误的地方,因为即使您String#slice返回nil您正在呼叫to_s所以它是空String但{{1}如果String nil app['domains'].first会引发此错误,则会出现+ nil

击穿

#short_app_name can be nil because of explicit #to_s
short_app_name.to_s 
####
# assuming node is a Hash
# node must have 'hostname' key 
# or NoMethodError: undefined method `[]' for nil:NilClass wil be raised
# node['hostname'][/([\d]+)$­/, 1] can be nil because of explicit #to_s
node['hostname'][/([\d]+)$­/, 1].to_s 
#####
# assuming app is a Hash
# app must contain 'domains' key and the value must respond to first
# and the first value must be a String or be implicitly coercible (#to_str) or it will fail with 
# TypeError: no implicit conversion of ClassName into String
# could explicitly coerce (#to_s) like you do previously  
app['domains'].first

示例:

node = {"hostname" => 'nodable'}
app = {"domains" => []}
node['hostname'][/([\d]+)$­/, 1]
#=> nil
node['hostname'][/([\d]+)$­/, 1].to_s
#=> ""
app["domains"].first
#=> nil
node['hostname'][/([\d]+)$­/, 1].to_s + '.' + app["domains"].first
#=> TypeError: no implicit conversion of nil into String
node = {"hostname" => 'node2'}
app = {"domains" => ['here.com']}
node['hostname'][/([\d]+)$­/, 1].to_s + '.' + app["domains"].first
#=> "2.here.com"