In Ruby, most operators are actually methods:
1 + 3
# is actually...
1.+(3)
4 == 4
# is actually...
4.==(4)
This is true for the operators bellow:
Operators | Description |
---|---|
`[]`, `[]=` | Collection element getter/setter |
`**` | Exponential operator |
`!`, `~`, `+`, `-` | Not, complement, unary plus and minus |
`*`, `/`, `%` | Multiply, divide, and modulo |
`+`, `-` | Plus, minus |
`>>`, `<<` | Right and left shift |
`&` | Bitwise "and" |
`^`, `|` | Bitwise exclusive and inclusive "or" |
`<=`, `<`, `>`, `>=` | Less than/equal to, etc |
`<=>`, `==`, `===`, `!=`, `=~`, `!~` | Equality and pattern matching |
Operators that are, in fact, methods, can be defined in custom classes
1
to change their default behaviors. For example we could compare two Person
classes by their age. To do that, we could use the greater than operator (>
) between two instances:
class Person
def initialize(age)
@age = age
end
def >(other_person)
age > other_person.age
end
def ==(other_person)
age == other_person.age
end
protected
attr_reader :age
end
arthur = Person.new(44)
tommy = Person.new(43)
arthur > tommy # => true
arthur == tommy # => false
(Note the use of protected
which is perfect for this use case.)
Now, defining ==
method gives us !=
. This is not true for >
though.
arthur != tommy # => true
arthur < tommy # => NoMethodError (undefined method `<' for...
If we know we are going to use a lot of comparison, we can include the Comparable
module to our class and define <=>
. By doing this, we are effectively defining all comparison methods.
class Person
include Comparable
def initialize(age)
@age = age
end
def <=>(other_person)
age <=> other_person.age
end
protected
attr_reader :age
end
arthur = Person.new(44)
tommy = Person.new(43)
arthur > tommy # => true
arthur < tommy # => false
arthur == tommy # => false
For the sake of completeness, let’s add that there are also operators which are not methods (and thus, can’t be defined):
Operators | Description |
---|---|
`.`, `::` | Method/constant resolution operators |
`&&` | Logical "and" |
`||` | Logical "or" |
`..`, `...` | Inclusive range, exclusive range |
`?` `:` | Ternary if-then-else |
`=`, `%=`, `/=`, `-=`, `+=`, `|=`, `&=`, `>>=`, `<<=`, `*=`, `&&=`, `||=`, `**=`, `{` | Assignment/shortcuts, block delimiter |