In Ruby, how do I check if method "foo=()" is defined?

RubySyntax Error

Ruby Problem Overview


In Ruby, I can define a method foo=(bar):

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

Now I'd like to check if it has been defined,

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

What is the proper syntax to use here? I assume there must be a way to escape "foo=" such that it is parsed and passed correctly to the defined? operator.

Ruby Solutions


Solution 1 - Ruby

The problem is that the foo= method is designed to be used in assignments. You can use defined? in the following way to see what's going on:

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

def foo=(bar)
end

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

Compare that to:

def foo
end

defined?(foo)
#=> "method"

To test if the foo= method is defined, you should use respond_to? instead:

respond_to?(:foo=)
#=> false

def foo=(bar)
end

respond_to?(:foo=)
#=> true

Solution 2 - Ruby

You can check if a method exists by using the respond_to? method, and you pass it a symbol, e.g. bar.respond_to?(:foo=) to see if the object bar has a method foo=. If you want to know if instances of a class respond to a method you can use method_defined? on the class (or module), e.g. Foo.method_defined?(:bar=).

defined? isn't a method, but an operator which returns a description of the operand (or nil if it is not defined, which is why it can be used in an if statement). The operand can be any expression, i.e. a constant, a variable, an assignment, a method, a method call, etc. The reason why it doesn't work when you do defined?(foo=) is because of the parentheses, skip them and it should work more or less as expected. That being said, defined? is a pretty weird operator, and no one uses it to test for the existence of methods.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex BoisvertView Question on Stackoverflow
Solution 1 - RubymolfView Answer on Stackoverflow
Solution 2 - RubyTheoView Answer on Stackoverflow