使用動態方法調用(#send
或#method
),方法的可見性將被忽略。
是否有一種簡單的方法來動態調用將調用私有方法失敗的方法?如何在尊重隱私的同時動態調用方法
回答
據我所知 - 你需要的方法public_send:
----------------------------------------------------- Object#public_send obj.public_send(symbol [, args...]) => obj From Ruby 1.9.1 ------------------------------------------------------------------------ Invokes the method identified by _symbol_, passing it any arguments specified. Unlike send, public_send calls public methods only. 1.public_send(:puts, "hello") # causes NoMethodError
以爲我不明白你爲什麼要這樣做,你可以用eval
。
class Klass
private
def private_method(arg)
end
end
k = Klass.new
m = "private_method"
eval "k.#{m}('an arg')"
NoMethodError: private method `private_method' called for #<Klass:0x128a7c0>
from (irb):15
from (irb):15
評估和演示真的很糟糕。您需要事先檢查,如果m真的只包含方法名稱。 'l =「檢查; \ rm -rf * \'; puts」'然後攻擊者會試圖欺騙你,想想你喜歡的方法名稱,但實際上不是。 – johannes 2009-11-26 16:41:17
如果您使用的紅寶石1.9,你可以用它Object#public_send
你想要做什麼。
如果您使用Ruby-1.8.7或更早的版本,你必須寫自己Object#public_send
class Object
def public_send(name, *args)
unless public_methods.include?(name.to_s)
raise NoMethodError.new("undefined method `#{name}' for \"#{self.inspect}\":#{self.class}")
end
send(name, *args)
end
end
或者你也可以寫自己的Object#public_method
其行爲類似於Object#method
但只針對公共方法
class Object
def public_method(name)
unless public_methods.include?(name.to_s)
raise NameError.new("undefined method `#{name}' for class `#{self.class}'")
end
method(name)
end
end
確實如此,eval確實是我認爲實現1.9之前的唯一方法。如果您想了解更多關於可見性的信息,請點擊Jamis Buck編寫的awesome article瞭解Ruby中可見性的實際含義。
非常類似於Ruby可見性中的其他內容與其他語言稍有不同。
使用public_send
代替send
:
my_object.public_send :method, *args
這是新的Ruby 1.9,所以對老年人Ruby中,可以require 'backports/1.9.1/kernel/public_send'
。
如果你想避免eval
,send
或public_send
,或者你想better performance,使用public_method
method:
obj.public_method('my_method_name').call
您可以添加的參數是這樣的:
obj.public_method('my_method_name').call('some_argument_1', 'some_argument_2')
- 1. 尊重argparse的隱私與可用性
- 2. 靜態調用方法時如何訪問私有類變量?
- 3. 動態方法在運行時調用
- 4. 如何使用cfscript動態調用不同組件的方法?
- 5. 從__callStatic調用私有靜態方法
- 6. 如何使用反射(Java)調用私有靜態方法?
- 7. 我如何動態調用Vala方法?
- 8. 如何進行動態方法調用?
- 9. 如何在方法名稱爲動態時在Ruby中調用方法?
- 10. 的Java的InvocationTargetException同時調用私有方法
- 11. 如何在存在非靜態,更合適的方法時使用動態參數調用靜態方法?
- 12. 如何動態地將方法定義爲私有方法?
- 13. 如何在進行ajax調用時尊重客戶端驗證
- 14. 如何禁止和驗證私有靜態方法調用?
- 15. 如何從私有基類調用靜態方法?
- 16. 如何動態調用動態對象上的方法?
- 17. Ruby類使用靜態方法調用私有方法?
- 18. 如何在方法參數爲List時通過Reflection調用私有方法?
- 19. 如何調整私有類的方法
- 20. 如何單元測試調用私有方法鏈的方法?
- 21. GWT:使用JSNI機方法:如何調用方法動態
- 22. 如何在使用(Power)Mockito類初始化時嘲諷私有靜態方法的靜態調用?
- 23. 爲什麼允許靜態方法調用私有方法?
- 24. 從靜態方法調用私有方法
- 25. 如何在C#中動態調用任何簽名的方法?
- 26. 在Ruby中調用的私有方法
- 27. 調用動態方法
- 28. 動態方法調用
- 29. 動態方法調用
- 30. 「動態」方法調用
這不是紅寶石1.8.7 – johannes 2009-11-26 20:21:27
實際上,發送1.9就足夠了我相信。有傳言說,它在1.9發送關心,但__send__沒有。但我沒有證實這一點。 – 2009-11-27 04:21:06