2016-10-16 10 views
7

ich einige Code las, und ich sah etwas entlang der Linien vonWas bedeutet + @ bedeuten als Methode in Ruby

module M 
    def [email protected] 
    self 
    end 
end 

Ich war überrascht, dass dies legal Syntax, aber wenn ich ruby -c auf die Datei lief (zu fusseln) es sagte, es sei gültig. [email protected] war auch eine legale Methode Name noch, als ich versuchte *@ oder [email protected] beide von denen waren illegal. Ich habe mich gefragt, was [email protected] bedeutet und warum ist es legal?

Antwort

12

Rubin enthält einige unäre Operatoren, einschließlich +, -, !, ~, & und *. Wie bei anderen Operatoren können Sie diese auch neu definieren. Für ~ und ! können Sie einfach nur def ~ und def ! sagen, da sie kein binäres Gegenstück haben (z. B. können Sie nicht sagen a!b).

jedoch für - und + gibt es sowohl eine einstellige und eine binäre Version (z a+b und +a sind beide gültig), wenn Sie also die einstellige Version neu definieren möchten Sie def [email protected] und def [email protected] verwenden.

Beachten Sie auch, dass es eine unäre Version von * und & als auch gibt, aber sie haben eine besondere Bedeutung. Für * ist es gebunden, um das Array zu sprengen, und für & ist es gebunden, das Objekt in ein proc zu konvertieren, also wenn Sie sie verwenden möchten, müssen Sie to_a bzw. to_proc neu definieren. Hier

ist ein vollständigeres Beispiel alle Arten der unäre Operatoren zeigt:

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

In Ihrem Beispiel das Modul einfach nur definiert einen einstelligen Operator +, mit einem Standardwert von nichts mit dem Objekt zu tun (Das ist ein übliches Verhalten für das unäre Plus, 5 und +5 bedeuten normalerweise dasselbe. Das Mischen mit jeder Klasse würde bedeuten, dass die Klasse sofort Unterstützung für die Verwendung des unären Plus-Operators erhält, was nicht viel bewirken würde.

Zum Beispiel (unter Verwendung von Rubin <=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" 

Beachten Sie, dass Sie in diesem Beispiel deutlich von der Fehlermeldung, die [email protected] Methode aus der Klasse fehlt

Hinweis sehen, dass das obige Beispiel unterscheidet sich von Ruby 2.3, da die unären Minuszeichen und Pluszeichen für Strings seit dieser Version definiert sind, und sie beziehen sich auf das Zurückgeben einer eingefrorenen und ungefrorenen Zeichenfolge aus dem Original.

+0

anständige Erklärung, +1 –

1

die Methodennamen [email protected][email protected] und werden verwendet, um die unäre Operatoren + und - in Ruby (1.9+) zu überlasten. Unäre Operatoren sind Operatoren, die nur einen einzigen Wert annehmen (z. B. value = -value).