Ruby 错误 - '+': 没有将 Fixnum 隐式转换为字符串 (TypeError)
Ruby error - '+': no implicit conversion of Fixnum into String (TypeError)
这一行抛出错误:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
编辑:charLine[i]
是一个数字(ascii码),shift
也是一个数字
我知道这与尝试将变量 shift 中的数字添加到我在 charLine 数组索引中的字节 ascii 代码有关。但我什至根本不处理字符串,这就是为什么我对这个错误如此困惑......这是错误的方法:
def caesarCipher(string)
puts "Original:\n #{string}"
charLine = string.chars
charLine.each_index { |i| charLine[i]=charLine[i].bytes }
charLine.flatten!
puts charLine.inspect
shift = 1
alphabet = ('A'..'Z').to_a
while shift <= alphabet.size
#moving up in the alphabet using ascii code
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
puts "Shifted:\n #{charLine.inspect}"
puts "With a letter shift of #{shift}"
shift = shift + 1
@@shiftyArray.push(charLine.flatten)
end
end
您正在尝试添加 shift
,这是一个字符串的 Fixnum。只需在 shift 上调用 to_s
即可将其转换为字符串:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift.to_s)}
我已经成功地重现了这个问题,并且通过一些调试输出我可以看到第一次迭代运行良好,问题只出现在第二次迭代 (shift = 2) 上。
在第一次迭代中,charLine 是一个 整数数组 ,因此整数 + 整数可以很好地处理这一行:charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
但是随后在循环的下一行将 charLine 转换为字符串数组:
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
所以在第二次迭代开始时,charLine 现在是一个字符串数组,因为它没有被转换回来。然后在 .each_line 上,它尝试将字符串 + 整数相加,结果爆炸了。
解决方案是在每次迭代开始时将字符串数组重新映射为整数。
charLine.map!(&:ord)
另一种方法是不修改数组并将结果保存到临时变量中,这是一个工作示例:
def caesar_cipher(string)
shiftyArray = []
charLine = string.split(//)
charLine.map!(&:ord)
shift = 1
alphabet_size = 26
while shift <= alphabet_size
shifted_array = charLine.map { |c| (c + shift) < 122 ? (c + shift) : (c + shift) - 26 }
shifted_array.map!(&:chr)
p shifted_array
shift += 1
shiftyArray.push(shifted_array.join)
end
end
caesar_cipher("testing")
这一行抛出错误:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
编辑:charLine[i]
是一个数字(ascii码),shift
也是一个数字
我知道这与尝试将变量 shift 中的数字添加到我在 charLine 数组索引中的字节 ascii 代码有关。但我什至根本不处理字符串,这就是为什么我对这个错误如此困惑......这是错误的方法:
def caesarCipher(string)
puts "Original:\n #{string}"
charLine = string.chars
charLine.each_index { |i| charLine[i]=charLine[i].bytes }
charLine.flatten!
puts charLine.inspect
shift = 1
alphabet = ('A'..'Z').to_a
while shift <= alphabet.size
#moving up in the alphabet using ascii code
charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
puts "Shifted:\n #{charLine.inspect}"
puts "With a letter shift of #{shift}"
shift = shift + 1
@@shiftyArray.push(charLine.flatten)
end
end
您正在尝试添加 shift
,这是一个字符串的 Fixnum。只需在 shift 上调用 to_s
即可将其转换为字符串:
charLine.each_index { |i| charLine[i] = (charLine[i] + shift.to_s)}
我已经成功地重现了这个问题,并且通过一些调试输出我可以看到第一次迭代运行良好,问题只出现在第二次迭代 (shift = 2) 上。
在第一次迭代中,charLine 是一个 整数数组 ,因此整数 + 整数可以很好地处理这一行:charLine.each_index { |i| charLine[i] = (charLine[i] + shift)}
但是随后在循环的下一行将 charLine 转换为字符串数组:
#converting back to letters
charLine.each_index { |x| charLine[x] = charLine[x].chr }
所以在第二次迭代开始时,charLine 现在是一个字符串数组,因为它没有被转换回来。然后在 .each_line 上,它尝试将字符串 + 整数相加,结果爆炸了。
解决方案是在每次迭代开始时将字符串数组重新映射为整数。
charLine.map!(&:ord)
另一种方法是不修改数组并将结果保存到临时变量中,这是一个工作示例:
def caesar_cipher(string)
shiftyArray = []
charLine = string.split(//)
charLine.map!(&:ord)
shift = 1
alphabet_size = 26
while shift <= alphabet_size
shifted_array = charLine.map { |c| (c + shift) < 122 ? (c + shift) : (c + shift) - 26 }
shifted_array.map!(&:chr)
p shifted_array
shift += 1
shiftyArray.push(shifted_array.join)
end
end
caesar_cipher("testing")