Ruby pack - TypeError:无法将String转换为Integer

时间:2013-02-25 18:15:20

标签: ruby-on-rails ruby ruby-on-rails-3.2 jruby

我收到了TypeError: can't convert String into Integer,我也找到了重复的答案,但我在'pack'时遇到了这个错误。

其他混淆是,它与ruby 1.8.7合作正常,而不是ruby 1.9.3,这是代码,我正在使用jruby1.7.2

irb(main):003:0> length=nil
=> nil
irb(main):004:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):005:0> token =  (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.pack("c*")
TypeError: can't convert String into Integer
    from (irb):5:in `pack'
    from (irb):5
    from /home/appandya/.rvm/rubies/ruby-1.9.3-p374/bin/irb:13:in `<main>'
irb(main):006:0>

任何想法?

3 个答案:

答案 0 :(得分:2)

string[x]中的{p> Ruby 1.8会为您提供Fixnum(字符代码),而1.9会为您提供single character string

Array#pack将数组转换为二进制序列。要打包的“c *”模板将一个Ruby整数数组转换为一个8位有符号字的流。

以下是解决方案,这些解决方案来自Google网上论坛

<强> 1

背景
>> %w(a b c).pack('*c')
TypeError: can't convert String into Integer
        from (irb):1:in `pack'
        from (irb):1
        from /usr/bin/irb:12:in `<main>'
>> [1, 2, 3].pack('*c')
=> "\x01"
>> %w(a b c).map(&:ord).pack('*c')
=> "a"
irb(main):001:0> length=nil
=> nil
irb(main):002:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):003:0> (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.map(&:ord).pack("c*")
=> "rd!:!LcxU3ON57*t2s520v*zvvdflSNAgU6uq14SiD00VUDlm9:4:tJz5Ri5o"
irb(main):004:0>

<强> 2

String's []函数的返回类型为Fixnum 1.8String1.9

>JRUBY_OPTS=--1.9 ruby -e "puts 'a'[0].class"
String

>JRUBY_OPTS=--1.8 ruby -e "puts 'a'[0].class"
Fixnum

JRuby 1.7.x默认为Ruby 1.9.3。您需要设置JRUBY_OPTS

第3

尝试join而不是pack

irb(main):004:0> length=nil
=> nil
irb(main):005:0> token_string ||= ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!$:*)
=> "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$:*"
irb(main):006:0> token =  (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.join("c*")
=> "Fc*Dc*1c*6c*ac*Kc*Tc*Qc*Hc*jc*Ec*Kc*kc*zc*sc*3c*ic*hc*kc*wc**c*Wc*$c*Kc*Ic*Uc*Cc*bc*Pc*1c*!c*mc*Bc*lc*dc*ic*Dc*sc*Ac*Bc*nc*Kc*mc*Lc*oc*Zc*Xc*jc*6c*2c*Uc*ec*Yc*Dc*vc*Ic*Uc*5c*Zc*3c*o"
irb(main):007:0>

<强> 4

如果您只想创建一个8位清洁的随机字符串,您可能需要查看Random#bytes和类似Base64.encode64的内容。

<强> 5

active_support / secure_random 也为这些内容提供了一个很好的API

答案 1 :(得分:0)

我建议你看一下:Array Method Pack,基本上.pack("c")期望数组的元素是整数。您可以尝试.pack("a*")

答案 2 :(得分:0)

使用token = (0..(length ? length : 60)).collect { token_string[rand( token_string.size)]}.pack("a"*61)

你得到相同的结果。我使用的是61,因为从0..60开始有61个元素。