Ruby has lots of operators, but they’re nearly all methods really ;)

Download this source

# The numeric types define the arithmetic operations as you'd expect:

p 3 + 1
p 48.3 - 6
p (18 + 7 * 6) / 2.4

# However, lots of other classes define operators too.
# like String (see strings.rb) and arrays...
p [1,2,3] + [4,5]
p [1,2,3,4,5] - [1,3,5]

# There are all the other operators you'd expect too, and
# they're all defined via methods

# Equality (==) and case comparison (===) are methods
class Demo
  attr_reader :str
  
  def initialize(str)
    @str = str
  end
  
  def ==(other)
    @str == other.str
  end

  def ===(other)
    @str === other.str
  end
end

d1 = Demo.new("str")
d2 = Demo.new("str")

p d1 == d2

case d1
when d2
  p "Case comp match!"
end

# The square bracket operators can be easily defined
class Demo
  def [](idx)
    @str[idx]
  end

  def []=(idx, value)
    @str[idx] = value
  end
end

p d2[1]
d2[1] = 99
p d2[1]
puts "Changed str: #{d2.str}"

# String brackets are much more flexible than that. E.g. they let
# you extract a matching portion:
s = 'Test string'
puts "Matching portion: #{s['est']}"

# and can even be assigned to
s['est'] = 'otal'
puts "String now #{s}"

# Bit of a shock if you're coming from an immutable-string language,
# huh?

# Many classes define '=~' to match a regexp. Let's go back 
# and do that for our Demo class.

class Demo      # adding methods
  def =~(regexp)
    @str =~ regexp
  end
end

p 'Regex Match!' if d1 =~ /s.r/

# You can even redefine some of the unary operators

class Demo
  def +@
    "Positive " + @str    
  end

  def -@
    "Negative " + @str
  end
end

puts -d1
puts +d2

# IMHO, One of Ruby's most univerally handy features is the conditional
# assignment ('improvement') operators, that allow you to test and set
# a variable based on it's existing value (or lack thereof).
#
# NOTE that these shouldn't be confused with the bitwise assignment
# operators (see bitwise.rb).

# Firstly, you often need to use a variable, giving it some default value
# if it's not yet set. This is easy with:
new_var ||= "Default"
puts new_var
new_var ||= "Won't be assigned"
puts new_var

# Less often, you'll want to do the opposite - assign only if the variable
# already has a value.

no_var = nil
no_var &&= "Improved"
puts no_var

new_var &&= "Ahh, that's better..."
puts new_var

Running this outputs:

4
42.3
25.0
[1, 2, 3, 4, 5]
[2, 4]
true
"Case comp match!"
116
99
Changed str: scr
Matching portion: est
String now Total string
"Regex Match!"
Negative str
Positive scr
Default
Default
nil
Ahh, that's better...