Что супер (& nil) делает в рубине? - PullRequest
0 голосов
/ 03 июня 2018

Я читал исходный код для concurrent-ruby и наткнулся на эту строку кода ruby.

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

Может кто-нибудь объяснить мне, что он должен делать?

1 Ответ

0 голосов
/ 04 июня 2018

Вы должны начать с понимания оператора &, как он используется здесь.См. Например:

# 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 => он также способен превращать некоторые объекты в процессы, например:

# 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.По сути, это говорит «ничего не передавать как блок».Я полагаю, что если вы этого не сделаете, блоки автоматически перенаправляются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...