рубин содержит несколько унарные операторы, в том числе +
, -
, !
, ~
, &
и *
. Как и в случае с другими операторами, вы также можете переопределить их. Для ~
и !
вы можете просто сказать def ~
и def !
, поскольку у них нет двоичного аналога (например, вы не можете сказать a!b
).
Однако для -
и +
там как унарный и бинарный вариант (например, a+b
и +a
являются действительным), так что если вы хотите, чтобы переопределить унарную версию вы должны использовать def [email protected]
и def [email protected]
.
Также обратите внимание, что есть унарная версия *
и &
, но они имеют специальные значения. Для *
он привязан к разбиению массива, и для &
он привязан к преобразованию объекта в proc, поэтому, если вы хотите их использовать, вам необходимо переопределить to_a
и to_proc
соответственно.
Вот более полный пример, показывающий все виды унарные:
class SmileyString < String
def [email protected]
SmileyString.new(self + " :)")
end
def [email protected]
SmileyString.new(self + " :(")
end
def ~
SmileyString.new(self + " :~")
end
def !
SmileyString.new(self + " :!")
end
def to_proc
Proc.new { |a| SmileyString.new(self + " " + a) }
end
def to_a
[SmileyString.new(":("), self]
end
end
a = SmileyString.new("Hello")
p +a # => "Hello :)"
p ~a # => "Hello :~"
p *a # => [":(", "Hello"]
p !a # => "Hello :!"
p +~a # => "Hello :~ :)"
p *+!-~a # => [":(", "Hello :~ :(:! :)"]
p %w{:) :(}.map &a # => ["Hello :)", "Hello :("]
В вашем примере модуль просто определяет унарный оператор +, со значением по умолчанию ничего не делает с объектом (который является обычным поведением для унарного плюса, 5
и +5
обычно означает одно и то же). Смешение с любым классом означало бы, что класс немедленно получает поддержку использования оператора унарного плюса, что ничего не значило бы.
Например (используя рубин <=2.2
):
module M
def [email protected]
self
end
end
p +"Hello" # => NoMethodError: undefined method `[email protected]' for "Hello":String
class String
include M
end
p +"Hello" # => "Hello"
Обратите внимание, что в этом примере вы можете ясно видеть из сообщения об ошибке, что метод [email protected]
отсутствующего из класса
Обратите внимание, что в приведенном выше примере будет отличаться от Ruby 2.3, поскольку унарный минус и плюс определены для строк с этой версии, и они относятся к возврату замороженной и незамерзшей строки из оригинала.
достойный информация, +1 –