Ruby错误 - ' +':没有将Fixnum隐式转换为String(TypeError)

时间:2015-03-03 00:33:58

标签: ruby error-handling encryption

这一行引发了错误:

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

2 个答案:

答案 0 :(得分:1)

您正在尝试添加shift,它是字符串的Fixnum。只需在班次上调用to_s即可将其转换为字符串:

charLine.each_index { |i| charLine[i] = (charLine[i] + shift.to_s)}

答案 1 :(得分:0)

我设法重现了这个问题,通过一些调试输出,我可以看到第一次迭代运行正常,问题只出现在第二次迭代(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")