红宝石包含了一些一元运算符,包括+
,-
,!
,~
,&
和*
。与其他运营商一样,您也可以重新定义这些。对于~
和!
,您可以简单地说def ~
和def !
,因为它们没有二进制对应部分(例如,您不能说a!b
)。
然而,对于-
和+
有两个一元和二进制版本(例如a+b
和+a
都是有效的),所以如果你想重新定义,你必须使用def [email protected]
和def [email protected]
一元版本。
另请注意,还有一个*
和&
的一元版本,但它们有特殊的含义。对于*
而言,它与splatting数组有关,并且对于&
它将对象转换为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 –