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. Operators (Ruby)

Operators (Ruby)

Ruby operators cover three fundamental categories: arithmetic, comparison, and logical. In Ruby, many operators are implemented as methods, which allows their behavior to be customized per class (operator overloading).

Arithmetic Operators

# Basic arithmetic operators.
a + b   # addition
a - b   # subtraction
a * b   # multiplication
a / b   # division (returns only the quotient when both operands are integers)
a % b   # modulo (remainder)
a ** b  # exponentiation (power)

# divmod: returns the quotient and remainder together as an array.
a.divmod(b)  # => [quotient, remainder]

Comparison Operators

# Equality comparison.
a == b   # returns true if values are equal.
a != b   # returns true if values are not equal.

# Spaceship operator (used with Comparable).
a <=> b  # returns -1 if a is smaller, 0 if equal, 1 if larger.

# Identity comparison (compares object IDs).
a.equal?(b)  # checks whether a and b are the same object.

# Compares both type and value.
a.eql?(b)    # returns true if type and value are both equal.

Logical Operators

# Symbol form (higher precedence, suited for conditional expressions).
a && b  # AND: returns true when both are truthy.
a || b  # OR: returns true when either is truthy.
!a      # NOT: inverts the boolean.

# Word form (lower precedence, suited for control flow).
a and b  # AND (lower precedence than &&)
a or b   # OR (lower precedence than ||)
not a    # NOT (lower precedence than !)

Operator Reference

Arithmetic Operators

Operator / MethodDescription
+Addition. Also used for string and array concatenation.
-Subtraction.
*Multiplication. Also used for string and array repetition.
/Division. When both operands are integers, returns the quotient with the fractional part truncated.
%Returns the remainder.
**Computes exponentiation.
divmod(n)Returns both the quotient and the remainder as an array [quotient, remainder].

Comparison Operators

Operator / MethodDescription
==Returns true if values are equal. Types that differ may still be considered equal depending on how == is implemented.
!=Returns true if values are not equal.
<=>Spaceship operator. Returns -1 if left is smaller, 0 if equal, 1 if larger.
eql?(other)Returns true only when both type and value are equal. Used for hash key comparison.
equal?(other)Returns true only when both objects share the same object_id.

Logical Operators

OperatorDescription
&&AND operator. Returns true when both sides are truthy. Short-circuits: does not evaluate the right side if the left side is falsy.
||OR operator. Returns true when either side is truthy. Short-circuits: does not evaluate the right side if the left side is truthy.
!NOT operator. Inverts the boolean value.
andSame as && but with lower precedence. Used in control flow (after method calls).
orSame as || but with lower precedence. Used for fallback processing on errors.
notSame as ! but with lower precedence. Used in contexts where readability is prioritized.

Sample Code

Basic usage of arithmetic operators and divmod, calculating KOF character power values.

arithmetic_operators.rb
# Define KOF character power and HP values.
terry_power  = 9500   # Terry Bogard's power
kyo_power    = 9800   # Kyo Kusanagi's power
terry_hp     = 1000   # Terry's HP

# Basic addition, subtraction, multiplication, division.
puts terry_power + kyo_power        # => 19300 (total power)
puts kyo_power - terry_power        # => 300 (difference)
puts terry_power * 2                # => 19000 (doubled)
puts terry_power / 3                # => 3166 (integer division, fractional part truncated)

# Modulo (%) to check the remainder when dividing by 3.
puts terry_power % 3                # => 2 (remainder)

# Exponentiation (**) to calculate a combo bonus.
combo_bonus = 2 ** 5
puts "Combo bonus: #{combo_bonus}"  # => 32

# divmod to break down HP consumption into quotient and remainder.
# How many times can 1000 HP be reduced by 300, and what is left over?
quotient, remainder = terry_hp.divmod(300)
puts "Times reduced: #{quotient}, remaining HP: #{remainder}"  # => 3, 100
ruby arithmetic_operators.rb
19300
300
19000
3166
2
Combo bonus: 32
Times reduced: 3, remaining HP: 100

Verifying differences between comparison operators. Examining the behavior of ==, eql?, and equal?.

comparison_operators.rb
# == compares value equality.
puts 1 == 1.0    # => true (values are equal)
puts 1.eql?(1.0) # => false (types differ)

# equal? compares object identity.
str_a = "Terry Bogard"
str_b = "Terry Bogard"
str_c = str_a  # reference to the same object.

