来自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
在这个例子中是否存在不提出错误的理由/理念?
答案 0 :(得分:5)
括号运算符为您提供二进制表示的第n位:
答案 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_id
或cache_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