Eli*_*off 8 ruby operator-overloading unary-operator
我正在阅读一些代码,我看到了一些东西
module M
def +@
self
end
end
Run Code Online (Sandbox Code Playgroud)
我很惊讶这是合法的语法,但是当我运行ruby -c文件(到lint)时,它说它是有效的.-@当我尝试*@或d@两者都是非法的时候,这也是一个合法的方法名称.我想知道什么+@意思,为什么合法?
Szt*_*upY 17
Ruby提供了一个几元运算符,包括+,-,!,~,&和*.与其他运营商一样,您也可以重新定义这些运营商.对于~和!你可以简单地只说def ~和def !他们没有一个二进制对应(例如,你不能说a!b).
然而,对于-并且+有一元和二元版本(例如a+b并且+a都是有效的),所以如果你想重新定义你必须使用的一元版本def +@和def -@.
还要注意的是有一个一元的版本*,并&为好,但他们有特殊的含义.对于*它绑泼洒数组,并为&它是联系在一起的对象转换为一个进程,所以如果你想使用它们,你必须重新定义to_a和to_proc分别.
这是一个更完整的示例,显示了各种一元运算符:
class SmileyString < String
def +@
SmileyString.new(self + " :)")
end
def -@
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 :("]
Run Code Online (Sandbox Code Playgroud)
在您的示例中,模块只是简单地定义了一个一元+运营商,而不是与对象做任何事情的默认值(这是一元加一个共同的行为,5并+5通常意味着同样的事情).混入任何类都意味着该类立即获得使用一元加运算符的支持,这将不会做任何事情.
例如(使用ruby <=2.2):
module M
def +@
self
end
end
p +"Hello" # => NoMethodError: undefined method `+@' for "Hello":String
class String
include M
end
p +"Hello" # => "Hello"
Run Code Online (Sandbox Code Playgroud)
请注意,在此示例中,您可以从错误消息中清楚地看到+@该类中缺少该方法
请注意,上面的示例与Ruby 2.3不同,因为从该版本开始为字符串定义了一元减号和加号,它们指的是从原始字符串返回冻结和解冻的字符串.