puts str_a == str_b      # => true (values are equal)
puts str_a.eql?(str_b)   # => true (type and value both equal)
puts str_a.equal?(str_b) # => false (different objects)
puts str_a.equal?(str_c) # => true (same object)

# Spaceship operator <=> for magnitude comparison.
powers = { terry: 9500, kyo: 9800, iori: 9600, mai: 8900, rock: 9200 }

puts powers[:kyo] <=> powers[:terry]  # => 1 (kyo is greater)
puts powers[:terry] <=> powers[:kyo]  # => -1 (terry is smaller)
puts powers[:terry] <=> 9500          # => 0 (equal)

# sort uses <=> to order elements.
sorted = powers.sort_by { |_name, p| -p }
sorted.each { |name, p| puts "#{name}: #{p}" }
ruby comparison_operators.rb
true
false
true
true
false
true
1
-1
0
kyo: 9800
iori: 9600
terry: 9500
rock: 9200
mai: 8900

Verifying short-circuit evaluation of logical operators and the precedence difference between symbol and word forms.

logical_operators.rb
# Short-circuit (short-circuit evaluation) behavior.
# && does not evaluate the right side if the left side is false/nil.
def attack(name)
  puts "#{name} attacked."
  true
end

# Terry is ready (true), so the right side is also evaluated.
terry_ready = true
terry_ready && attack("Terry Bogard")  # => "Terry Bogard attacked."

# Kyo is knocked out (false), so the right side is not evaluated.
kyo_ready = false
kyo_ready && attack("Kyo Kusanagi")  # => nothing is printed.

puts "---"

# || does not evaluate the right side if the left side is truthy.
# Iori's HP remains, so the default is not used.
iori_hp = 250
current_hp = iori_hp || 0  # iori_hp is not nil/false, so 250 is used.
puts "Iori Yagami HP: #{current_hp}"

# Mai's HP is nil, so the default value 0 is used.
mai_hp = nil
current_hp = mai_hp || 0  # nil, so 0 from the right side is used.
puts "Mai Shiranui HP: #{current_hp}"

puts "---"

# and/or have lower precedence than &&/||, so behavior differs with assignment.
# Symbol form (higher precedence): result is assigned, then and is evaluated.
result = true && false
puts "result (symbol): #{result}"  # => false

# Word form (lower precedence): result = true is evaluated first, result becomes true.
result = true and false
puts "result (word): #{result}"  # => true (= is evaluated before and)

# not has lower precedence than !, but is sometimes used for readability.
rock_ready = true
puts !rock_ready    # => false
puts (not rock_ready) # => false
ruby logical_operators.rb
Terry Bogard attacked.
---
Iori Yagami HP: 250
Mai Shiranui HP: 0
---
result (symbol): false
result (word): true
false
false

Because operators are defined as methods, they can be overloaded in a class. Redefining operators in a KOF character class.

operator_overload.rb
# Class representing a KOF character.
# Operators are overloaded to define custom behavior.
class KofCharacter
  include Comparable

  attr_reader :name, :power

  def initialize(name, power)
    @name  = name
    @power = power
  end

  # + operator: returns a new character representing a combined technique.
  def +(other)
    KofCharacter.new("#{@name}&#{other.name}", @power + other.power)
  end

  # <=> operator: compares by power level (required by Comparable).
  # Defining this alone enables <, <=, >, >=, between?, and clamp.
  def <=>(other)
    @power <=> other.power
  end

  # == operator: considers two characters equal if both name and power match.
  def ==(other)
    other.is_a?(KofCharacter) && @name == other.name && @power == other.power
  end

  def to_s
    "#{@name} (power: #{@power})"
  end
end

terry = KofCharacter.new("Terry Bogard",  9500)
kyo   = KofCharacter.new("Kyo Kusanagi",  9800)
iori  = KofCharacter.new("Iori Yagami",   9600)
mai   = KofCharacter.new("Mai Shiranui",  8900)
rock  = KofCharacter.new("Rock Howard",   9200)

# + operator creates a combined technique.
combined = terry + rock
puts combined  # => Terry Bogard&Rock Howard (power: 18700)

# All comparison operators work because <=> is defined.
puts kyo > terry   # => true (Kyo Kusanagi is stronger)
puts mai < iori    # => true (Mai Shiranui is weaker)
puts terry >= rock # => true (Terry is at least as strong as Rock)

