2012-02-06 15 views
0

另一個工作轉換工作,我需要做什麼才能讓D)工作正常。最終D)將是一個密碼,但我想只是讓它適用於任何函數的每個字符(最下面是一個例子)。分組爲5個字符的桶是我正在開發的密碼的一部分。Ruby - 爲什麼不for_each不會請求小寫?收益/自我問題?

def keystream_converter(message, conversion) 
    case conversion.downcase 
    when 'lower_case' 
     message.upcase 
    when 'upper_case' 
     message.downcase 
    when 'special' 
     message.each_char { |ltr| ltr.downcase } 
    else 
     'invalid_conversion' 
    end 
end 

initial_src = "I see Ruby going 100 years!!" 
test_string = (initial_src.delete('^a-zA-Z') +"X"*(initial_src.length % 5)).scan(/.{5}/).to_s.upcase 
lower = keystream_converter(test_string, 'lower_case') 
upper = keystream_converter(test_string, 'upper_case') 
special = keystream_converter(test_string, 'special') 
# 
puts "A) - " + initial_src 
puts "B) - " + upper 
puts "C) - " + lower 
puts "D) - " + special 

輸出:

A) - I see Ruby going 100 years!! 
B) - ["iseer", "ubygo", "ingye", "arsxx"] 
C) - ["ISEER", "UBYGO", "INGYE", "ARSXX"] 
D) - ["ISEER", "UBYGO", "INGYE", "ARSXX"] 

回答

3

String#each_char產生原始字符串長度爲1的子字符串。如果您更改這些子字符串(即使使用downcase!而不是非變異的downcase),原始字符串也不會受到影響。如果你想使用each_char與塊,你可以做這樣的事情:

message.each_char.map(&:downcase).join 
+0

或換句話說,'ltr'是數據的一個新*副本,改變它對原文沒有影響。 – DGM 2012-02-06 19:45:46

+0

+1接受。這是我最喜歡的,儘管我也喜歡BaronVonBraun's(幾乎和我喜歡他的名字一樣多))。 – 2012-02-06 20:14:28

+0

這個答案很關鍵,因爲它提到了「收益率」,這是理解控制權在哪裏的一個關鍵概念。 'map'是滿足這些需求和'.join'(或者'result = message.each_char.map(&:downcase).join')的最佳選擇, – 2012-02-06 20:25:33

2

您對each_char調用返回原來的輸入字符串,而不是塊的結果。

例如,如果你在IRB這樣做:

"A STRING".each_char { |ltr| ltr.downcase } 
# => "A STRING" 

如果你想繼續使用each_char,你應該追加每個結果的一些變量,你以後可以返回,即,

# ... 
when 'special' 
    new_message = "" 
    message.each_char { |ltr| new_message += ltr.downcase } 
    new_message 
else 
# ... 
+0

+1我喜歡這個答案以英語開頭的一句話。我基本上希望我可以將它與Alex接受的那個結合起來,因爲他們都表達了很好的觀點。 – 2012-02-06 20:13:29

+0

這也是我將實際使用的選項,因爲它看起來比現在更容易編碼一組更復雜的操作,而不僅僅是''downcase'' – 2012-02-06 20:28:05

0

很奇怪,但無論如何。您可以將'特殊'情況更改爲:

message.each_char.map(&:downcase) * '' 
相關問題