То, что делает send
, вызывает метод , всего один, с нулем или более аргументов.Он не может вызывать несколько методов одновременно.Ваш пример здесь:
send("[:a][:b][:c][:d]=", :e)
Это пытается вызвать метод с именем, буквально, [:a][:b][:b][:d]=
, который не существует, поэтому send
завершается ошибкой.
Теперь этот битФактический код Ruby:
x[:a][:b][:c][:d] = :e
. Ruby интерпретируется как:
x.send(:[], :a).send(:[], :b).send(:[], :c).send(:[]=, :d, :e)
Это очень длинный и уродливый способ сделать то, что сделал исходный код.Ключевым моментом здесь является то, что каждая [...]
часть представляет вызов метода, который возвращает что-то, и затем следующая часть сравнивается с этим, или приковывается к .
Теперь для исходной части этоpretzel-stab:
super &-> h, k { h[k] = self.class.new }
&
означает «пройти через этот Proc в качестве аргумента блока», как в случае с методом с подписью:
initialize(&block)
Где &block
представляет блок, если он указан, этому методу, например:
Hash.new { |h,k| h[k] = { } }
В более базовой реализации.
Часть -> h, k { ... }
традиционно записывается как:
lambda { |h, k| ... }
Где это, вероятно, более узнаваемо.