来自 Python我发现以下行为非常令人惊讶: irb(main):211:0 x= 33= 33irb(main):212:0 x[0]= 1irb(main):213:0 x[1]= 0irb(main):214:0 x[2]= 0 在这个例子中是否存在不提出错误的理由/理念? 你可能对内部的工作
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
在这个例子中是否存在不提出错误的理由/理念?
你可能对内部的工作有点困惑,但在处理Ruby时这是正常的,因为它与其他脚本语言完全不同.除非你使用过 SmallTalk,否则它可能看起来很疯狂.当Ruby看到以下代码时:
x = 6 x[1]
它实际上做的是这样的:
x.send(:[], 6) # Send :[] method call to x with arguments [ 6 ]
x对象可以自由地解释它想要的,并且行为通常(但不总是)由类x定义,如果x是普通实例则属于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来填充您通常拥有Hash或Array的位置,并且接收对象的方法并不明智.
正是这种灵活性将x […]的含义留给了你自己的类实例x,这使得它非常强大.
例如:
class Bracketeer def [](i) "%d brackets" % i end end bracketeer = Bracketeer.new bracketeer[6] # => "6 brackets"
当您尝试为您的类创建最小接口时,这种简单的表示法通常会派上用场.在许多情况下,您可以使用像[]这样简单的东西来替换像find_by_id或cache_fetch这样更冗长的方法.