Why does this ruby use \u001 for 1 and how to change?

☆樱花仙子☆ 提交于 2019-12-11 07:49:18

问题


I've written the classic fizzbuzz code.

The spec:

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

The code:

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

Why am I getting \u001... instead of 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)>'

Is it some sort of utf-8 issue?


回答1:


In Ruby for string concatenation: <<, if the object is an Integer, it is considered as a codepoint, and is converted to a character before concatenation. And since Ruby 1.9 default encoding is UTF-8. The codepoints are forced to be encoded with UTF-8:

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

So, when you're doing this:

"" << 1

Ruby actually consider 1 as a codepoint and try to convert it to string with UTF-8 encoding, and will actually does this instead:

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

So, to solve your problem. You can explicitly convert Fixnum to String by changing code to:

result << inner.to_s

or with String interpolation:

result << "#{inner}"



回答2:


It is the expected behaviour of the String#<< method. From the Ruby documentation:

Concatenates the given object to str. If the object is a Integer, it is considered as a codepoint, and is converted to a character before concatenation.

You have to explicitly convert the integer to a string before appending:

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



回答3:


For small numbers their type is a FixNum [ Holds Integer values that can be represented in a native machine word (minus 1 bit). ]

result << inner

Explicitly convert it to a String and you'll get the results you want.

result << inner.to_s


来源:https://stackoverflow.com/questions/26404442/why-does-this-ruby-use-u001-for-1-and-how-to-change

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!