2013-12-17 3 views
4

두 가지 방법으로 클래스 ABC가 있다고 가정 해 봅시다.루비의 특정 메소드를 콘솔에서 호출하지 못하도록하는 방법

class ABC 
    def test 
    "test" 
    end 

    def display_test 
    puts test 
    end 
end 

이 난 단지 ('테스트'나 반환) 내 콘솔 (IRB)에서 ABC.new.display_test를 호출 할 수 있어야하고, 그 문제에 ABC.new.test 또는 ABC.new.send(:test)를 호출 할 수 없습니다 싶어요. 이것이 가능한가? 그렇다면 어떻게?

+0

콘솔이란 무엇입니까? IRB? – Linuxios

+0

예, IRB를 의미합니다. – Biketire

+0

irb가 아닌 테스트가 여전히 호출 가능해야합니까? – Linuxios

답변

5

그래서 test 개인 을하는 것 특히 전화를 차단하는 send 메소드를 오버라이드 (override) 수행하는 가장 철저한 방법 ~ test :

class ABC 
    def test 
    "test" 
    end 

    private :test 

    def display_test 
    puts test 
    end 

    def send(id) 
    if id == :test 
     raise NoMethodError.new("error") 
    else 
     super(id) 
    end 
    end 

    alias_method :__send__, :send 
end 

send 오버라이드는 하나의 매개 변수 만 허용하기 때문에 올바르지 않습니다. 올바른 방법을 수행하는 경우

,이 같은 일을 할 수있게합니다 :

ABC.new.send(:send, :test) 
+0

'__send__' 역시 무시해야합니다. –

+0

@Denis yes indeed – SirDarius

+0

흠, 내가 이렇게하면 경고 메시지가 나타납니다. "경고 :'__send__ '를 재정의하면 심각한 문제가 발생할 수 있습니다." – Biketire

1

부분적으로 가능합니다. 직접 호출하지 않고 보낼 수는 있지만 보낼 수는 없습니다. 이것은 Ruby의 개인 메소드가 작동하는 방식입니다.

직접 호출되지 않도록하려면 비공개로 설정하십시오.

private :test 

class TestClass 
    def display_test 
    puts test 
    end 

    private 
    def test 
     "test" 
    end 
end 

이 전체 예입니다

puts TestClass.new.display_test 
puts TestClass.new.send(:test) 

begin 
    puts TestClass.new.test 
rescue 
    puts "Error!" 
end 

Ruby Private Methods

2

이 방법은 개인합니다. 이 작업을 수행하는

한 가지 방법은 다음과 같습니다

class Foo 
    private 
    def bar 
    # … 
    end 
end 

또 다른 방법은 다음과 같습니다이 완전히이라고 얻기에서 방법을 방지 할 수 없습니다

class Foo 
    def bar 
    # … 
    end 
    private :bar 
end 

하는 것으로 : 그것은 단지 중단됩니다 "정상 "전화. 실제로 루비의 클래스 외부에서 private 메소드를 호출하는 방법은 여러 가지가 있습니다.

Foo.new.send :bar 
Foo.new.__send__ :bar 
Foo.new.instance_eval { bar } 

당신 방법에 메시지를 보내 가능한 모든 방법을 열거 해 낼 수 있지만 당신의 노력이 가능성이 결국 열매를 맺지 될 것입니다 : 루비 멀리 내 머리 위로 떨어져 몇 가지를 나열하려면 문을 막을 수있을 정도로 너에게 열려있어. 그래서 그것을 비밀로 만들어라.

관련 문제