2013-12-17 65 views
4

假設我有兩種方法的ABC類。如何在控制檯中禁用某個紅寶石方法

class ABC 
    def test 
    "test" 
    end 

    def display_test 
    puts test 
    end 
end 

我只希望能夠調用ABC.new.display_test從我的控制檯(IRB)(返回我的「測試」),並不能稱之爲ABC.new.testABC.new.send(:test)對這一問題。這可能嗎?如果是這樣,怎麼樣?

+0

你是什麼意思的控制檯? IRB? – Linuxios

+0

是的,我的意思是IRB。 – Biketire

+0

如果不在irb中,測試是否仍需要調用? – Linuxios

回答

5

,最徹底的辦法這樣做將有test私人覆蓋send方法特異性阻斷通話到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是的確的 – 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 

請注意,這不會完全阻止的方法,以獲取調用:它只會停止「正常「電話。事實上,在Ruby中有很多方法可以從類之外調用私有方法。要列出幾關我的頭頂:

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

可以嘗試列舉每一個可能的方式將消息發送給一個方法,但你的努力很可能會最終無果而終:Ruby是遠太開放,你能夠密封大門。所以堅持把它變成私人的。