Search code examples
ruby

const_defined? vs. defined? in Ruby


To test, whether a constant (say: a class) is known at a certain point in the code, I can write for instance:

if defined? :String

or I can write

if self.class.const_defined? :String

Is there a situation where I these two ways of testing would make a difference? Note that I don't ask about the case where I have an explicit receiver, such as MyModule.const_defined? :Something, but only for the case where I want to test whether a certain constant (which in my case happens to be a constant denoting a class) is already defined.


Solution

  • First things first, defined? is a keyword which behaves a bit similar similar to a method. It receives the name of the thing (variable, constant, ...) to check. What makes this method different from all others is that the parser will not resolve the value of the given name but rather check directly for whether it is defined (hence the keyword property). To check if a constant is defined, you thus have to pass the actual name (rather than a Symbol):

    if defined?(String)
    

    The const_defined? on the oither hand is more regular. It expects a Symbol or String with the name of a constant and checks whether it is defined on the receiver.

    Now as for the differences between the two (when used correctly): if you use them both within the context of an instance method to check for the existence of a constant, they work the same.

    When running e.g. in a class definition (such that self is e.g. a class), you need to make sure to use the correct receiver for your const_defined method, e.g. if self.const_defined? :String.

    Also, defined? can check for a lot more than just constants (e.g. methods, expressions, variables, ...)

    If you want to use this to make sure you actually have the name of a constant at hand in a given variable, you need to use const_defined?. If you want to "statically" check whether an constant was defined, you can use defined?.