Ruby Unary Operators include: + - ~ ! * & !!
An Unary operator requires a single value to perform an operation. Examples:
The Integer unary minus operator -
states the integer is a negative integer.
-5
The Integer unary plus operator +
states the integer is a positive integer.
+5
A Binary operator requires two values, the receiver and argument, to perform an operation. Examples:
The Integer binary minus operator -
performs subtraction. In this example,
10 is the receiver and 5 is the argument.
10 - 5
# same operation without the syntactic sugar:
10.-(5)
The Integer binary plus operator +
performs addition.
10 + 5
# same operation without the syntactic sugar:
10.+(5)
While it's more common to define binary operators like <<
to add syntactic
sugar to a custom class, it's far less common to define or override unary
operators. But that shouldn't stop us from having a bit of fun!
To gain familiarity with both types of operators, let's override the String
binary and unary plus (+
) operators.
In the example below, the ExcitedString
class inherits from String
, which
gives the custom class access to binary plus (+
) operator that's already
defined on String
.
class ExcitedString < String
end
ExcitedString.new("Happy ") + "Birthday"
=> "Happy Birthday"
That's convenient but we want our class to make each string excited by adding an exclamation mark to the end of the string.
class ExcitedString < String
def initialize(string)
@string = string
end
def +(other_string)
string + other_string + "!"
end
private
attr_reader :string
end
ExcitedString.new("Happy ") + "Birthday"
=> "Happy Birthday!"
Great! We've successfully overridden the inherited binary plus +
operator and
ensured each string is excited to be alive. Let's move on to defining the unary
plus (+
) operator.
Similar to binary plus (+
) operator, String
already defines a unary plus
(+
) operator. It's not commonly used so here's a brief overview of what it
does:
# If the string is frozen, then return duplicated mutable string.
# If the string is not frozen, then return the string itself.
# Example for "If the string is not frozen..."
string = "my string"
new_string = +string
=> "my string"
string.object_id == new_string.object_id
=> true
Let's override the existing unary plus (+
) operator and make it do something a
bit more exciting.
class ExcitedString < String
def initialize(string)
@string = string
end
def +(other_string)
string + other_string + "!"
end
def +@
string + "!!"
end
private
attr_reader :string
end
+ExcitedString.new("hi")
=> "hi!!"
You probably noticed that when overriding the unary plus (+
) operator, the
method includes an at sign (@
). When a class defines a binary and
unary method, Ruby uses the at sign (@
) to differentiate between the two
methods. To see this in action, let's look at an example using Array
, which
defines a binary plus (+
) operator but does not define a unary plus (+
)
operator.
# binary plus operator on Array
[1] + [2]
=> [1, 2]
# unary plus operator on Array
+[]
=> MethodError (undefined method `+@' for []:Array)