2012-03-24 5 views
1

아마도 구조체에 대해 충분히 알지 못하고 맹목적으로 사용하고 있었지만 아래 결과는 나에게 비합리적으로 보입니다.구조체에서이 변수가 사라지는 이유는 무엇입니까?

class VarTest < Struct.new(:email) 
    def perform 
    puts "Start: #{email}" 
    if email == "nothing" 
     email = "bad email" 
    end 
    puts "End: #{email}" 
    end 
end 
VarTest.new("[email protected]").perform 

예기치 않은 출력 :

Start: [email protected] 
End: 

나는에 코드를 변경하는 경우 :

class VarTest < Struct.new(:email) 
    def perform 
    e = email 
    puts "Start: #{e}" 
    if e == "nothing" 
     e = "bad email" 
    end 
    puts "End: #{e}" 
    end 
end 

VarTest.new("[email protected]").perform 

우리는 예상 출력을 얻을 :

Start: [email protected] 
End: [email protected] 

누군가가이 일을 설명해 주시겠습니까?

감사합니다.

+0

실제 목표는 무엇입니까? 즉, 왜 VarTest = Struct.new (: email) 대신'VarTest.new ('[email protected]') 대신 상속을 사용하고 있습니까? –

+0

지연된 작업이 대기열에 포함되어 사용 중입니다. 그럼에도 불구하고이 방법으로이 동작을 사용하는 이유는 무엇입니까? – chrishomer

답변

4

email = "bad email"self.email = "bad email"으로 바꾸면 예상대로 작동합니다. setter를 사용할 때 항상 true입니다.

이유는 간단합니다. Ruby가 bareword를 만날 때, 로컬 var로 해결하려고 시도합니다. 아무것도없는 경우, 그 이름의 메소드를 호출하려고합니다. 계급 몸 안쪽에 독자는 암묵적인 수신기이다, 그래서 독자는 다만 일한다. 이제 작가에게는 문제가 있습니다. foo = "bar"과 같은 것을 쓰면 Ruby는 새로운 지역 변수를 생성 할 것이므로 수신기를 명시 적으로 만들어야합니다.

이 경우는 다소 번잡합니다. if email == "nothing"은 getter를 사용합니다. 그러나 email = "bad email"은 여전히 ​​구문 분석기에서 볼 수 있으며 로컬 변수 emailnil으로 설정됩니다. 이것은 파서가 bareword를 과제의 LHS로 간주 할 때 항상 발생합니다. 이 로컬 nil 값은 email 값이 사라지는 것입니다 (이 값은 마지막 putsputs "End: #{self.email}"으로 만 변경하여 확인할 수 있음).

+0

굉장합니다. 그래서 이것은 Structs에 고유하지 않습니다. 구조 변수가 어떻게 작동하는지 알지 못했습니다. 뒤늦은 지각에서 완벽한 의미를 갖습니다. 글쎄, 학습이 계속되며 그게 재미있게 만드는거야! 감사! – chrishomer

관련 문제