Ruby Caesar Cipher解释
我正在努力构建一个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 )
-
初始化一个空字符串:
caesar_string = ""
-
迭代字符串中的每个字符(请注意,现在首选
string.each_char
):string.scan (/./) do |i|
请注意,所有Ruby样式指南都不鼓励方法调用和左括号之间的空格。
-
对于每个字母,检查其小写forms是否在“a”到“z”的范围内。
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
既不必要也不是惯用语。
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
的末尾, caesar_string
重建字符串一个字符。
return caesar_string
当string.scan (/./) do |i|
块已完成,返回caesar_string
。