首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >super(&nil)在ruby中做什么?

super(&nil)在ruby中做什么?
EN

Stack Overflow用户
提问于 2018-06-04 04:43:02
回答 1查看 177关注 0票数 7

我正在读the source code for concurrent-ruby,偶然发现了这行ruby代码。

def initialize(*args, &block)
  super(&nil) # <--- ???
  synchronize { ns_initialize(*args, &block) }
end

有人能给我解释一下它是做什么的吗?

EN

回答 1

Stack Overflow用户

发布于 2018-06-04 06:56:36

您必须从理解这里使用的&操作符开始。例如,请参阅:

# The & here converts a block argument to a proc
def a(&blk)
end

# The & here converts the proc to a block
a(&Proc.new { true })

在proc =>块的情况下,它还能够将一些对象转换为proc,例如:

# The symbol :class gets to_proc called here
[1].map(&:class)

Symbol#to_proc产生的功能如下所示

[1].map(&Proc.new { |x| x.class })

我不确定这方面的官方文档在哪里(欢迎使用指针),但从测试中可以看出,&nil实际上根本没有向该方法传递任何块--它没有任何作用:

def a
  block_given?
end

a {} # => true
a &:puts # => true
a &nil # => false

现在已经解释了这一点,我可以继续说明为什么需要它。

如果省略带有super的括号,则传递所有参数:

class A
  def initialize arg
    puts arg && block_given?
  end
end

class B < A
  def initialize arg
    super
  end
end

B.new(1) {}
# prints "true" - block and arg were both passed to super

如果您不希望发生这种情况,可以手动将参数传递给super。这有一个问题,我将在后面讨论:

class A
  def initialize arg1, arg2=nil
    puts arg1 && !arg2
  end
end

class B < A
  def initialize arg1, arg2=nil
    super arg1
  end
end

B.new 1, 2
# prints "true" - arg1 was passed to super but not arg2

问题是,虽然您可以防止位置和关键字参数被传递,但这种方法不会阻止块被传递:

class A
  def initialize arg1
    puts arg1 && block_given?
  end
end

class B < A
  def initialize arg1
    super arg1
  end
end

B.new(1) { }
# prints "true" - arg and block were both passed

不管出于什么原因,在这里重要的是不要发生这种情况,所以他们使用了一个我以前没有见过但似乎可以完成工作的成语:&nil。它本质上是在说“什么都不作为一个块传递”。我猜如果你不这样做,那么区块就会被自动转发。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50670794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档