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 -c(对于lint)时,它说它是有效的。 - @也是一个合法的方法名称,但当我尝试* @或d @时,这些都是非法的。我想知道+ @是什么意思,为什么合法?
2 个解决方案
#1
12
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
).
Ruby包含一些一元运算符,包括+, - ,!,〜,&和*。与其他运营商一样,您也可以重新定义这些运营商。对于〜和!你可以简单地说def~和def!因为他们没有二元对应物(例如你不能说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 -@
.
但是对于 - 和+有一元和二元版本(例如+ + b和+ a都有效),所以如果你想重新定义一元版本,你必须使用def + @和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.
另请注意,*和&有一元版本,但它们有特殊含义。因为*它与splatting数组相关联,并且它与将对象转换为proc绑定在一起,因此如果要使用它们,则必须分别重新定义to_a和to_proc。
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.
在你的例子中,模块只是简单地定义一个一元+运算符,其默认值是对对象没有做任何事情(这是一元加号的常见行为,5和+5通常意味着相同的事情)。混入任何类都意味着该类立即获得使用一元加运算符的支持,这将不会做任何事情。
For example (using ruby <=2.2
):
例如(使用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.
请注意,上面的示例与Ruby 2.3不同,因为从该版本开始为字符串定义了一元减号和加号,它们指的是从原始字符串返回冻结和未冻结的字符串。
#2
1
The method names +@
and -@
are used to overload the unary operators +
and -
in Ruby (1.9+). Unary operators are operators which only take a single value (e.g. value = -value
).
方法名+ @和 - @用于在Ruby(1.9+)中重载一元运算符+和 - 。一元运算符是仅采用单个值的运算符(例如,value = -value)。
#1
12
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
).
Ruby包含一些一元运算符,包括+, - ,!,〜,&和*。与其他运营商一样,您也可以重新定义这些运营商。对于〜和!你可以简单地说def~和def!因为他们没有二元对应物(例如你不能说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 -@
.
但是对于 - 和+有一元和二元版本(例如+ + b和+ a都有效),所以如果你想重新定义一元版本,你必须使用def + @和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.
另请注意,*和&有一元版本,但它们有特殊含义。因为*它与splatting数组相关联,并且它与将对象转换为proc绑定在一起,因此如果要使用它们,则必须分别重新定义to_a和to_proc。
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.
在你的例子中,模块只是简单地定义一个一元+运算符,其默认值是对对象没有做任何事情(这是一元加号的常见行为,5和+5通常意味着相同的事情)。混入任何类都意味着该类立即获得使用一元加运算符的支持,这将不会做任何事情。
For example (using ruby <=2.2
):
例如(使用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.
请注意,上面的示例与Ruby 2.3不同,因为从该版本开始为字符串定义了一元减号和加号,它们指的是从原始字符串返回冻结和未冻结的字符串。
#2
1
The method names +@
and -@
are used to overload the unary operators +
and -
in Ruby (1.9+). Unary operators are operators which only take a single value (e.g. value = -value
).
方法名+ @和 - @用于在Ruby(1.9+)中重载一元运算符+和 - 。一元运算符是仅采用单个值的运算符(例如,value = -value)。