Question
What is the correct Ruby way to determine whether a value is an array?
For example, I want a string to be treated as not being an array and an array to be recognized as one:
is_array("something") # => false
is_array(["something", "else"]) # => true
How can I also get the number of items when the value is an array?
Short Answer
You will learn how Ruby identifies arrays, how to check a value safely with is_a?(Array), and how to count array elements using length, size, or count.
Concept
Ruby values are objects, and every object has a class. An array such as ["something", "else"] is an instance of Array, while "something" is an instance of String.
Use is_a?(Array) to ask whether an object is an array:
"something".is_a?(Array) # => false
["something", "else"].is_a?(Array) # => true
Once you know you have an array, use length or size to get its number of elements:
items = ["something", "else"]
items.length # => 2
items.size # => 2
Checking a value's type matters when input may come from JSON, APIs, forms, configuration files, or method arguments. It helps your program avoid calling array-only methods on a string, number, or nil.
Mental Model
Think of an Array as a labelled container with several slots.
is_a?(Array)checks the label on the container: “Is this an Array?”lengthcounts how many slots currently contain elements.
A string is not an array container, even though it can contain multiple characters. Therefore, a string fails the array check and should not be handled as a list of items unless you deliberately convert it.
Syntax and Examples
Use is_a?(Array) for a normal Ruby type check.
value = ["red", "green", "blue"]
if value.is_a?(Array)
puts "This is an array with #{value.length} items."
else
puts "This is not an array."
end
Output:
This is an array with 3 items.
You can also write the type check with Array === value:
Array === [1, 2] # => true
Array === "text" # => false
However, value.is_a?(Array) is usually easier for beginners to read.
To count elements in an array:
numbers = [10, 20, 30]
numbers.length # => 3
numbers.size # => 3
numbers.count # => 3
For an array with no elements, all three return 0:
[].length # => 0
Step by Step Execution
Consider this method that accepts either an array or another kind of value:
def describe_items(value)
return "Not an array" unless value.is_a?(Array)
"Array contains #{value.length} item(s)"
end
puts describe_items("something")
puts describe_items(["something", "else"])
Step by step:
describe_items("something")receives aString.value.is_a?(Array)isfalse.- The
unlesscondition returns early with"Not an array". describe_items(["something", "else"])receives anArray.- The type check is
true, so execution continues. value.lengthcounts the two elements.- The method returns
"Array contains 2 item(s)".
Output:
Not an array
Array contains 2 item(s)
Real World Use Cases
- JSON API responses: Confirm that a field such as
tagsis an array before iterating over it. - Form parameters: Handle a field that may arrive as one value or as a list of selected values.
- Configuration: Validate that a setting like
allowed_hostscontains a list. - Data imports: Check a CSV or parsed data value before treating it as a collection.
- Method inputs: Give a clear error when a method requires a list of records or IDs.
Example API-style validation:
def process_tags(tags)
return [] unless tags.is_a?(Array)
tags.map { |tag| tag.to_s.downcase }
end
process_tags(["Ruby", "Web"]) # => ["ruby", "web"]
process_tags("Ruby") # => []
Real Codebase Usage
In production Ruby code, type checks are commonly paired with validation and guard clauses.
A guard clause handles invalid input immediately, keeping the main code path simple:
def total_price(prices)
raise ArgumentError, "prices must be an Array" unless prices.is_a?(Array)
prices.sum
end
When an array is optional, a default may be more appropriate:
def send_notifications(recipients)
recipients = [] unless recipients.is_a?(Array)
recipients.each do |recipient|
puts "Sending notification to #{recipient}"
end
end
Developers often use array methods after validation:
users = [{ active: true }, { active: false }, { active: true }]
active_users = users.select { |user| user[:active] }
active_users.count # => 2
If a method's contract clearly says it receives an array, repeated type checks inside that method may be unnecessary. Validate at the boundary where external input enters the application.
Common Mistakes
Calling length on a value before checking it
A string has a length too, but it means character count rather than item count:
value = "hello"
value.length # => 5, not an array item count
Check for an array first when array semantics matter.
value.length if value.is_a?(Array)
Calling array methods on nil
This raises an error:
value = nil
value.length
# NoMethodError
Use a guard clause or a default:
items = value.is_a?(Array) ? value : []
items.length # => 0
Using instance_of?(Array) when subclasses should count
value.instance_of?(Array)
instance_of? is stricter: it only returns true when the object's direct class is exactly Array. Usually, is_a?(Array) is the better choice because it also supports subclasses.
Confusing count with length
Without arguments, count returns the number of elements. With an argument or block, it counts matching elements:
[1, 2, 2, 3].count # => 4
[1, 2, 2, 3].count(2) # => 2
[1, 2, 2, 3].count(&:even?) # => 2
Use length or size when you simply need the total number of elements.
Comparisons
| Task | Recommended Ruby code | Notes |
|---|---|---|
| Check whether a value is an array | value.is_a?(Array) | Clear and commonly used. |
| Check with case-equality | Array === value | Works, but is less conversational to read. |
| Require the exact direct class | value.instance_of?(Array) | Usually too strict. |
| Get total elements | array.length or array.size | Equivalent for arrays. |
| Count total elements | array.count | Same result with no argument or block. |
| Count matching elements | array.count(item) or array.count { ... } | Useful for filtering counts. |
length and size are interchangeable for Ruby arrays. Many developers use length when emphasizing a count and size when discussing a collection's size; both are valid.
Cheat Sheet
# Type check
value.is_a?(Array)
"text".is_a?(Array) # => false
[1, 2].is_a?(Array) # => true
# Total number of array elements
array.length
array.size
array.count
["a", "b"].length # => 2
[].size # => 0
# Count matching elements
[1, 2, 2, 3].count(2) # => 2
[1, 2, 2, 3].count(&:even?) # => 2
# Safe fallback when input might not be an array
items = value.is_a?(Array) ? value : []
- Prefer
is_a?(Array)for ordinary array checks. - Prefer
lengthorsizefor the total item count. countcan also count only elements that match a value or condition.- Do not assume
nil, strings, hashes, and arrays support the same methods.
FAQ
How do I check if something is an array in Ruby?
Use value.is_a?(Array). It returns true for arrays and false for values such as strings, integers, hashes, and nil.
What is the difference between length, size, and count for an array?
With no arguments, all return the number of elements. count is additionally useful with an argument or block to count only matching elements.
Does a Ruby string count as an array?
No. A string is a String object, not an Array, even though it contains characters.
What happens when I call length on an empty array?
It returns 0.
Should I use is_a?(Array) or instance_of?(Array)?
Usually use is_a?(Array). It is more flexible because it accepts instances of Array subclasses too.
How can I safely treat a non-array as an empty array?
Use a conditional fallback:
items = value.is_a?(Array) ? value : []
Can I count only particular values in an array?
Yes. Use count with a value or block:
["a", "b", "a"].count("a") # => 2
Mini Project
Description
Build a small input inspector for a command-line Ruby script. It receives a value, reports whether it is an array, and, when appropriate, reports the total item count. This mirrors validation performed before processing input from an API or configuration file.
Goal
Create a method that safely describes arrays and rejects non-array values.
Requirements
- Create a method named
array_reportthat accepts one value. - Return a message when the value is not an array.
- Return the number of elements when the value is an array.
- Test the method with a string, an empty array, and an array with multiple values.
- Use
is_a?(Array)for the type check.
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.