2012-10-02 3 views
1

Ruby를 배우기 시작했을 때, Michael Hartl의 뛰어난 Rails Tutorial으로 시작했습니다. 튜토리얼을 다시 살펴보고 예제 애플리케이션 코드의 일부분이 수정되었음을 알았습니다. 인증 장에서는 두 가지 방법으로 변경 하였다 :self 키워드를 추가하면 어떤 차이가 있습니까?

# SessionsHelper 
def sign_in(user) 
    ... 
    self.current_user = user 
end 

def sign_out 
    self.current_user = nil 
    ... 
end 

이전 키워드 self 생략 하였다. 하지만 앱이 효과가있었습니다. 그래서, 그것이 파산하지 않으면, 왜 그것을 고칠 수 있습니까? 어떤 가치가 self으로 추가되었으며 왜 사용됩니까?

나는 self이 인스턴스 메소드가 아닌 클래스 메소드를 정의한다는 것을 알고 있습니다. 그리고 모델에서 self을 사용하면 객체의 속성을 직접 참조 할 수 있습니다. 하지만 점들을 묶어 도우미에서 사용되는 방법을 볼 수는 없습니다. 나는 전에 컨트롤러에서 그것을 보았고 왜 우리가 그것을 사용하고 싶어하는지 이해할 수 없다.

+1

이는'self' 키워드없이 일한다면, 그들은 인스턴스 변수를 사용하고 있어야합니다 (이 setter 메소드를 호출 B/C,하지만 자기없이, 그것은 지역 변수를 설정합니다). 이것들은 똑같은 것이 아니며, IMO, 인스턴스 변수보다 설정 메소드를 사용하는 것이 훨씬 낫다. (b/c 설정은 직접적으로 당신이 그것의 구현에 대한 지식을 가지고 있음을 의미하지만 setter를 호출하는 것은 하나의 메소드). –

+1

@JoshuaCheek : 필연적으로,'attr_accessor : current_user' 또는 명시 적 메소드'def current_user = (new_user)'가있을 수 있으며 같은 구문이 유효합니다. – maerics

+0

실제로 새로운 방법과 이전 버전이 있습니다 : def current_user = (user) @current_user = user end' – Mohamad

답변

4

[편집]

튜토리얼의 원래 부분은 그냥 일반 잘못 가능성이 높습니다. "self"리시버를 생략하면 메쏘드는 메쏘드 로컬 변수 "current_user"에 값을 할당합니다.

내 원래의 대답은 정확하지 않으므로 무시해야합니다. 다른 방법처럼 수신기 메서드 foo=(x)을 호출 할 수 없으므로 무시해야합니다.

[다음은 잘못된 원래 응답]은 "자기"수신기를 사용하는

이유는 명확성을 위해 가능성이 높습니다.

"self"가 생략 된 경우 교육받지 않은 사람에게는 단순히 "user"변수를 "current_user"라는 새 변수에 할당하고 다른 효과는없는 것처럼 보입니다. 숙련 된 Rubyists는 객체 인스턴스에 "current_user"라는 메서드가 있으면 새로운 변수를 생성하고 할당하는 대신 호출된다는 것을 알고 있습니다. 그러나이 메서드는 쉽게 상속 될 수 있습니다. 특히 메서드가 상속되거나 선언되지 않은 경우에는 쉽게 간과 될 수 있습니다. 현재의 클래스 정의 섹션.

"self"키워드를 명시 적으로 사용하면이 개체 인스턴스에 대해 메서드를 호출하고 있음을 분명하게 나타냅니다.

+0

정말요? 'current_user'가 할당의 왼쪽 부분에서'self'없이 사용된다면'current_user ='가 정의되어 있어도 루비는'current_user' 메쏘드를 호출하는 대신에 지역 변수를 생성 할 것입니다. 내가 여기서 빠진 게 뭔가? –

+0

-1. 이것은 단지 명백한 잘못입니다. 'foo = bar' * 항상 * 로컬 변수'foo'에 할당합니다. 어떤 상황에서도 결코'foo ='메세지를 보내지 않을 것입니다. 못. 라이터 메서드를 호출하려면 항상 명시 적 수신기를 사용해야합니다. 이러한 이유 때문에 특별히 'private'메소드에 대한 규칙도 예외입니다. ('private' 메소드는 명시 적 리시버없이 호출 될 수 있고, 작성자는 명시 적 리시버로만 호출 될 수 있으므로, 예외가 존재하지 않으면 개인 라이터를 호출 할 수 없습니다.) –

+0

아, 재미 있습니다. 어쩌면 1.8 행동이었을까요? 나는 또한 1.9에서 이것이 사실이 아니라는 것을 확인했다. – maerics

1
class User 
    attr_accessor :current_user 

    def sign_in_1 
    # Assigning local variable here 
    current_user = "Foo" 
    end 

    def sign_in_2 
    # Calling accessor method 
    self.current_user = "Bar" 
    end 
end 

u = User.new 
u.sign_in_1 
p u.current_user #=> nil 
u.sign_in_2 
p u.current_user #=> "Bar" 
관련 문제