Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Ruby Dictionary

  1. Home
  2. Ruby Dictionary
  3. Ternary Operator ?: (Ruby)

Ternary Operator ?: (Ruby)

The basic syntax of Ruby's ternary operator condition ? true_value : false_value. Covers usage alongside postfix if, readability issues with nested ternaries, and combining with &. (safe navigation operator).

Syntax

# Basic ternary operator syntax.
# Returns true_value if the condition is truthy, false_value otherwise.
result = condition ? true_value : false_value

# Postfix if syntax.
# Executes the expression on one line when the condition is met.
expression if condition

# Combined with safe navigation operator (&.).
# Returns nil when object is nil; otherwise calls the method.
result = object&.method ? true_value : false_value

Syntax / Operator Reference

Syntax / OperatorDescription
condition ? a : bReturns a if the condition is truthy, b otherwise. Condenses if/else into a single expression.
Postfix if (expr if condition)Executes the expression only when the condition is truthy. Suited for simple operations without assignment.
&. (safe navigation)Returns nil without calling the method when the object is nil. Prevents NilClass errors.
NestingNesting ternary operators allows multiple branches in one line, but readability drops sharply beyond two levels.

Sample Code

Basic usage of the ternary operator — returning status based on a character's HP or grade.

ternary_basic.rb
hp = 0
status = hp > 0 ? "alive" : "defeated"
puts "Yuji Itadori's status: #{status}"

grade = "special"
puts "Satoru Gojo: #{grade == "special" ? "Special Grade sorcerer." : "Regular sorcerer."}"

power = 8500
rank_label = power >= 10000 ? "Special Grade" : "Grade 1"
puts "Megumi Fushiguro's combat rating: #{rank_label}"

is_active = true
label = is_active ? "on mission" : "standby"
puts "Nobara Kugisaki: #{label}"
ruby ternary_basic.rb
Yuji Itadori's status: defeated
Satoru Gojo: Special Grade sorcerer.
Megumi Fushiguro's combat rating: Grade 1
Nobara Kugisaki: on mission

Choosing between postfix if and the ternary operator. The ternary operator is clearer when assigning a value; postfix if is natural for simple execution without assignment.

postfix_if_vs_ternary.rb
hp = 120
display_hp = hp > 100 ? 100 : hp
puts "Nanami's HP: #{display_hp}"

is_cursed = true
puts "Under a curse!" if is_cursed

name = "Yuji Itadori"
greeting = name.empty? ? "Unknown" : name
puts "Character: #{greeting}"

power = 9000
puts "Special move available!" if power >= 8000
ruby postfix_if_vs_ternary.rb
Nanami's HP: 100
Under a curse!
Character: Yuji Itadori
Special move available!

Readability issues with nested ternary operators and a cleaner approach for three or more branches.

ternary_nested.rb
power = 8500
rank = power >= 10000 ? "Special Grade" : power >= 7000 ? "Grade 1" : "Grade 2 or below"
puts "Megumi Fushiguro's grade: #{rank}"

characters = [
  { name: "Yuji Itadori",  power: 9200 },
  { name: "Satoru Gojo",   power: 99999 },
  { name: "Megumi Fushiguro", power: 8500 },
  { name: "Nobara Kugisaki",  power: 7800 },
  { name: "Kento Nanami",     power: 8200 },
]

characters.each do |chara|
  grade = case chara[:power]
          when 10000..Float::INFINITY then "Special Grade"
          when 8000..9999             then "Grade 1"
          when 6000..7999             then "Semi Grade 1"
          else                             "Grade 2 or below"
          end
  puts "#{chara[:name]}: #{grade} (power: #{chara[:power]})"
end
ruby ternary_nested.rb
Megumi Fushiguro's grade: Grade 1
Yuji Itadori: Grade 1 (power: 9200)
Satoru Gojo: Special Grade (power: 99999)
Megumi Fushiguro: Grade 1 (power: 8500)
Nobara Kugisaki: Semi Grade 1 (power: 7800)
Kento Nanami: Grade 1 (power: 8200)

Combining &. (safe navigation operator) with the ternary operator to handle nil safely while branching.

safe_navigation_ternary.rb
class Sorcerer
  attr_reader :name, :grade, :technique

  def initialize(name, grade, technique)
    @name      = name
    @grade     = grade
    @technique = technique
  end

  def special_grade?
    @grade == "Special Grade"
  end
end

s1 = Sorcerer.new("Yuji Itadori",  "Grade 1",      "Black Flash")
s2 = nil
s3 = Sorcerer.new("Satoru Gojo",   "Special Grade","Hollow Purple")

