括号运算符对Ruby中的FixNum做了什么?

时间:2015-05-14 21:04:28

标签: ruby

来自Python我发现以下行为非常令人惊讶:

irb(main):211:0> x= 33
=> 33
irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0

在这个例子中是否存在不提出错误的理由/理念?

4 个答案:

答案 0 :(得分:5)

括号运算符为您提供二进制表示的第n位:

http://ruby-doc.org/core-2.1.2/Fixnum.html#method-i-5B-5D

答案 1 :(得分:4)

你可能对内部的工作有点困惑,但在处理Ruby时这是正常的,因为它与其他脚本语言完全不同。除非您使用SmallTalk,否则它甚至可能看起来很疯狂。

当Ruby看到以下代码时:

x = 6
x[1]

它实际上做的是:

x.send(:[], 6) # Send :[] method call to x with arguments [ 6 ]

x对象可以自由地解释它想要的,并且行为通常(但并不总是)由类x定义属于if x是正常实例

在这种情况下,它会返回给定索引处的位,相当于x & (1 << 6) >> 6

有时[]方法可以做几件事:

string = "brackets"

# Retrieve a single character
string[1]
# => "r"

# Retrieve a substring
string[5,2]
# => "et"

# Perform a pattern match
string[/[^aeiou]+/]
# => "br"

这也有一些非常疯狂的事情,因为你也可以将它应用到Proc:

fn = lambda { |x| x + 1 }

# Conventional (explicit) call
fn.call(2)
# => 3

# Square bracket method
fn[5]
# => 6

由于Ruby非常依赖于Duck Typing,这意味着您可以编写一个Proc来填充您通常拥有哈希或数组的位置,并且接收您的对象的方法并不明智。

x[...]含义留给您自己的类实例x可以灵活处理,这使得它非常强大。

例如:

class Bracketeer
  def [](i)
    "%d brackets" % i
  end
end

bracketeer = Bracketeer.new

bracketeer[6]
# => "6 brackets"

当您尝试为您的某类创建最小界面时,这种简单的符号通常会派上用场。在许多情况下,您可以使用像[]这样简单的内容来替换find_by_idcache_fetch等更详细的方法。

答案 2 :(得分:1)

当然可以。你会发现manual非常有启发性。

这会将位位置值的二进制位返回为零或一。

答案 3 :(得分:1)

它正在返回@msergeant正确观察到的第n位。

这意味着,对于数字33,其二进制表示是:

Index : [7][6][5][4] [3][2][1][0]
Bits  :  0  0  1  0   0  0  0  1

其中解释了输出:

irb(main):212:0> x[0]
=> 1
irb(main):213:0> x[1]
=> 0
irb(main):214:0> x[2]
=> 0