Question
How is the conditional operator ? : used in Ruby?
For example, is this expression correct?
<% question = question.size > 20 ? question.question.slice(0, 20) + "..." : question.question %>
I want to understand whether this is valid Ruby and how the conditional operator should be written and used properly.
Short Answer
By the end of this page, you will understand how Ruby's conditional operator works, how to read and write ternary expressions, and when to use them instead of a regular if/else. You will also see how to clean up the example code so it is easier to read and safer to maintain.
Concept
Ruby's conditional operator, often called the ternary operator, is a compact way to choose between two values based on a condition.
The syntax is:
condition ? value_if_true : value_if_false
It works like a short if/else expression:
if condition
value_if_true
else
value_if_false
end
This matters because Ruby treats if and the ternary operator as expressions, which means they both return a value. That makes them useful when you want to assign a result, return a value from a method, or print one of two outputs.
For example:
message = age >= 18 ? "adult" : "minor"
If age >= 18 is true, message becomes "adult". Otherwise, it becomes "minor".
In your example, the ternary operator itself is valid Ruby. The bigger issue is readability and variable naming. Reusing question on both sides of the assignment can be confusing because it makes it harder to tell whether question is a string, an object, or the final truncated value.
A clearer version would be:
text = question.question
short_text = text.length > 20 ? text.slice(0, 20) + "..." : text
This keeps the intent clear:
textis the original question textshort_textis the shortened version if needed
As a general rule, use the ternary operator for simple two-way choices. If the logic becomes long or nested, a normal if/else is usually better.
Mental Model
Think of the ternary operator like a fork in the road:
- First, you check the sign:
condition - If the sign says yes, go left:
value_if_true - Otherwise, go right:
value_if_false
So this:
logged_in ? "Welcome back" : "Please sign in"
means:
- If the user is logged in, show
"Welcome back" - Otherwise, show
"Please sign in"
It is just a quick decision with exactly two outcomes.
Syntax and Examples
The basic Ruby syntax is:
condition ? result_if_true : result_if_false
Basic example
age = 20
label = age >= 18 ? "adult" : "minor"
puts label
Output:
adult
String length example
name = "Alexander"
display_name = name.length > 5 ? name.slice(0, 5) + "..." : name
puts display_name
Output:
Alexa...
Your example, cleaned up
text = question.question
preview = text.length > 20 ? text.slice(0, 20) + "..." : text
This means:
- If
textis longer than 20 characters, take the first 20 characters and add... - Otherwise, use the original text
In an ERB template
If you want to output the result in a Ruby template, you would usually use <%= instead of <%:
<%= question.question.length > 20 ? question.question.slice(0, 20) + "..." : question.question %>
Why?
<% %>runs Ruby code but does not print anything<%= %>runs Ruby code and prints the result
So if your goal is to display the text, <%= is the correct choice.
Step by Step Execution
Consider this example:
text = "Ruby ternary operators are useful"
preview = text.length > 20 ? text.slice(0, 20) + "..." : text
puts preview
Step by step:
-
textis assigned the string:"Ruby ternary operators are useful" -
Ruby evaluates the condition:
text.length > 20 -
text.lengthis greater than20, so the condition istrue. -
Because the condition is true, Ruby uses the expression after
?:text.slice(0, 20) + "..." -
text.slice(0, 20)returns the first 20 characters. -
Ruby adds
"..."to the end. -
That final value is assigned to
preview. -
puts previewprints the shortened string.
If the string had been 20 characters or fewer, Ruby would have skipped the true branch and used the value after : instead.
Real World Use Cases
The ternary operator is useful in many small day-to-day Ruby tasks.
1. Display labels in a web app
status_text = user.active ? "Active" : "Inactive"
2. Shorten text previews
preview = article.body.length > 100 ? article.body.slice(0, 100) + "..." : article.body
3. Choose a default value for output
name_to_show = user.name.empty? ? "Anonymous" : user.name
4. Format values for APIs or JSON
role = admin ? "admin" : "user"
5. Show conditional CSS classes in templates
css_class = completed ? "task done" : "task pending"
These are all short, two-choice decisions, which is where the ternary operator works best.
Real Codebase Usage
In real Ruby codebases, developers use the ternary operator for small expressions, not for complex branching.
Common pattern: assign one of two values
icon = online ? "green-dot" : "gray-dot"
Common pattern: conditional formatting
price_label = price.zero? ? "Free" : "$#{price}"
Common pattern: view templates
<%= user.admin? ? "Administrator" : "Member" %>
When developers avoid it
If either branch becomes long, developers usually switch to if/else:
message = if order.paid?
"Thank you for your payment"
else
"Payment is still pending"
end
Related pattern: guard clauses
A ternary is not always the cleanest choice. If a method should exit early, a guard clause is often better:
def display_name(user)
return "Anonymous" if user.name.nil? || user.name.empty?
user.name
end
Practical advice
Use the ternary operator when:
- there are only two outcomes
- both branches are short
- the result fits comfortably on one line
- readability stays high
Avoid it when:
- branches are complex
- conditions are hard to read
- you are tempted to nest multiple ternaries
Common Mistakes
Here are common beginner mistakes with Ruby's ternary operator.
1. Forgetting the : part
Broken code:
result = score > 50 ? "pass"
Why it is wrong:
- A Ruby ternary needs both outcomes
- You must provide a true branch and a false branch
Correct version:
result = score > 50 ? "pass" : "fail"
2. Using it for long logic
Hard to read:
message = user.logged_in? ? (user.admin? ? "Welcome admin" : "Welcome user") : "Please log in"
This works, but it is difficult to read. Prefer if/else for clarity.
3. Confusing assignment with output in ERB
Your original code used:
<% question = question.size > 20 ? question.question.slice(0, 20) + "..." : question.question %>
Problem:
<% %>does not print anything- It only executes Ruby code
If you want to display the result, use:
<%= question.question.length > 20 ? question.question.slice(0, 20) + "..." : question.question %>
4. Reusing the same variable name in a confusing way
Confusing code:
question = question.size > 20 ? question.question.slice(0, 20) + "..." : question.question
Why it is risky:
questionstarts as an object- then it becomes a string
- this makes later code harder to understand
Better:
text = question.question
preview = text.length > 20 ? text.slice(0, 20) + "..." : text
5. Checking the wrong length
If question is an object and question.question is the text, then this may be wrong:
question.size > 20
You probably want:
question.question.length > 20
Always check the length of the actual string you want to shorten.
Comparisons
| Concept | Best for | Example | Notes |
|---|---|---|---|
Ternary ? : | Short two-way choices | age >= 18 ? "adult" : "minor" | Compact, but should stay simple |
if/else | Longer or clearer branching | if age >= 18 ... else ... end | Easier to read for complex logic |
Modifier if | One-sided condition | puts "Hi" if logged_in | No false branch |
Ternary vs if/else
label = score >= 50 ? "pass" : "fail"
Equivalent:
label = if score >= 50
"pass"
else
"fail"
end
Use the ternary when the expression is short. Use if/else when readability matters more than compactness.
Ternary vs modifier if
Modifier if only handles the true case:
puts "Long text" if text.length > 20
Ternary handles both true and false cases:
label = text.length > 20 ? "Long text" : "Short text"
Cheat Sheet
# Basic syntax
condition ? value_if_true : value_if_false
Quick examples
age >= 18 ? "adult" : "minor"
online ? "Connected" : "Offline"
name.empty? ? "Anonymous" : name
ERB output
<%= condition ? value_if_true : value_if_false %>
Good use cases
- Assign one of two simple values
- Format output briefly
- Choose between short labels or strings
Avoid when
- the logic is long
- ternaries are nested
- readability gets worse
Common fix for the sample question
text = question.question
preview = text.length > 20 ? text.slice(0, 20) + "..." : text
Or directly in ERB:
<%= question.question.length > 20 ? question.question.slice(0, 20) + "..." : question.question %>
Important detail
<% %>executes Ruby<%= %>executes Ruby and prints the result
FAQ
Is the ternary operator valid in Ruby?
Yes. Ruby supports the conditional operator with this syntax:
condition ? true_value : false_value
What is the difference between if/else and the ternary operator in Ruby?
They can both choose between two values. The ternary operator is shorter, while if/else is usually easier to read for longer logic.
Can I use the ternary operator in ERB templates?
Yes. Use <%= %> if you want the result to appear in the HTML output.
Why does <% %> not show anything in my template?
Because <% %> only runs Ruby code. It does not print the result. Use <%= %> to output a value.
Should I nest ternary operators in Ruby?
Usually no. Nested ternaries quickly become hard to read. Prefer if/elsif/else when there are multiple decisions.
Is size or length better for strings in Ruby?
For strings, both are commonly used and return the character count. Many developers use length when talking about text because it reads more clearly.
How do I shorten a string in Ruby if it is too long?
A common pattern is:
text.length > 20 ? text.slice(0, 20) + "..." : text
This returns a shortened version only when needed.
Mini Project
Description
Build a small Ruby script that formats article titles for display. If a title is longer than 25 characters, show only the first 25 characters followed by .... Otherwise, show the full title. This demonstrates a practical use of the ternary operator for UI-friendly text formatting.
Goal
Create a Ruby program that loops through several titles and prints a shortened preview for each one using the ternary operator.
Requirements
- Store several article titles in an array.
- For each title, decide whether it needs to be shortened.
- Use the ternary operator to choose between the full title and the shortened title.
- Print the original and formatted versions.
- Keep the logic readable by using clear variable names.
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.