+ @是什么意思作为ruby中的方法

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_ato_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不同,因为从该版本开始为字符串定义了一元减号和加号,它们指的是从原始字符串返回冻结和解冻的字符串.