[ruby] Checking if a variable is defined?

How can I check whether a variable is defined in Ruby? Is there an isset-type method available?

This question is related to ruby reflection

The answer is


This is useful if you want to do nothing if it does exist but create it if it doesn't exist.

def get_var
  @var ||= SomeClass.new()
end

This only creates the new instance once. After that it just keeps returning the var.


defined?(your_var) will work. Depending on what you're doing you can also do something like your_var.nil?


WARNING Re: A Common Ruby Pattern

This is the key answer: the defined? method. The accepted answer above illustrates this perfectly.

But there is a shark, lurking beneath the waves...

Consider this type of common ruby pattern:

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2 always returns nil. The first time you call method1, the @x variable is not set - therefore method2 will be run. and method2 will set @x to nil. That is fine, and all well and good. But what happens the second time you call method1?

Remember @x has already been set to nil. But method2 will still be run again!! If method2 is a costly undertaking this might not be something that you want.

Let the defined? method come to the rescue - with this solution, that particular case is handled - use the following:

  def method1
    return @x if defined? @x
    @x = method2
  end

The devil is in the details: but you can evade that lurking shark with the defined? method.


Leaving an incredibly simple example in case it helps.

When variable doesn't exist:

if defined? a then "hi" end
# => nil

When variable does exist:

a = 2
if defined? a then "hi" end
# => "hi"

This is useful if you want to do nothing if it does exist but create it if it doesn't exist.

def get_var
  @var ||= SomeClass.new()
end

This only creates the new instance once. After that it just keeps returning the var.


You can try:

unless defined?(var)
  #ruby code goes here
end
=> true

Because it returns a boolean.


defined? is great, but if you are in a Rails environment you can also use try, especially in cases where you want to check a dynamic variable name:

foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo)        # => 1
try(:bar)        # => nil
try(my_foo)      # => 1
try(my_bar)      # => nil

You can try:

unless defined?(var)
  #ruby code goes here
end
=> true

Because it returns a boolean.


Leaving an incredibly simple example in case it helps.

When variable doesn't exist:

if defined? a then "hi" end
# => nil

When variable does exist:

a = 2
if defined? a then "hi" end
# => "hi"

Use defined? YourVariable
Keep it simple silly .. ;)


Try "unless" instead of "if"

a = "apple"
# Note that b is not declared
c = nil

unless defined? a
    puts "a is not defined"
end

unless defined? b
    puts "b is not defined"
end

unless defined? c
    puts "c is not defined"
end

This is useful if you want to do nothing if it does exist but create it if it doesn't exist.

def get_var
  @var ||= SomeClass.new()
end

This only creates the new instance once. After that it just keeps returning the var.


Also, you can check if it's defined while in a string via interpolation, if you code:

puts "Is array1 defined and what type is it? #{defined?(@array1)}"

The system will tell you the type if it is defined. If it is not defined it will just return a warning saying the variable is not initialized.

Hope this helps! :)


Here is some code, nothing rocket science but it works well enough

require 'rubygems'
require 'rainbow'
if defined?(var).nil?  # .nil? is optional but might make for clearer intent.
 print "var is not defined\n".color(:red)
else
 print "car is defined\n".color(:green)
end

Clearly, the colouring code is not necessary, just a nice visualation in this toy example.


As many other examples show you don't actually need a boolean from a method to make logical choices in ruby. It would be a poor form to coerce everything to a boolean unless you actually need a boolean.

But if you absolutely need a boolean. Use !! (bang bang) or "falsy falsy reveals the truth".

› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false

Why it doesn't usually pay to coerce:

>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true

Here's an example where it matters because it relies on the implicit coercion of the boolean value to its string representation.

>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil

defined?(your_var) will work. Depending on what you're doing you can also do something like your_var.nil?


Here is some code, nothing rocket science but it works well enough

