Question
How can I check whether a variable is defined in Ruby? Is there an isset-style method or built-in way to detect whether a variable currently exists?
Short Answer
By the end of this page, you will understand how Ruby checks whether variables are defined, why defined? is the usual tool for this job, and how it behaves with local, instance, class, and global variables. You will also see common patterns, mistakes, and practical examples you can use in real Ruby code.
Concept
Ruby does not use an isset() function like PHP. Instead, Ruby provides the defined? keyword to check whether something exists and is recognized by the current program context.
defined? can be used with:
- local variables
- instance variables
- class variables
- global variables
- methods
- constants
- expressions
The important detail is that defined? does not simply return true or false.
It returns:
- a descriptive string when the thing is defined
nilwhen it is not defined
For example:
x = 10
p defined?(x) # "local-variable"
p defined?(y) # nil
This matters because Ruby treats nil as falsey, so defined? works naturally inside conditionals:
if defined?(x)
puts "x exists"
end
Why this matters in real programming:
- You may want to avoid errors when reading a variable that might not exist yet.
- You may want lazy initialization, where a value is created only once.
- You may need different behavior depending on whether a method, constant, or variable is available.
- You may work with metaprogramming or optional configuration.
Also note an important Ruby-specific rule: some variable types behave differently when uninitialized.
For example:
- Reading an undefined local variable usually raises an error.
- Reading an uninitialized instance variable returns
nil.
So checking whether something is defined is not always the same as checking whether its value is nil.
Mental Model
Think of defined? as asking Ruby:
"Do you recognize this name in the current scope, and what kind of thing is it?"
It is not asking:
"Does this variable contain a useful value?"
That distinction is important.
A variable can be:
- defined and hold a value
- defined and hold
nil - not defined at all
Imagine labeled storage boxes:
- If the box exists and contains
42, it is defined. - If the box exists and contains nothing (
nil), it is still defined. - If the box was never created, it is not defined.
defined? checks whether the box exists, not whether the box is empty.
Syntax and Examples
The basic syntax is:
defined?(expression)
Example: local variable
name = "Ruby"
p defined?(name) # "local-variable"
p defined?(age) # nil
Here:
nameexists, so Ruby returns a descriptive string.agedoes not exist, so Ruby returnsnil.
Using it in a condition
if defined?(name)
puts "name is defined"
else
puts "name is not defined"
end
Because defined?(name) returns a non-nil value, the condition is treated as true.
Example: instance variable
class User
def check_email
p defined?(@email)
end
end
User.new.check_email
This returns:
"instance-variable"
Even though @email was never assigned, instance variables are recognized by Ruby syntax and read as nil when uninitialized.
Example: method check
p defined?(puts) # "method"
p defined?(missing_one) # nil
Example: constant check
MY_APP_NAME = "Demo"
p defined?(MY_APP_NAME) # "constant"
p defined?(UNKNOWN_NAME) # nil
A common lazy initialization pattern
@config ||= load_config
This is often enough when nil and false should both trigger initialization.
If you specifically care whether something was ever defined, use defined? instead:
unless defined?(@config)
@config = load_config
end
Step by Step Execution
Consider this example:
x = nil
puts defined?(x)
puts defined?(y)
if defined?(x)
puts "x exists"
end
Step by step:
-
x = nil- A local variable named
xis created. - Its value is
nil. - Even though the value is
nil, the variable is still defined.
- A local variable named
-
puts defined?(x)- Ruby checks whether
xexists in the current scope. - It does.
- Ruby returns
"local-variable". - That string gets printed.
- Ruby checks whether
-
puts defined?(y)- Ruby checks whether
yexists. - It does not.
- Ruby returns
nil. puts nilprints a blank line.
- Ruby checks whether
-
if defined?(x)- Ruby evaluates
defined?(x)again. - It returns
"local-variable". - Since that is truthy, the
ifblock runs.
- Ruby evaluates
-
puts "x exists"- The message is printed.
Output:
local-variable
x exists
The blank line appears because defined?(y) returned nil.
Real World Use Cases
Here are common situations where checking whether something is defined is useful:
Optional configuration
if defined?(APP_TIMEOUT)
timeout = APP_TIMEOUT
else
timeout = 30
end
This is useful when a constant may or may not be loaded.
Lazy setup in objects
def cache
unless defined?(@cache)
@cache = {}
end
@cache
end
This creates the cache only when first needed.
Optional framework features
if defined?(Rails)
puts "Running inside Rails"
end
This helps code adapt to different environments.
Defensive metaprogramming
if defined?(some_helper_method)
some_helper_method
end
Useful when code may run in multiple contexts where helper methods are not always available.
Safe constant checks in libraries
if defined?(JSON)
JSON.generate(data)
else
require "json"
end
This avoids reloading or assuming a library is already present.
Real Codebase Usage
In real Ruby projects, developers usually use defined? in a few focused patterns rather than everywhere.
1. Guarding optional dependencies
require "json" unless defined?(JSON)
This is common in scripts and libraries.
2. Lazy initialization when nil is a valid stored value
||= is common, but it reassigns when the current value is nil or false.
If you need to know whether the variable was ever initialized, defined? is safer.
def setting
return @setting if defined?(@setting)
@setting = compute_setting
end
3. Environment-specific behavior
if defined?(Rails)
logger.info("Rails mode")
else
puts "Standalone mode"
end
4. Guard clauses
return default_value unless defined?(input)
This is useful when code may be evaluated dynamically.
5. Checking constants before use
if defined?(Redis)
client = Redis.new
end
In larger codebases, constant checks are often clearer than rescuing a NameError.
Practical advice
- Use
defined?when you truly need to know whether something exists. - Use
nil?when you know the variable exists and only want to inspect its value. - Use
||=for simple memoization whenfalseandnilshould both mean “not ready yet.”
Common Mistakes
Mistake 1: Confusing defined? with checking for nil
Broken idea:
x = nil
p defined?(x) == nil
Why it is wrong:
xis defined.- Its value is
nil, butdefined?(x)returns"local-variable".
Correct thinking:
x = nil
p defined?(x) # "local-variable"
p x.nil? # true
Mistake 2: Expecting defined? to return true or false
Broken assumption:
x = 1
p defined?(x) == true # false
Why it happens:
defined?returns a string ornil, not a boolean.
Better approach:
if defined?(x)
puts "x is defined"
end
Mistake 3: Reading an undefined local variable directly
Broken code:
p y
This raises an error because y does not exist.
Safer approach:
p defined?(y)
Mistake 4: Using ||= when false is a meaningful value
Broken pattern:
@enabled ||= expensive_check
If expensive_check returns false, this will run again next time.
Better pattern:
unless defined?(@enabled)
@enabled = expensive_check
end
Mistake 5: Assuming all variable types behave the same
Example:
class Example
def test
p @value # nil
p value # may be interpreted as a method call or raise an error depending on context
end
end
Remember:
- uninitialized instance variables return
nil - undefined local variables are different
- bare identifiers may also be parsed as method calls
Comparisons
| Concept | What it checks | Return value | Best use |
|---|---|---|---|
defined?(x) | Whether Ruby recognizes x | Descriptive string or nil | Existence checks |
x.nil? | Whether x has value nil | true or false | Value checks |
| `x | = value` | Assign if current value is nil or false | |
respond_to?(:name) | Whether an object has a method | true or false | Method availability on objects |
const_defined?(:Name) | Whether a module/class defines a constant | true or false | Constant checks in modules/classes |
defined? vs nil?
x = nil
p defined?(x) # "local-variable"
p x.nil? # true
These answer different questions:
defined?= does the variable exist?nil?= does the value equalnil?
defined? vs ||=
unless defined?(@result)
@result = compute
end
vs.
@result ||= compute
Use defined? when false or nil are valid final values you want to keep.
Use ||= when you want to recompute if the current value is falsey.
Cheat Sheet
# Basic syntax
defined?(expression)
Returns
- descriptive string if defined
nilif not defined
Common results
defined?(x) # "local-variable"
defined?(@x) # "instance-variable"
defined?(@@x) # "class variable"
defined?($x) # "global-variable"
defined?(MyConst) # "constant"
defined?(puts) # "method"
Typical conditional use
if defined?(x)
puts "x exists"
end
Important rule
defined? checks existence, not value.
x = nil
defined?(x) # "local-variable"
x.nil? # true
Memoization edge case
@value ||= compute
- recomputes if
@valueisnilorfalse
unless defined?(@value)
@value = compute
end
- computes only once, even if result is
nilorfalse
Good fits for defined?
- optional constants
- lazy initialization
- environment checks
- metaprogramming
- avoiding
NameErrorfor missing names
FAQ
How do I check if a variable exists in Ruby?
Use defined?(variable_name). It returns a descriptive string if the variable exists, or nil if it does not.
Is there an isset() equivalent in Ruby?
Ruby does not use isset(). The closest built-in tool is defined?.
Does defined? return true or false?
No. It returns a string such as "local-variable" or "method", or nil when not defined.
What is the difference between defined? and nil? in Ruby?
defined? checks whether something exists. nil? checks whether a value is nil.
Can a variable be defined and still be nil?
Yes.
x = nil
Here, x is defined, but its value is nil.
Should I use defined? for memoization?
Sometimes. Use it when false or nil are valid cached values. Otherwise, ||= is usually shorter.
Can defined? check methods and constants too?
Yes. It can check variables, methods, constants, and more.
Does reading an undefined variable always raise an error in Ruby?
Not always. Undefined local variables usually cause errors, but uninitialized instance variables return nil.
Mini Project
Description
Build a small Ruby class that lazily loads configuration values only when needed. This demonstrates the difference between a variable being defined and a variable merely having a truthy value.
Goal
Create a class that initializes a setting only once and safely checks whether an instance variable has already been set.
Requirements
- Create a class named
AppConfig. - Add a method that returns a cached configuration value.
- Use
defined?to ensure the value is only initialized once. - Make the computed value able to be
falsewithout being recomputed. - Print the returned value multiple times to show the caching behavior.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.