rubyguides

String#include?

str.include?(other_str) -> true | false

String#include? tells you whether one string contains another. It returns true when the substring is found anywhere inside the string, false when it is not. This is one of the most common checks in Ruby — validating input, branching on file types, guarding against keywords.

Signature

str.include?(other_str) -> true | false
ParameterTypeDescription
other_strStringThe substring to search for

include? takes exactly one argument — the substring you want to find. It does not accept a regular expression. If you need regex matching, reach for String#match? instead.

Return Value

Always returns a boolean: true or false. It never returns nil, and it never returns the position where the match was found. For position information, use String#index, which returns an integer or nil.

Basic Substring Checks

"Hello, World!".include?("Hello")  # => true
"Hello, World!".include?("World")  # => true
"Hello, World!".include?("Ruby")   # => false

The search is literal — characters must match exactly, including case.

Case Sensitivity

email = "user@example.com"

email.include?("example")  # => true
email.include?("EXAMPLE")  # => false
email.include?("@")        # => true

This catches a lot of beginners. include? does a byte-by-byte comparison, so "A" and "a" are different characters. For case-insensitive checks, normalise both strings first:

email.downcase.include?("example")  # => true

A case-insensitive alternative that avoids allocating a new string:

email.casecmp("example").zero?  # => false

casecmp returns 0 when the strings match case-insensitively, -1 or 1 otherwise, and nil when there’s no comparison possible. It avoids the downcase allocation entirely.

Guard Clauses

The most common real-world use is a quick guard in a method:

def process_command(input)
  return puts "Cancelled" if input.include?("quit")
  return puts "Stopping"  if input.include?("stop")
  # ...
end

process_command("please quit now")  # => Cancelled
process_command("start task")       # => (no early return)

This pattern is especially useful when processing user input or reading files line by line.

File Type Detection

filename = "report.pdf"

if filename.include?(".pdf")
  puts "Rendering PDF"
elsif filename.include?(".doc")
  puts "Opening Word document"
else
  puts "Unknown format"
end
# => Rendering PDF

When you need multiple extensions, chain the checks or reach for a regular expression. The include? approach breaks down if filenames can contain .pdf elsewhere (e.g. ".pdf.bak"), so use end_with? or match? for anything security-adjacent.

Edge Cases

Empty substring

"hello".include?("")   # => true
"".include?("")        # => true

An empty string is technically always found within any string. Unusual to rely on this, but it follows from how substring search is defined.

Substring longer than the string

"hi".include?("hello")  # => false

No error is raised — it simply returns false.

Nil argument

"hello".include?(nil)
# => NoMethodError: undefined method `include?' for nil:NilClass

Ruby does not coerce nil to a string here. If your argument might be nil, guard against it explicitly:

return false unless arg.is_a?(String)
str.include?(arg)

Non-string argument

"hello".include?(123)
# => wrong argument type (expected string) (ArgumentError)

Ruby raises an ArgumentError for non-string types rather than coerces them. If you need to check for numeric or other types, convert first with to_s.

Relation to Array#include?

Both String and Array expose include?, but they check different things:

# String: checks substring presence
"hello".include?("ell")  # => true

# Array: checks element membership
["hello", "world"].include?("hello")  # => true
["hello", "world"].include?("ell")    # => false

The parameter types differ — Array checks for an object equal to one of its elements, String checks for a character sequence within itself.

See Also