翻閱Rails代碼庫有時respond_to_missing?調用超級,有時不會。有沒有你不應該從respond_to_missing調用super的情況?紅寶石respond_to_missing?呼叫超級或不?
回答
它取決於類的實現以及您想要的#respond_to_missing?
以外的行爲。看看ActiveSupport::TimeWithZone
,它是Time
的代理包裝。它試圖模仿它,愚弄你認爲它是Time
的一個實例。例如,當通過Time
時,TimeWithZone#is_a?
將響應true
。
# Say we're a Time to thwart type checking.
def is_a?(klass)
klass == ::Time || super
end
alias_method :kind_of?, :is_a?
respond_to_missing?
應該抓住將由method_missing
被抓住的情況下,所以你必須看看這兩種方法。 TimeWithZone#method_missing
代表丟失方法到Time
而不是super
。
def method_missing(sym, *args, &block)
wrap_with_time_zone time.__send__(sym, *args, &block)
rescue NoMethodError => e
raise e, e.message.sub(time.inspect, inspect), e.backtrace
end
是很有意義的,它會委託respond_to_missing?
到Time
爲好。
# Ensure proxy class responds to all methods that underlying time instance
# responds to.
def respond_to_missing?(sym, include_priv)
return false if sym.to_sym == :acts_like_date?
time.respond_to?(sym, include_priv)
end
同意。是否省略了||超級'在respond_to_missing結束?一個監督或一個故意的設計決定? –
@PiersC對我來說,這看起來像一個蓄意的設計決定。他們希望它返回任何'時間'將返回。就像'method_missing'中沒有'super'一樣,他們只是讓'Time'找出如何處理它。班上一致的模式是,它試圖欺騙調用者認爲它是「時間」的一個實例。就好像這個班是猴子補丁一樣,根本不需要修改。 –
@PiersC查看你的另一個例子'StringInquirer','method_missing'和'respond_to_missing?'調用'super',並且在相同的條件下如果'method_name [-1]!=「?」'。這似乎是一個合理的經驗法則,在大多數情況下'respond_to_missing?'應該反映'method_missing'。 –
respond_to_missing?
作爲method
方法的解決方案出現在Ruby 1.9.2版中。這裏有一個博客帖子大約是一個Ruby核心提交者:http://blog.marc-andre.ca/2010/11/15/methodmissing-politely/
之所以叫super
然而,讓事件的邏輯返回false時,來電會冒泡的類層次結構Object
返回false
。如果你的類是實現respond_to_missing?
的類的子類,那麼當你的邏輯返回false時,你會想要調用super。這通常是庫代碼的問題,而不是應用程序代碼。
所以當你知道一個超類還實現'respond_to_missing? 「如果你不確定,打電話過來是否安全? –
是的,如果你不確定它是安全的,因爲它會冒泡到'Object'類 – DiegoSalazar
謝謝,很好的答案。 –
- 1. 紅寶石/超薄級聯
- 2. 紅寶石HTTPS GET呼叫被卡住
- 3. 紅寶石對象可以在「祖父母」上超級呼叫嗎?
- 4. 紅寶石Thread.new一些奇怪的事情級呼叫
- 5. 紅寶石的零級超 - OOP
- 6. 呼叫紅寶石法嵌入JavaScript的不同參數
- 7. 紅寶石寶石問題與升級
- 8. 紅寶石陣#to_yaml不叫to_yaml遞歸
- 9. 升級紅寶石1.9.3用RVM或brightbox寶石
- 10. 將呼叫置於超級?
- 11. 紅寶石軌上超大
- 12. 呼叫功能氟利昂紅寶石控制器以JavaScript
- 13. 如何從呼叫者獲取文件名紅寶石CGI
- 14. 紅寶石寶石是否或依賴?
- 15. 不能叫青菜或紅寶石命令在bat文件
- 16. 紅寶石1.8.7升級到紅寶石1.9.2
- 17. 如何從紅寶石2.2.3升級到紅寶石2.3.0
- 18. 升級紅寶石1.8.6到紅寶石1.9.2
- 19. 紅寶石 - 超時工作不
- 20. Python /紅寶石:cronjob將不會加載紅寶石寶石?
- 21. 紅寶石或其他
- 22. 紅寶石按位或
- 23. 紅寶石「 - 」到 - 或「+」到+
- 24. 紅寶石與LDAP或AD
- 25. 紅寶石self.class.class_eval或singleton_class.class_eval
- 26. 紅寶石FizzBuzz和/或
- 27. 變化克隆在紅寶石1.9.2.p290或紅寶石1.9.3
- 28. 紅寶石寶石不會運行
- 29. 紅寶石寶石不上市
- 30. 紅寶石1.9.3不壓倒1.9.1寶石
你可能會提供一些代碼片斷,這兩種類型的行爲(當然鏈接到github)? –
例如。 [ActiveSupport :: TimeWithZone](https://github.com/rails/rails/blob/cfb1e4dfd8813d3d5c75a15a750b3c53eebdea65/activesupport/lib/active_support/time_with_zone.rb)從respond_to調用超級?還有[respond_to_missing?](https://github.com/rails/rails/blob/cfb1e4dfd8813d3d5c75a15a750b3c53eebdea65/activesupport/lib/active_support/time_with_zone.rb#L503),但沒有。 [StringInquirer](https://github.com/rails/rails/blob/cfb1e4dfd8813d3d5c75a15a750b3c53eebdea65/activesupport/lib/active_support/string_inquirer.rb)更爲典型。 –
常見模式是調用respond_to?在一個包裹的物體上跳過超級,例如。 [Duration#respond_to_missing?](https://github.com/rails/rails/blob/cfb1e4dfd8813d3d5c75a15a750b3c53eebdea65/activesupport/lib/active_support/duration.rb#L365) –