最近我在Ruby中偶然发现了这段代码:
@data = 3.chr * 5
导致“\ 003 \ 003 \ 003 \ 003 \ 003”
稍后在代码
中flag = @data[2] & 2
用于, 我知道它有点按钮标记的东西。似乎值1,2和3用作状态标志,但是因为ruby 1.9,这是我熟悉的版本,改变了Integer.chr方法,代码不再有效,我真的想知道什么是上。 此外,“\ 00x”逃脱的目的是什么?
感谢您的回答
答案 0 :(得分:4)
要使代码在Ruby 1.9中运行,请尝试将该行更改为:
flag = @data[2].ord & 2
在Ruby 1.9之前,str[n]
将返回0到255之间的整数,但在Ruby 1.9中支持新的unicode,str[n]
返回一个字符(长度为1的字符串)。要获取整数而不是字符,可以在字符上调用.ord
。
&
运算符只是C,Ruby和许多其他语言的标准按位AND运算符。
第三个字节(0x03)不是可打印的ASCII字符,因此当您在字符串中有该字节并调用inspect
时,ruby将该字节表示为\003
。只要确保你理解“\ 003”是一个单字节字符串,而'\ 003'是一个四字节字符串。
在Ruby中,字符串实际上是字节序列。在Ruby 1.9中,还有编码信息,但它们实际上只是一个字节序列。
答案 1 :(得分:1)
" \ 00X" thing是值的八进制表示。
所以,如果我们这样做:
irb(main):001:0> 15.chr
=> "\017"
irb(main):002:0> 16.chr
=> "\020"
请注意我们是如何从17到20的?八。
" \ 003 \ 003 \ 003 \ 003 \ 003"是值3的5个字节然后你可以按位和其他字节,如2或\ 002。
因此2或0010(2)的二进制中的3或0011是2(0010)
1.9问题是因为1.9不使用像1.8这样的ascii。大卫格雷森很好地说明了这一点。
答案 2 :(得分:1)
请注意,ruby 1.9将检查十六进制表示中的不可打印字符:
3.chr # => "\x03"
更令人困惑的是,有时字符串将以unicode(UTF-8)显示:
"\003" # => "\u0003" (utf-8)
3.chr.encoding # => #<Encoding:US-ASCII>
"\003".encoding # => #<Encoding:UTF-8>
"\003" == 3.chr # => true (this is strange because the encoding is different)
如果您试图了解这些八进制和十六进制字符串与十进制数字的关系,您可以将它们转换为二进制数:
"\003".unpack('B*') # same as "\003".ord.to_s(2)
# => ["00000011"] # the 2 least significant bits are set
2.to_s(2) # convert to base 2
#=> "10"
表达式3 & 2
是按位和二进制数11b和10b,它将产生10b(因为1和1对于最高有效位是1; 1&amp; 0对于最低有效位是0) 。
其他转换:
'%x' % 97 # => '61' hex
0x61 # => 97 decimal from raw hex input
'%o' % 97 # => '141' octal
0141 # => 97 decimal from raw octal input
这是一种速成课程,但你应该谷歌更深入的信息。