2013-06-05 14 views
25

Wir verkürzen oft einen Block mit der & Notation auf ein Symbol wie folgt aus:Gibt es einen kurzen Weg, um `{| x | zu schreiben x} `?

some_array.group_by(&:foo) 

Gibt es eine ähnliche Art und Weise Ausdrücke wie {|x| x} zu verkürzen?

some_array.group_by{|x| x} 

Wenn es eine Methode Object#self waren die self zurückgibt, dann können wir

some_array.group_by(&:self) 

tun, aber leider gibt es keine solche Methode. In Bezug auf die Anzahl der Zeichen kann es länger sein, aber die Lesbarkeit verbessert sich.

+1

keine 'Es' wie in stark, ich habe Angst – Ven

+3

Das ist die [Identität Function] (http: //en.wikipedia .org/wiki/Identitätsfunktion). 'IDENT = Proc.neu {| x | x}; array.group_by (& IDENT) '. – user2246674

+0

Macht 'to_proc' in diesem Zusammenhang Sinn? Ich könnte falsch liegen. – squiguy

Antwort

29

Ja. #itself wurde in Ruby 2.2.0 implementiert.


können Sie die Diskussion Ruby-Core-Team Zugriff zu dieser Funktion here.

Als ein interessantes Analog, #ergo Methode has been proposed, die den Empfänger zu einem bestimmten Block liefern würde.

Wenn Sie noch nicht von Ruby 2.2.0 aktualisiert haben, können Sie möchten #itself zurückzuportieren und/oder #ergo wie folgt definieren:

class Object 
    def itself; self end 
    def ergo 
    fail ArgumentError, "Block expected!" unless block_given? 
    yield self 
    end 
end 

Und dann:

some_array.group_by &:itself 
+0

Gute Nachrichten, das zu hören. Danke für die Information. Ich hoffe, es wird bald umgesetzt werden. – sawa

+0

Nun, sie haben es der "nächsten Nebenversion" zugewiesen, aber sie arbeiten bereits an 2.1, und diese Funktion wird immer noch zurückgehalten. Vielleicht bedeutet "next minor" nicht gleich "sofort next" :-))) Ich denke, sie sind sehr beschäftigt und schaffen es trotzdem, auf Vorschläge zu reagieren. –

+0

Großartig !! :) '+ 1' zu dir. –

17

Nun, es gibt keine eingebaute, soweit ich weiß, aber man kann eine wiederverwendbare Identität Block machen:

id = Proc.new {|x| x} 
some_array.group_by(&id) 

Und dann wirklich, wenn möchten diese waren eine Sprache-Funktion:

class Object 
    def it 
    Proc.new {|x| x} 
    end 
end 

Und dann können Sie

some_array.group_by(&it) 

tun, wo immer Sie wollen. Dies kann zum Erlöschen der Garantie führen.

+0

Dies ist im Wesentlichen, worüber ich in meinem Kommentar gesprochen habe. +1 – squiguy

12

Ja! Die Methode Kernel#itself wurde in Ruby 2.2.0 hinzugefügt. Diese Methode gibt einfach das Objekt wurde aufgerufen, so können Sie schreiben:

some_array.group_by(&:itself) 

Sie können die ausführliche Diskussion dieser Funktion hier sehen: https://bugs.ruby-lang.org/issues/6373. Der Patch wurde von Rafael França in Nachricht # 53 eingereicht. Sie können es in der offiziellen Ruby-Quelle sehen, indem Sie in object.c suchen.

Wenn Sie eine Version von Ruby verwenden älter als 2.2.0, können Sie leicht Kernel#itself in Ihrem Projekt hinzufügen, indem Sie diesen Code irgendwo in Ihrem Projekt setzen und dafür sorgen, es wird benötigt:

module Kernel 
    def itself 
    self 
    end 
end if !Kernel.instance_methods.include?(:itself) 

jedoch Das Patchen eines Teils des Ruby-Kerns auf diese Weise kann gefährlich sein und ich würde es nicht empfehlen, wenn Sie wiederverwendbaren Code wie einen Edelstein herstellen.Stattdessen würde ich empfehlen, nur die eigene Identität Funktion zu machen, wie user2246674 vorgeschlagen:

module MyLibrary 
    IDENT = Proc.new { |x| x } 

    array.group_by(&IDENT) 
end 
Verwandte Themen