使用切片!在变量上修改填充变量的节点属性
Using slice! on a variable is modifying the node attribute that populated the variable
在 OpsWorks Stacks 中,我使用自定义 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
是属性的 link 而不是它自己的变量,我尝试将它的值分配给一个单独的变量(install_certs_app_name
和其他食谱中的类似),但行为仍然存在.
这是 Ruby/Chef 中的预期行为吗?有没有更好的方法从属性中排除 app_
前缀?
当您将 app_name
分配给 install_certs_app_name
时,您仍然引用同一个对象。为了创建新对象,您可以这样做:
install_certs_app_name = app_name.dup
已创建具有相同值的新对象。并且切片 install_certs_app_name
不会影响 app_name
这种方式。
app_name
是直接修改。这就是方法后爆炸 !
的原因...这样您就知道该方法改变了对象。
和app_name
和install_certs_app_name
引用同一个对象。
请注意 slice
和 slice!
都是 return "app_" 但是 bang 对象通过删除切片文本来改变调用者。
如果你这样做了
结果 = install_certs_app_name.slice!('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_', '')
如果你想要一个变量切片,你会得到非破坏性版本:
str.slice
而不是 str.slice!
这些通常被称为 Bang 方法,并在适当的位置替换变量。
下面是 .downcase
方法的示例。这与 .slice
.
的原理相同
编辑:
但是,由于 .slice
returns 部分已被删除,您可以删除 app_
-部分 .sub
,例如
"app_manager".sub("app_",'') #=> "manager"
在 OpsWorks Stacks 中,我使用自定义 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
是属性的 link 而不是它自己的变量,我尝试将它的值分配给一个单独的变量(install_certs_app_name
和其他食谱中的类似),但行为仍然存在.
这是 Ruby/Chef 中的预期行为吗?有没有更好的方法从属性中排除 app_
前缀?
当您将 app_name
分配给 install_certs_app_name
时,您仍然引用同一个对象。为了创建新对象,您可以这样做:
install_certs_app_name = app_name.dup
已创建具有相同值的新对象。并且切片 install_certs_app_name
不会影响 app_name
这种方式。
app_name
是直接修改。这就是方法后爆炸 !
的原因...这样您就知道该方法改变了对象。
和app_name
和install_certs_app_name
引用同一个对象。
请注意 slice
和 slice!
都是 return "app_" 但是 bang 对象通过删除切片文本来改变调用者。
如果你这样做了
结果 = install_certs_app_name.slice!('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_', '')
如果你想要一个变量切片,你会得到非破坏性版本:
str.slice
而不是 str.slice!
这些通常被称为 Bang 方法,并在适当的位置替换变量。
下面是 .downcase
方法的示例。这与 .slice
.
编辑:
但是,由于 .slice
returns 部分已被删除,您可以删除 app_
-部分 .sub
,例如
"app_manager".sub("app_",'') #=> "manager"