2015-01-27 15 views
0

메쏘드를 반환 할 때 가끔씩 탭을 사용하기를 좋아합니다.재귀 함수의 탭 동작

def render 
    "Name: #{name}\n".tap do |res| 
     children.each do |child| 
     res += " - " + child.render + "\n" 
     end 
    end 
    end 
:

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 

을 내가 탭을 사용하여 렌더링 기능을 변경하는 경우 : 재귀 함수와 탭을 사용할 때 내가 무엇을 기대하지만, 그것은 행동이 다른가요

돌아 가기

Name: Parent 

이 동작은 첫 번째 렌더링 함수와 동일하다고 가정합니다. 문서는 "x를 블록에 출력하고 x를 반환합니다"라고 표시합니다 ... 함수가 반복적으로 함수 스택을 오염시키는 것이므로?

답변

0

이것은 할당이 변수를 변경하고 변수가 값으로 전달된다는 점을 제외하고는 아무런 관련이 없습니다. tap은 관련이 없습니다. 문자열을 변수에 넣으면 동작이 동일합니다.

귀하의 경우 문자열 리터럴을 proc에 전달하면 res이라는 문자열을 포함하는 변수가 수신됩니다. 그런 다음 해당 변수를 수정하면 이 아니라 원래 문자열 자체입니다.

고려 : 첫 번째 예는 작동

def test(res) 
    res += "bar" 
end 

x = "foo" 
test(x) 
puts x # outputs "foo", not "foobar" 

이유는 새 값으로 문자열 res에 값을 대체 야한다는 것입니다. 실제로 res에 저장된 문자열에 데이터를 추가하지는 않습니다.

+1

Ruby의'String's은 매우 가변적입니다. '''','''','''',''연결'',''preby'',''setbyte'',''force_encoding'',''insert'',''replace' 등 많은 돌연변이 방법이 있습니다. chop!','delete!','downcase!','upcase!','encode!','lstrip!'과 같은 것들을 포함하고 있습니다. ''! ',''!'''''''''''''''''''''! ,'tr_s! '. –

+0

문자열은 불변하지 않습니다. 그러나 할당 연산자를 사용할 때마다 실제로'='의 왼쪽에있는 객체를 변경하여 객체의 값을 변경하지 않습니다. –