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

What does +@ mean as a method in ruby

我正在阅读一些代码,我看到了一些类似

的内容
module M
  def +@
    self
  end
end

我很惊讶这是合法的语法,但是当我 运行 ruby -c 在文件上(对 lint)它说它是有效的。 -@ 也是一个合法的方法名称,但当我尝试 *@d@ 时,这两个都是非法的。我想知道 +@ 是什么意思,为什么合法?

方法名+@-@用于重载Ruby(1.9+)中的一元运算符+-。 一元运算符是只接受单个值的运算符(例如 value = -value)。

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 :("]

在你的例子中,模块只是简单地定义了一个一元 + 运算符,默认值是不对对象做任何事情(这是一元加号的常见行为,5+5 通常表示同一件事)。与任何 class 混合将意味着 class 立即获得对使用一元加运算符的支持,这不会做太多事情。

例如(使用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"

注意,在这个例子中你可以从错误信息中清楚地看到class

缺少+@方法

请注意,上面的示例将与 Ruby 2.3 不同,因为从该版本开始,为字符串定义了一元减号和加号,它们指的是从原始字符串返回冻结和解冻的字符串。