당신은 그것을 도움 (액세스 제어 건너 뛰기) public, private and protected.의 루비의 정의를 읽어 찾을 수
루비의 개인 자바의 보호와 유사하다. Java의 private에 해당하는 Ruby는 없습니다. EDIT :이 솔루션은 이제 Ruby 객체에서 Java의 비공개에 대한 위조의 방법을 제공합니다.
개인은 만 암시 적으로 호출 할 수있는 메소드/변수로 정의됩니다. 이것이 문 2와 3이 실패하는 이유입니다. 다시 말해, 개인은 메소드/변수가 정의 된 클래스 또는 서브 클래스의 컨텍스트에 메소드/변수를 제한합니다. 상속은 private 메소드를 서브 클래스에 전달하므로 암시 적 자체를 사용하여 액세스 할 수 있습니다. (왜 성명 6이 효과가 있는지 설명하십시오.)
나는 당신이 보호받는 것에 더 가깝게 찾고 있다고 생각합니다. 가시성이 부여되지 않은 Java 접근 자와 비슷한 동작 (예 : public, private, protected) Spy에서 개인을 변경하여 모든 6 개의 명령문을 보호합니다. 보호 된 메서드는 정의 클래스 또는 해당 하위 클래스의 모든 인스턴스에서 호출 할 수 있습니다. 호출자가 호출에 응답하는 객체의 클래스이거나 해당 객체에서 상속되는 경우 보호 된 메서드에 대한 명시 적 또는 암시 적 호출은 유효한 문입니다.
class Person
private
attr_reader :weight
end
class Spy < Person
protected
attr_accessor :code
public
def test
code #(1) OK: you can call a private method in self
Spy.new.code #(2) OK: Calling protected method on another instance from same class family or a descendant.
self.code #(3) OK: Calling protected method on with explicit self is allowed with protected
code="xyz" #(4) Ok, it runs, but it actually creates a local variable!!!
self.code="z" #(5) OK! This is the only case where explicit 'self' is ok
weight #(6) OK! You can call a private method defined in a base class
end
end
s = Spy.new
s.test # succeeds
s.code #(7) Error: Calling protected method outside of the class or its descendants.
진술 4와 같습니다. 모호성을 피하는 것으로 가정합니다. 루비의 역동적 인 성질에 잠재적 인 피해를주는 것은 더 많은 안전 장치입니다. 나중에 클래스를 다시 열어 접근자를 재정의 할 수 없도록합니다. 예를 들어, 오염 된 코드를 평가하여 발생할 수있는 상황.
저는 이러한 행동을 유도 한 의사 결정에 대해서만 추측 할 수 있습니다. 대부분의 경우 나는 그것이 언어의 역동적 인 성격에 있다고 생각한다.
P. 당신이 정말로 사물의 자바 정의를주고 싶다면. 서브 클래스가 아닌 정의 된 클래스에서만 사용할 수 있습니다. 클래스에 self.inherited 메서드를 추가하여 액세스를 제한하려는 메서드에 대한 참조를 제거 할 수 있습니다.무게를 만들기
는 서브 클래스에서 접근 할 수없는 속성 :
class Person
private
attr_reader :weight
def initialize
@weight = 5
end
def self.inherited(subclass)
subclass.send :undef_method, :weight
end
end
class Spy < Person
private
attr_accessor :code
public
def test
weight
end
end
Person.new.send(:weight) # => 5
Spy.new.send(:weight) #=> Unhelpful undefined method error
그것은 이런 식으로 undef_method 전화를 대체 할 더 이해 할 수
: 훨씬 더 도움이 오류를 제공
def self.inherited(subclass)
subclass.class_eval %{
def weight
raise "Private method called from subclass. Access Denied"
end
}
end
과를 동일한 기능.
다른 클래스의 개인 메서드를 호출하기 위해 보내기가 필요합니다. 실제로 작동하는 것을 증명하는 데에만 사용됩니다.
뒤늦게 볼 때 사생활 보호 및 쓸모없는 것입니다. 만약 당신이 정말로 당신의 방법을 보호하기 위해 심각하다면 당신은 그들을 차단하기 위해 보내기를 무시해야합니다. 다음 코드는 객체의 private_methods에 따라 것을 수행합니다
def send_that_blocks_private_methods(method, *args)
if private_methods.include?(method.to_s)
raise "Private method #{method} cannot called be called with send."
else
send_that_allows_private_methods(method, *args)
end
end
alias_method :send_that_allows_private_methods, :send
alias_method :send, :send_that_blocks_private_methods
private :send_that_allows_private_methods
당신은 대신 모든 개인 방법에 대한 액세스를 거부의 액세스를 차단하려는 private_methods의 class_variable을 지정할 수 있습니다. 비공개로 보낼 수도 있지만, 객체 외부에서 send를 호출하는 합법적 인 방법이 있습니다.
저는 실제로 디자인 결정에 대한 추론을 알고 싶어합니다. 내 대답은 당신의 오해를 해결하는 설명 일뿐입니다. 방법의 약간을 제공하는 것을 설명하지만, 이유는 설명하지 않습니다. – EmFi