# sort orders by power level.
fighters = [terry, kyo, iori, mai, rock]
fighters.sort.reverse.each.with_index(1) do |c, rank|
  puts "#{rank}: #{c}"
end
ruby operator_overload.rb
Terry Bogard&Rock Howard (power: 18700)
true
true
true
1: Kyo Kusanagi (power: 9800)
2: Iori Yagami (power: 9600)
3: Terry Bogard (power: 9500)
4: Rock Howard (power: 9200)
5: Mai Shiranui (power: 8900)

Notes

Ruby's arithmetic operators (+, -, *, /, %, **) work not only with numbers but also with strings and arrays. Integer division with / truncates the fractional part, which requires attention. When a floating-point result is needed, one of the operands must be a Float (e.g., 9500.0 / 3).

For comparison operators, knowing the difference between ==, eql?, and equal? is important. == compares value equality, eql? compares both type and value, and equal? compares object identity (same memory address). Hash key comparison uses eql? and the hash method internally.

Symbol-form logical operators (&&, ||, !) and word-form logical operators (and, or, not) have different precedence levels. Word-form operators have very low precedence, so combining them with assignment expressions can produce unintended results. The Ruby convention is to use symbol form for conditional expressions and word form for control flow.

Because most Ruby operators are implemented as ordinary methods, they can be redefined (overloaded) within a class. Defining just one <=> and including the Comparable module automatically provides six comparison operators. See Comparable / <=> for details.

Common Mistakes

Mistake 1: Losing the decimal part in integer division (7/2 == 3)

Using / with two integers truncates the result to an integer. When a decimal result is needed, one of the operands must be a floating-point number.

ng_integer_division.rb
terry_power = 9500
iori_power  = 3

# Division of two integers truncates the fractional part.
ratio = terry_power / iori_power
puts ratio  # 3166 (not 3166.666...)
ruby ng_integer_division.rb
3166

Correct approach: converting one operand to a floating-point number (Float) preserves the fractional part.

ok_float_division.rb
terry_power = 9500
iori_power  = 3

# Converting one operand to Float gives the decimal result.
ratio = terry_power.to_f / iori_power
puts ratio   # 3166.6666666666665

# Or add .0 to a numeric literal.
ratio2 = 9500.0 / 3
puts ratio2  # 3166.6666666666665
ruby ok_float_division.rb
3166.6666666666665
3166.6666666666665

Mistake 2: Precedence trap with result = value and fallback (and has lower precedence than =)

The word-form and has lower precedence than the assignment operator =, so result = value and fallback is interpreted as (result = value) and fallback. Using it as a replacement for || produces unintended results.

ng_and_precedence.rb
iori_hp = nil

# Because and has lower precedence than =, result gets nil assigned.
result = iori_hp and 0
puts result.inspect  # nil (not 0)
ruby ng_and_precedence.rb
nil

Correct approach: use || to set a default value.

ok_or_operator.rb
iori_hp = nil

# || is appropriate for setting default values.
result = iori_hp || 0
puts result.inspect  # 0

iori_hp = 350
result = iori_hp || 0
puts result.inspect  # 350
ruby ok_or_operator.rb
0
350

Mistake 3: Difference between == and eql? (eql? also compares type)

== compares value equality, but it may return true for type mismatches such as integers and floats. When type also matters — for example when integers and floats coexist as hash keys — eql? is the appropriate choice.

ng_eq_vs_eql.rb
# == returns true even when types differ but values are equal.
puts 9500 == 9500.0    # true

# Hash keys are compared with eql?, so an integer and a float are different keys.
powers = { 9500 => "Terry Bogard" }
puts powers[9500]      # Terry Bogard
puts powers[9500.0]    # nil (different key)
ruby ng_eq_vs_eql.rb
true
Terry Bogard
nil

Correct approach: use eql? to make type-sensitive comparisons explicit. When using hash keys, keep the types consistent.

ok_eql_usage.rb
puts 9500.eql?(9500)     # true (same type and value)
puts 9500.eql?(9500.0)   # false (different type)

# Use consistent types for hash keys.
powers = { 9500 => "Terry Bogard", 9800 => "Kyo Kusanagi", 9600 => "Iori Yagami" }
key = 9500  # use integer consistently
puts powers[key]         # Terry Bogard
ruby ok_eql_usage.rb
true
false
Terry Bogard

If you find any errors or copyright issues, please .