2010-02-27 71 views
60

在Ruby中,我可以定義一個方法foo =(巴):在Ruby中,如何檢查方法「foo =()」是否已定義?

irb(main):001:0> def foo=(bar) 
irb(main):002:1> p "foo=#{bar}" 
irb(main):003:1> end 
=> nil 

現在,我想檢查它是否已被定義,

irb(main):004:0> defined?(foo=) 
SyntaxError: compile error 
(irb):4: syntax error, unexpected ')' 
from (irb):4 
from :0 

什麼是正確的語法使用這裏?我假設必須有一種方法來轉義「foo =」,以便它被解析並正確地傳遞給定義的?運營商。

回答

104

問題是foo=方法被設計用於賦值。您可以使用defined?通過以下方式,看看發生了什麼事情:

defined? self.foo=() 
#=> nil 
defined? self.foo = "bar" 
#=> nil 

def foo=(bar) 
end 

defined? self.foo=() 
#=> "assignment" 
defined? self.foo = "bar" 
#=> "assignment" 

與此相比,:

def foo 
end 

defined? foo 
#=> "method" 

要測試foo=方法被定義,你應該使用respond_to?代替:

respond_to? :foo= 
#=> false 

def foo=(bar) 
end 

respond_to? :foo= 
#=> true 
+0

謝謝!這解決了我的問題。我仍然很想知道是否有辦法逃脫foo =這樣它可以被定義爲饋送?但至少現在我可以繼續前進。 – 2010-02-27 19:24:24

+1

這裏的問題是'foo ='總是用在賦值中,所以如果你測試了'defined',Ruby會返回''assignment''? foo()'(查看更新的答案)。 – molf 2010-02-27 19:40:50

32

您可以通過使用respond_to?方法來檢查方法是否存在,並將其傳遞給一個符號,例如bar.respond_to?(:foo=)以查看對象bar是否有方法foo=。如果您想知道類的實例是否響應某種方法,您可以在類(或模塊)上使用method_defined?,例如, Foo.method_defined?(:bar=)

defined?不是一種方法,而是一個返回操作數描述的操作符(或者如果它沒有被定義,這就是爲什麼它可以用在if語句中)。操作數可以是任何表達式,例如常量,變量,賦值,方法,方法調用等等。當你做defined?(foo=)時它不起作用的原因是因爲括號,跳過它們,它應該工作或多或少如預期的那樣。這就是說,defined?是一個相當奇怪的運算符,並沒有人用它來測試方法的存在。

+0

它是respond_to ?,而不是responds_to? – 0x4a6f4672 2012-07-30 15:42:22

+3

啊,Ruby核心庫的拼寫......'respond_to?','start_with?','end_with?'。 – Theo 2012-07-31 10:00:56

+1

http://stackoverflow.com/questions/5280556/why-does-ruby-use-respond-to-instead-of-responds-to對命名TL背後的選擇有一個很好的解釋; DR'you.knock if you.respond_to?(:敲)' – drewish 2014-10-23 19:03:25

相關問題