require 'rubygems'
require 'rainbow'
if defined?(var).nil?  # .nil? is optional but might make for clearer intent.
 print "var is not defined\n".color(:red)
else
 print "car is defined\n".color(:green)
end

Clearly, the colouring code is not necessary, just a nice visualation in this toy example.


Try "unless" instead of "if"

a = "apple"
# Note that b is not declared
c = nil

unless defined? a
    puts "a is not defined"
end

unless defined? b
    puts "b is not defined"
end

unless defined? c
    puts "c is not defined"
end

defined? is great, but if you are in a Rails environment you can also use try, especially in cases where you want to check a dynamic variable name:

foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo)        # => 1
try(:bar)        # => nil
try(my_foo)      # => 1
try(my_bar)      # => nil

The correct syntax for the above statement is:

if (defined?(var)).nil? # will now return true or false
 print "var is not defined\n".color(:red)
else
 print "var is defined\n".color(:green)
end

substituting (var) with your variable. This syntax will return a true/false value for evaluation in the if statement.


Use defined? YourVariable
Keep it simple silly .. ;)


The correct syntax for the above statement is:

if (defined?(var)).nil? # will now return true or false
 print "var is not defined\n".color(:red)
else
 print "var is defined\n".color(:green)
end

substituting (var) with your variable. This syntax will return a true/false value for evaluation in the if statement.


As many other examples show you don't actually need a boolean from a method to make logical choices in ruby. It would be a poor form to coerce everything to a boolean unless you actually need a boolean.

But if you absolutely need a boolean. Use !! (bang bang) or "falsy falsy reveals the truth".

› irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false

Why it doesn't usually pay to coerce:

>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true

Here's an example where it matters because it relies on the implicit coercion of the boolean value to its string representation.

>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil

Please note the distinction between "defined" and "assigned".

$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"

x is defined even though it is never assigned!


It should be mentioned that using defined to check if a specific field is set in a hash might behave unexpected:

var = {}
if defined? var['unknown']
  puts 'this is unexpected'
end
# will output "this is unexpected"

The syntax is correct here, but defined? var['unknown'] will be evaluated to the string "method", so the if block will be executed

edit: The correct notation for checking if a key exists in a hash would be:

if var.key?('unknown')

Please note the distinction between "defined" and "assigned".

$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"

x is defined even though it is never assigned!


defined?(your_var) will work. Depending on what you're doing you can also do something like your_var.nil?


Also, you can check if it's defined while in a string via interpolation, if you code:

puts "Is array1 defined and what type is it? #{defined?(@array1)}"

The system will tell you the type if it is defined. If it is not defined it will just return a warning saying the variable is not initialized.

Hope this helps! :)


This is useful if you want to do nothing if it does exist but create it if it doesn't exist.

def get_var
  @var ||= SomeClass.new()
end

This only creates the new instance once. After that it just keeps returning the var.


It should be mentioned that using defined to check if a specific field is set in a hash might behave unexpected:

var = {}
if defined? var['unknown']
  puts 'this is unexpected'
end
# will output "this is unexpected"

The syntax is correct here, but defined? var['unknown'] will be evaluated to the string "method", so the if block will be executed

edit: The correct notation for checking if a key exists in a hash would be:

if var.key?('unknown')

WARNING Re: A Common Ruby Pattern

This is the key answer: the defined? method. The accepted answer above illustrates this perfectly.

But there is a shark, lurking beneath the waves...

Consider this type of common ruby pattern:

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2 always returns nil. The first time you call method1, the @x variable is not set - therefore method2 will be run. and method2 will set @x to nil. That is fine, and all well and good. But what happens the second time you call method1?

Remember @x has already been set to nil. But method2 will still be run again!! If method2 is a costly undertaking this might not be something that you want.

Let the defined? method come to the rescue - with this solution, that particular case is handled - use the following:

  def method1
    return @x if defined? @x
    @x = method2
  end

The devil is in the details: but you can evade that lurking shark with the defined? method.