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.
-5The Integer unary plus operator + states the integer is a positive integer.
+5A 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
=> trueLet'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)