2017-08-11 51 views
1

在OpsWorks堆栈的节点属性,我已使用自定义JSON字段中设置层属性:使用切片!上的变量被修改填充可变

{ 
    "layer_apps" : [ 
    "app_manager" 
    ] 
} 

属性的app_部分是必要的工作流程。有时候,我需要暂时删除一本食谱中的app_部分。要做到这一点,我用slice!

node['layer_apps'].each do |app_name| 

    install_certs_app_name = app_name 
    install_certs_app_name.slice!('app_') # 'app_manager' => 'manager' 
    # snip 
end 

然而,一旦做到这一点,即使app_name没有被直接修改,每个node['layer_apps']属性被切成薄片,其进行后续的食谱,并导致故障。我期望的行为是slice!将修改app_name,而不是当前的node['layer_apps']属性。认为app_name是属性的链接,而不是它自己的变量,我试着将它的值赋给一个单独的变量(install_certs_app_name和其他食谱中的类似变量),但行为持续存在。

这是Ruby/Chef中的预期行为吗?有没有更好的方法可以从属性中排除app_前缀?

回答

3

app_name被直接修改。这就是在方法之后爆炸!的原因......所以你知道该方法会改变对象。

app_nameinstall_certs_app_name引用同一个对象。

请注意,sliceslice!都会返回“app_”,但爆炸对象会通过删除切片文本来改变调用者。 !

如果你没有

结果= install_certs_app_name.slice( 'APP_') 看跌导致 ==> APP_ 提出install_certs_app_name - >经理

尝试(代替)

install_certs_app_name = app_name.dup 
    install_certs_app_name.slice!('app_') 

所以你有两个单独的对象。

另外,

install_certs_app_name = app_name.sub('app_', '') 
+0

比ks的建议,@SteveTurczyn! 过去我曾尝试'install_certs_app_name = app_name.slice('app _')',但奇怪的是,ruby似乎返回被删除的字符串部分,而不是结果字符串。不过,我之前没有看过'.dup',所以我会试试看。 – TorpedoBench

+0

它已经工作了! '.dup'似乎有诀窍。 – TorpedoBench

+0

是的,我的头在云端......'slice'和'slice!'总是返回切片文本,所以'string ='abc'; result = string.slice('a')'和'string ='abc';结果= string.slice!('a')'在两种情况下'result'将具有“a”,但在第二个示例中,“string”中的对象被修改。 – SteveTurczyn

1

当您将app_name指定给install_certs_app_name时,仍然引用同一个对象。为了创建新对象,您可以执行以下操作:

install_certs_app_name = app_name.dup 

创建具有相同值的新对象。切片install_certs_app_name不会影响app_name这种方式。

2

如果你想要一个变量切片,你会是什么无损版本:

str.slice而不是str.slice!

这些通常被称为到Bang-methods,并替换变量。
以下是.downcase方法的示例。这与.slice的原理相同。

编辑:
然而,由于.slice返回一个已经切出的部分,你可以只取出app_ -part .sub

"app_manager".sub("app_",'') #=> "manager"

+0

谢谢!我确实尝试了非破坏性方法,但切片似乎特别返回了被删除的字符串部分,而不是保留的字符串。有没有一种合适的方法让非破坏性切片返回结果字符串? – TorpedoBench

+0

哦,对,让我用另一个选项更新我的答案。 –

+0

这是否适合你@TorpedoBench –