En Ruby, je peux définir une méthode foo = (bar):
irb(main):001:0> def foo=(bar)
irb(main):002:1> p "foo=#{bar}"
irb(main):003:1> end
=> nil
Maintenant, je voudrais vérifier si elle a été définie,
irb(main):004:0> defined?(foo=)
SyntaxError: compile error
(irb):4: syntax error, unexpected ')'
from (irb):4
from :0
Quelle est la syntaxe appropriée à utiliser ici? Je suppose qu'il doit y avoir un moyen d'échapper à "foo =" de telle sorte qu'il soit analysé et transmis correctement au défini? opérateur.
Le problème est que le foo=
La méthode est conçue pour être utilisée dans les affectations. Vous pouvez utiliser defined?
de la manière suivante pour voir ce qui se passe:
defined? self.foo=()
#=> nil
defined? self.foo = "bar"
#=> nil
def foo=(bar)
end
defined? self.foo=()
#=> "assignment"
defined? self.foo = "bar"
#=> "assignment"
Comparez cela à:
def foo
end
defined? foo
#=> "method"
Pour tester si le foo=
est définie, vous devez utiliser respond_to?
à la place:
respond_to? :foo=
#=> false
def foo=(bar)
end
respond_to? :foo=
#=> true
Vous pouvez vérifier si une méthode existe en utilisant la méthode respond_to?
, Et vous lui passez un symbole, par ex. bar.respond_to?(:foo=)
pour voir si l'objet bar
a une méthode foo=
. Si vous voulez savoir si les instances d'une classe répondent à une méthode, vous pouvez utiliser method_defined?
Sur la classe (ou le module), par ex. Foo.method_defined?(:bar=)
.
defined?
N'est pas une méthode, mais un opérateur qui renvoie une description de l'opérande (ou nil s'il n'est pas défini, c'est pourquoi il peut être utilisé dans une instruction if). L'opérande peut être n'importe quelle expression, c'est-à-dire une constante, une variable, une affectation, une méthode, un appel de méthode, etc. La raison pour laquelle cela ne fonctionne pas lorsque vous faites defined?(foo=)
est à cause des parenthèses, sautez-les et cela devrait fonctionner plus ou moins comme prévu. Cela étant dit, defined?
Est un opérateur assez étrange, et personne ne l'utilise pour tester l'existence de méthodes.