2016-10-16 63 views

回答

12

紅寶石包含了一些一元運算符,包括+-!~&*。與其他運營商一樣,您也可以重新定義這些。對於~!,您可以簡單地說def ~def !,因爲它們沒有二進制對應部分(例如,您不能說a!b)。

然而,對於-+有兩個一元和二進制版本(例如a+b+a都是有效的),所以如果你想重新定義,你必須使用def [email protected]def [email protected]一元版本。

另請注意,還有一個*&的一元版本,但它們有特殊的含義。對於*而言,它與splatting數組有關,並且對於&它將對象轉換爲proc,所以如果要使用它們,則必須分別重新定義to_ato_proc

這裏是在各種一元運算符的一個更完整的例子:

class SmileyString < String 
    def [email protected] 
    SmileyString.new(self + " :)") 
    end 

    def [email protected] 
    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通常意味着同樣的事情)。與任何類混合意味着該類會立即得到使用一元加運算符的支持,而該運算符不會做任何事情。

例如(使用紅寶石<=2.2):

module M 
    def [email protected] 
    self 
    end 
end 

p +"Hello"  # => NoMethodError: undefined method `[email protected]' for "Hello":String 

class String 
    include M 
end 

p +"Hello"  # => "Hello" 

注意,在本實施例中可以清楚地從該[email protected]方法是從類缺少

注意,上述示例中的錯誤消息見將與Ruby 2.3不同,因爲從該版本開始,爲字符串定義了一元減號和加號,它們指的是從原始數據返回凍結和解凍的字符串。

+0

體面的解釋,+1 –