[s1, s2, s3].each_with_index do |sorcerer, i|
  grade_display = sorcerer&.grade ? sorcerer.grade : "Not registered"
  puts "#{i + 1}: #{grade_display}"
end

puts "---"

sorcerers = [
  Sorcerer.new("Megumi Fushiguro",  "Semi Grade 1", "Ten Shadows"),
  nil,
  Sorcerer.new("Nobara Kugisaki",   "Grade 1",      "Straw Doll"),
  Sorcerer.new("Kento Nanami",      "Grade 1",      "Ratio"),
  nil,
]

sorcerers.each do |s|
  label = s&.special_grade? ? "Special Grade sorcerer." : (s ? "Regular sorcerer." : "No data")
  name  = s&.name || "(unknown)"
  puts "#{name}: #{label}"
end
ruby safe_navigation_ternary.rb
1: Grade 1
2: Not registered
3: Special Grade
---
Megumi Fushiguro: Regular sorcerer.
(unknown): No data
Nobara Kugisaki: Regular sorcerer.
Kento Nanami: Regular sorcerer.
(unknown): No data

Notes

Ruby's ternary operator condition ? true_value : false_value condenses if/else into a single expression. It is clearest when deciding "which value to use" — such as assigning to a variable or passing an argument.

Postfix if (expression if condition) is used when running an operation without returning a value. Assigning to a variable with postfix if can leave the variable undefined when the condition is false. Use the ternary operator for conditional assignments.

Nested ternary operators are acceptable up to two levels. Beyond three levels, tracing which condition maps to which value becomes difficult, so rewriting with case/when is worth considering. &. (safe navigation operator) is handy for collections that may contain nil, but when complex conditions are involved, combining it with ordinary if/nil checks can improve readability. For an overview of conditional branching, see if / unless / postfix if.

Common Mistakes

Mistake 1: Three or more levels of nesting making the code unreadable

Nesting a ternary operator three or more levels deep makes it hard to trace which condition maps to which value. The form where conditions chain to the right is especially difficult to follow at a glance.

ng_nested_ternary.rb
power = 8500
rank = power >= 10000 ? "Special Grade" : power >= 8000 ? "Grade 1" : power >= 6000 ? "Semi Grade 1" : "Grade 2 or below"
puts "Megumi Fushiguro's grade: #{rank}"
ruby ng_nested_ternary.rb
Megumi Fushiguro's grade: Grade 1

Rewriting three or more branches with case/when lines up each condition vertically, making the mapping explicit.

ok_nested_ternary.rb
power = 8500
rank = case power
       when 10000..Float::INFINITY then "Special Grade"
       when 8000..9999             then "Grade 1"
       when 6000..7999             then "Semi Grade 1"
       else                             "Grade 2 or below"
       end
puts "Megumi Fushiguro's grade: #{rank}"
ruby ok_nested_ternary.rb
Megumi Fushiguro's grade: Grade 1

Mistake 2: Postfix if assignment leaving a variable undefined when condition is false

Assigning to a variable using postfix if leaves that variable uninitialized when the condition is false. Code that follows will see nil, and calling a method on it causes NoMethodError.

ng_postfix_assign.rb
is_active = false
label = "on mission" if is_active
puts label.upcase
ruby ng_postfix_assign.rb
ng_postfix_assign.rb:3:in `<main>': undefined method `upcase' for nil (NoMethodError)

Using the ternary operator for conditional assignment makes the value for the false case explicit.

ok_postfix_assign.rb
is_active = false
label = is_active ? "on mission" : "standby"
puts label.upcase
ruby ok_postfix_assign.rb
STANDBY

Mistake 3: Swapping the true and false values in the ternary operator

The ternary operator returns the left value when the condition is truthy and the right value when it is falsy. Combining a negative condition (! or unless-equivalent) can inadvertently flip the mapping.

ng_ternary_condition.rb
hp = 50
status = hp <= 0 ? "alive" : "defeated"
puts "Yuji Itadori: #{status}"
ruby ng_ternary_condition.rb
Yuji Itadori: defeated

Confirm what value should be returned when the condition is true before writing it. Using an affirmative condition makes the true-value and false-value mapping natural.

ok_ternary_condition.rb
hp = 50
status = hp > 0 ? "alive" : "defeated"
puts "Yuji Itadori: #{status}"
ruby ok_ternary_condition.rb
Yuji Itadori: alive

If you find any errors or copyright issues, please .