为什么会出现这种红宝石用\\ U001 1,如何改变?(Why does this ruby use

2019-10-21 03:34发布

我写的经典fizzbuzz代码。

该规范:

describe "can determine fizzbuxx output for" do
  it "3" do
    expect(Fizzbuzz.nums(3)).to eq "123fizz"
  end 
end

编码:

class Fizzbuzz
  def self.nums(n)
    result=""
    (1..n).each do |inner|
      puts "inner #{inner}"
      result << inner
      if (inner % 3)==0
        result << 'fizz'
      end
      if (inner % 5)==0
        result << 'buzz'
      end
    end
    result
  end
end

为什么我会得到\u001 ......而不是1

Failures:

1) can determine fizzbuxx output for 3
 Failure/Error: expect(Fizzbuzz.nums(3)).to eq "123fizz"

   expected: "123fizz"
        got: "\u0001\u0002\u0003fizz"

   (compared using ==)
 # ./fizzbuzz_spec.rb:5:in `block (2 levels) in <top (required)>'

它是某种形式的utf-8的问题?

Answer 1:

在Ruby字符串concatenation: << ,如果对象是一个整数,它被认为是一个码点,并在连接前被转换成一个字符。 而且,由于Ruby 1.9的默认编码为UTF-8。 码点被迫使用UTF-8编码:

1.chr(Encoding::UTF_8)
# => "\u0001"

所以,当你这样做:

"" << 1

红宝石实际上考虑1的代码点,并尝试将其与UTF-8编码转换为字符串,而实际上将做到这一点,而不是:

"" << 1.chr(Encoding::UTF_8)
#=> "\u0001"

因此,要解决你的问题。 你可以明确地转换到长整数字符串通过改变代码:

result << inner.to_s

或者用字符串插值:

result << "#{inner}"


Answer 2:

这是预期的行为String#<<方法。 从Ruby文档 :

串接给定的对象海峡。 如果对象是一个整数,它被认为是一个码点,并在连接前被转换成一个字符。

你必须追加整数前显式转换为字符串:

'' << 1 # => "\u0001"
'' << 1.to_s => "1"


Answer 3:

对于小数目的类型是Fixnum对象 [保存可在本机机器字(减1位)来表示整数值。 ]

result << inner

明确将其转换为一个字符串,你就会得到你想要的结果。

result << inner.to_s


文章来源: Why does this ruby use \\u001 for 1 and how to change?
标签: ruby fizzbuzz