ZetCode

Ruby defined? Operator

last modified October 18, 2026

This tutorial explains how to use Ruby's defined? operator. It checks whether a variable, method, constant, or expression is defined and returns a string describing it, or nil if it is not defined.

The defined? operator is a special keyword that tests the existence of Ruby entities. It returns a string describing what it found, or nil if the expression is undefined.

This operator helps prevent errors by safely checking for definitions before use. It does not execute the method or expression it tests, and it works with variables, methods, constants, and other Ruby language elements.

Basic Variable Checking

This example shows how to check if local, instance, and global variables exist. The defined? operator returns different strings for each type.

basic_variables.rb
local_var = 10
@instance_var = 20
$global_var = 30

puts defined?(local_var)    # "local-variable"
puts defined?(@instance_var) # "instance-variable"
puts defined?($global_var)   # "global-variable"
puts defined?(unknown_var)   # nil

The operator returns descriptive strings for defined variables and nil for undefined ones. This helps distinguish between variable types and states.

Checking Method Existence

The defined? operator can verify whether methods are available. It checks both built-in methods and user-defined ones.

method_checking.rb
def greet
  "Hello"
end

puts defined?(greet)       # "method"
puts defined?(puts)        # "method"
puts defined?(unknown_method) # nil

# With parameters
puts defined?(greet())     # "method"

The operator returns "method" for user-defined and core methods. It does not call greet; it only checks that the method exists. Parentheses are optional in the check.

Constant Verification

Constants behave differently than variables in Ruby. The defined? operator helps check their existence before access.

constant_checking.rb
PI = 3.1415
module MyModule
  VERSION = "1.0"
end

puts defined?(PI)              # "constant"
puts defined?(MyModule::VERSION) # "constant"
puts defined?(UNKNOWN_CONST)   # nil

Nested constants can be checked with their full path, such as MyModule::VERSION. Constant lookup also follows the current lexical scope. The operator returns "constant" for any constant it finds.

Checking Expressions

The defined? operator can test entire expressions, not just simple identifiers. This helps verify complex operations before execution.

expression_checking.rb
x = 10
y = 20

puts defined?(x + y)      # "method"
puts defined?(x.foo)      # nil
puts defined?(x.methods)  # "method"
puts defined?(x && y)     # "expression"

Arithmetic operators are method calls, so they report "method". A missing method reports nil, which helps avoid calling it blindly. Non-method expressions such as && report "expression". Assignments report "assignment" without performing the assignment.

Superclass Method Checking

When working with inheritance, defined?(super) checks whether a superclass implementation of the current method is available. This is useful when overriding methods that may not exist in the parent class.

superclass_checking.rb
class Parent
  def inherited_method
    "Parent method"
  end
end

class Child < Parent
  def inherited_method
    if defined?(super)
      super + " extended"
    else
      "No parent method"
    end
  end
end

puts Child.new.inherited_method # "Parent method extended"

The example checks for a superclass implementation before calling it. defined?(super) returns "super" when one exists and nil otherwise, preventing errors when a parent class does not define the method.

Conditional Assignment

Combining defined? with conditional logic enables safe variable initialization. This prevents reinitialization of existing variables.

conditional_assignment.rb
unless defined?($counter)
  $counter = 0
end

def increment
  $counter += 1
end

increment
puts $counter # 1

The check initializes $counter only if the global variable has not been defined. Unlike $counter ||= 0, it does not replace an existing nil or false value.

Checking Yield and Blocks

defined?(yield) tests whether a block was given to the method. It returns "yield" when a block is present and nil otherwise, which helps make methods block-optional.

yield_checking.rb
def process
  if defined?(yield)
    yield
  else
    "No block given"
  end
end

puts process { "Block provided" } # "Block provided"
puts process                      # "No block given"

The method adapts its behavior based on block presence. This creates more flexible APIs that work with or without blocks.

Source

Ruby Keywords Documentation

This tutorial covered Ruby's defined? operator with practical examples showing variable, method, and expression checking patterns.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Ruby tutorials.