Ruby 带块的括号方法

Ruby Bracket Method with Block

我想在我自己创建的 class 上定义 [] 方法来取块。我是这样做的。

class A
  def self.[](*args, &block)
    puts "I am calling #{block} on #{args}."
    block.(*args)
  end
end

我可以按如下方式调用它。

# Explicit method invocation
A.[](1) { |x| puts x }
# With a procedure argument
arg = proc { |x| puts x }
A[2, &arg]

但是,我希望能够做到的是这个。

A[3] { |x| puts x }

不幸的是,这似乎产生了语法错误。括号方法是否有块语法,或者我是否坚持使用前两种调用它的方法?事实上,更一般地说,哪些 Ruby 方法名称将允许在调用中使用块,因为似乎对何时允许这样做可能有限制?

块仅适用于普通方法调用。

Ruby 有很多运算符,在这里列出所有运算符会很详尽,有两打以上。甚至 `a`!a-a 都是 Ruby 中的方法调用。显然,所有这些运算符都有限制,例如 + 必须采用一个参数,但不能更多,等等。

有趣的是,loop 也是一个方法调用。

对于语法错误,您无能为力,因此您必须更改语法。

如果您接受:

  • Kernel 中定义(即污染)大写方法(类似于 Kernel#Array
  • 使用圆括号代替方括号

你可以这样写:

class A
  def self.call_block_with_args(*args, &block)
    puts "I am calling #{block} on #{args}."
    block.call(*args)
  end
end

module Kernel
  def A(*args, &block)
    A.call_block_with_args(*args, &block)
  end
end

它是这样工作的:

A(3) { |x| puts x }
#=>
# I am calling #<Proc:0x000000012b9c50@block_brackets.rb:14> on [3].
# 3

它不干净,但它可能是最接近 A[3] { |x| puts x } 的地方。