Hash#has_key?

Added in v1.8 · Updated March 13, 2026 · Hash Methods
ruby hash key-check

These four methods check whether a hash contains a specific key. They are aliases for each other — you can use whichever reads most naturally in your code.

Syntax

hash.has_key?(key)          # => true or false
hash.key?(key)              # => true or false
hash.include?(key)          # => true or false
hash.member?(key)           # => true or false

Parameters

ParameterTypeDescription
keyObjectThe key to search for in the hash

Return Value

Returns true if the hash contains the given key, false otherwise.

Description

Ruby provides four identical methods for checking key existence:

  • has_key? — The most descriptive name. Readable in tests and conditionals.
  • key? — Concise. Common in Rails and Ruby codebases.
  • include? — Familiar if you come from Python or C++.
  • member? — The oldest alias, dating back to Ruby 1.8.

All four methods do exactly the same thing. Choose based on readability in your specific context.

The key difference between these methods and bracket notation (hash[key]) is that bracket notation returns nil for missing keys, which is ambiguous — you cannot tell whether the key exists with a nil value or the key is missing entirely. These methods always return a boolean.

Examples

Basic key checking

user = { name: "Alice", age: 30, city: "London" }

user.has_key?(:name)   # => true
user.has_key?(:email)  # => false
user.key?(:age)        # => true

Using in conditionals

config = { environment: "production", debug: false }

if config.key?("environment")
  puts "Running in #{config["environment"]} mode"
end
# => Running in production mode

Different aliases, same result

data = { a: 1, b: 2 }

data.has_key?(:a)    # => true
data.key?(:a)       # => true
data.include?(:a)   # => true
data.member?(:a)    # => true

With string keys

params = { "controller" => "users", "action" => "show" }

params.has_key?("controller")  # => true
params.has_key?(:controller)  # => false - different key type!

# Convert string keys to symbols if needed
params.transform_keys(&:to_sym).has_key?(:controller)
# => true

Note that symbol keys and string keys are distinct in Ruby hashes.

Comparison with bracket notation

scores = { alice: nil, bob: 100 }

scores[:alice]       # => nil (ambiguous!)
scores[:charlie]     # => nil (also nil!)

scores.has_key?(:alice)    # => true - knows the key exists
scores.has_key?(:charlie) # => false - key is missing

Common Patterns

Safe value retrieval

settings = { theme: "dark" }

# Instead of this:
theme = settings[:theme] || "light"

# Do this (cleaner):
theme = settings.fetch(:theme, "light")

Validation

required_keys = [:name, :email, :password]
user_input = { name: "Bob", email: "bob@example.com" }

required_keys.each do |key|
  unless user_input.key?(key)
    raise ArgumentError, "Missing required key: #{key}"
  end
end
# Raises: Missing required key: password

Performance

These methods run in O(1) average time because hashes use internal lookup tables. The time complexity does not grow with hash size.

See Also

  • hash-fetch — Fetch a value with a default or block
  • hash-dig — Safely access nested values