+ @作为红宝石中的方法是什么意思 [英] What does +@ mean as a method in ruby

查看:112
本文介绍了+ @作为红宝石中的方法是什么意思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

的内容.

module M
  def +@
    self
  end
end

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

解决方案

Ruby包含一些一元运算符,包括+-!~&*.与其他运算符一样,您也可以重新定义它们.对于~!,您可以简单地说def ~def !,因为它们没有二进制副本(例如,您不能说a!b).

但是对于-+,既有一元版本,又有二进制版本(例如a+b+a都有效),因此,如果要重新定义一元版本,则必须使用def +@def -@.

还请注意,还有*&的一元版本,但是它们具有特殊含义.对于*,它与散布数组有关;对于&,它与将对象转换为proc有关,因此,如果要使用它们,则必须分别重新定义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通常表示同一件事).混入任何类将意味着该类立即获得使用一元加运算符的支持,这无济于事.

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

请注意,在此示例中,您可以从错误消息中清楚地看到类中缺少+@方法

请注意,上面的示例与Ruby 2.3有所不同,因为自该版本以来,一元减号和加号是为Strings定义的,它们表示从原始字符串返回冻结和未冻结的字符串.

I was reading some code and I saw something along the lines of

module M
  def +@
    self
  end
end

I was surprised that this was legal syntax, yet when I ran ruby -c on the file (to lint) it said it was valid. -@ was also a legal method name yet when I tried *@ or d@ both of those were illegal. I was wondering what +@ means and why is it legal?

解决方案

Ruby contains a few unary operators, including +, -, !, ~, & and *. As with other operators you can also redefine these. For ~ and ! you can simply just say def ~ and def ! as they don't have a binary counterpart (e.g. you cannot say a!b).

However for - and + there is both a unary, and a binary version (e.g. a+b and +a are both valid), so if you want to redefine the unary version you have to use def +@ and def -@.

Also note that there is a unary version of * and & as well, but they have special meanings. For * it is tied to splatting the array, and for & it is tied to converting the object to a proc, so if you want to use them you have to redefine to_a and to_proc respectively.

Here is a more complete example showing all kinds of the unary operators:

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

In your example the Module just simply defines an unary + operator, with a default value of not doing anything with the object (which is a common behaviour for the unary plus, 5 and +5 usually mean the same thing). Mixing in with any class would mean the class immediately gets support for using the unary plus operator, which would do nothing much.

For example (using 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"

Note that in this example you can clearly see from the error message that the +@ method is missing from the class

Note that the above example will be different from Ruby 2.3, as the unary minus and plus are defined for Strings since that version, and they refer to returning a frozen and unfrozen string from the original.

这篇关于+ @作为红宝石中的方法是什么意思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