当前位置 : 主页 > 编程语言 > ruby >

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

来源:互联网 收集:自由互联 发布时间:2021-06-23
来自 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 在这个例子中是否存在不提出错误的理由/理念? 你可能对内部的工作
来自 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

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

你可能对内部的工作有点困惑,但在处理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这样更冗长的方法.

网友评论