Rubyで、メソッド「foo =()」が定義されているかどうかを確認するにはどうすればよいですか?


81

Rubyでは、メソッドfoo =(bar)を定義できます。

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 =」をエスケープして、解析され、定義されたものに正しく渡されるようにする方法が必要だと思いますか?オペレーター。

回答:


132

問題は、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

ありがとう!これは私の問題を解決します。foo =をエスケープして、definedにフィードできるようにする方法があるかどうかを知りたいのですが。しかし、少なくとも今は先に進むことができます。
Alex Boisvert 2010

1
ここでの問題は、それfoo=が常に割り当てで使用されるため、"assignment"テストするとRubyが返されることですdefined? foo()(更新された回答を参照)。
molf 2010

43

メソッドを使用してメソッドが存在するかどうかを確認しrespond_to?、それにシンボルを渡すことができます。たとえばbar.respond_to?(:foo=)、オブジェクトbarにメソッドがあるかどうかを確認しますfoo=。クラスのインスタンスがmethod_defined?クラス(またはモジュール)で使用できるメソッドに応答するかどうかを知りたい場合は、たとえばFoo.method_defined?(:bar=)

defined?はメソッドではありませんが、オペランドの説明を返す演算子です(定義されていない場合はnilであるため、ifステートメントで使用できます)。オペランドは、定数、変数、代入、メソッド、メソッド呼び出しなど、任意の式にすることができます。defined?(foo=)括弧があるために機能しない理由は、括弧をスキップして、さらに機能するはずです。予想通り以下。そうは言っても、これdefined?はかなり奇妙な演算子であり、メソッドの存在をテストするためにそれを使用する人は誰もいません。


それはrespond_to?であり、responds_to?ではありません。
0x4a6f4672 2012

3
ああ、Rubyのコアライブラリの綴り... respond_to?start_with?end_with?
テオ

3
stackoverflow.com/questions/5280556/…TL;DRという名前の背後にある選択についての良い説明がありますyou.knock if you.respond_to?(:knock)
2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.