2017-08-11 83 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 –