我正在努力构建一个Caesar Cipher作为代码练习。我发现了一些代码片段并且它们有效,但我不明白为什么它有用,并且想知道是否有人可以解释为什么它一块一块地工作。这将有助于Ruby中的新手通过查看代码的实际实现来理解各种类型代码的构建块。
以下是代码:
def caesar_cipher (string, number)
caesar_string = ""
string.scan (/./) do |i|
if ("a".."z").include? (i.downcase) # Identify letters only.
number.times {i = i.next}
end
caesar_string << i[-1]
end
return caesar_string
end
print "What would you like to encrypt?"
text = gets.chomp
puts caesar_cipher( text, 5 )
答案 0 :(得分:2)
初始化一个空字符串:
caesar_string = ""
迭代字符串中的每个字符(请注意,string.each_char
现在是首选):
string.scan (/./) do |i|
请注意,所有Ruby样式指南都不鼓励方法调用和左括号之间的空格。
对于每个字母,检查其小写形式是否在&#34; a&#34;到&#34; z&#34;。
if ("a".."z").include? (i.downcase)
请注意,在循环外定义该范围(即LOWERCASE_LETTERS = ("a"..."z")
会更好,因为它避免了在每次迭代时生成一次性范围对象)。
转移number
次字母:
number.times {i = i.next}
这是有效的,因为"a".next == "b"
虽然没有所有迭代,但(i.ord + number).chr
之类的东西也可以实现。
该字符已添加到之前初始化的caesar_string
。
caesar_string << i[-1]
作者仅使用[-1]
以来字符串的最后一个字符"z".next == "aa"
。
返回字符串。
return caesar_string
请注意,此处使用return
既不必要也不是惯用语。
答案 1 :(得分:2)
string.scan (/./)
将创建字符串中每个字符的数组,然后迭代每个字符。
if ("a".."z").include? (i.downcase)
上述语句使用Range
创建字母表中的字母数组,并允许该方法仅移动字母表中的字符并跳过不应移位的数字和标点字符。
number.times {i = i.next}
这将字母向右移动了5次。但是,如果i
为"z"
,i.next
将返回"ae"
,那么下一行
caesar_string << i[-1]
仅获取字符串中的最后一个字符,并在此边缘情况下切断“a”。
在大多数情况下,i
将是单个字符,[ - 1]是唯一的字符,因此它适用于两种情况。 <<
运算符将字符拖到caesar_string
的末尾,以便一次重建字符串一个字符。
return caesar_string
string.scan (/./) do |i|
块完成后,将返回caesar_string
。