Мне нравится использовать краны иногда как средство для возврата метода. Однако, при использовании крана с рекурсивной функцией, это поведение отличается от того, что я ожидал:Поведение крана для рекурсивных функций
class Node
attr_accessor :name, :children
def initialize(name); self.name, self.children = name, []; end
def render
res = "Name: #{name}\n"
children.each do |child|
res += " - " + child.render + "\n"
end
res
end
end
parent = Node.new('Parent')
parent.children = [Node.new('Child')]
puts parent.render
Возвращает
Name: Parent
- Name: Child
Если изменить функцию рендеринга, чтобы использовать кран:
def render
"Name: #{name}\n".tap do |res|
children.each do |child|
res += " - " + child.render + "\n"
end
end
end
Он возвращает
Name: Parent
Я бы предположил, что поведение будет идентично первой функции рендеринга. Документы указывают на то, что он «выдает x в блок, а затем возвращает x» ... поскольку функция рекурсивно - это каким-то образом загрязняет стек функций?
'String's in Ruby очень изменчивы. Существует тонна методов мутаций на 'String':' << ',' [] = ',' clear', 'concat',' prepend', 'setbyte',' force_encoding', 'insert',' replace' , 'sub!', 'gsub!', 'capize!', 'chomp!', 'chop!', 'delete!', 'downcase!', 'upcase!', 'encode!', 'lstrip!' , 'strip!', 'next!', 'succ!', 'reverse!', 'scrub!', 'rstrip!', 'slice!', 'squeeze!', 'swapcase!', 'tr!' , 'tr_s!'. –
Строки не являются неизменяемыми, однако в любое время, когда вы используете оператор присваивания, вы фактически изменяете тот объект, к которому относится левая сторона символа '=', а не изменение значения этого объекта. –