2013-06-05 19 views
25

Często skrócić blok używając notacji & na symbol tak:Czy jest krótka droga do napisania `{| x | x} `?

some_array.group_by(&:foo) 

Czy istnieje podobny sposób skrócić wyrażeń jak {|x| x}?

some_array.group_by{|x| x} 

Gdyby nie było to metoda, która zwraca selfObject#self, to możemy zrobić

some_array.group_by(&:self) 

ale niestety nie ma takiej metody. Pod względem liczby znaków może być dłuższy, ale poprawia się czytelność.

+1

nie 'it' jak w Groovy, boję – Ven

+3

To jest [Identity Function] (http: //en.wikipedia .org/wiki/Identity_function). 'IDENT = Proc.new {| x | x}; array.group_by (& IDENT) '. – user2246674

+0

Czy 'to_proc' ma sens w tym kontekście? Mogę się mylić. – squiguy

Odpowiedz

29

Tak. #itself został zaimplementowany w Rubim 2.2.0.


Możesz uzyskać dostęp do dyskusji zespołu rdzeniowego Ruby na temat tej funkcji here.

Jako interesujący analog, #ergo metoda has been proposed, która dałaby odbiornik do danego bloku.

Jeśli nie masz jeszcze uaktualniony do Ruby 2.2.0, może chcesz backport #itself i/lub zdefiniować #ergo następująco:

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

, a następnie:

some_array.group_by &:itself 
+0

Dobra wiadomość, aby to usłyszeć. Dzięki za informację. Mam nadzieję, że wkrótce zostanie wdrożony. – sawa

+0

Cóż, przypisali to do "następnego niewielkiego wydania", ale już pracują nad wersją 2.1, a ta funkcja wciąż jest wstrzymywana. Może więc "następny pomniejszy" nie oznacza "zaraz następny" :-))) Sądzę, że są bardzo zajęci i wciąż potrafią odpowiedzieć na sugestie. –

+0

Świetne !! :) '+ 1' do Ciebie. –

17

Cóż, nie ma wbudowaną o ile mi wiadomo, ale można dokonać wielokrotnego użytku blok Tożsamość:

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

A jeśli naprawdę chcesz to była funkcja język:

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

A następnie można wykonać:

w dowolnym miejscu. Może to spowodować utratę gwarancji.

+0

To jest zasadniczo to, o czym mówiłem w swoim komentarzu. +1 – squiguy

12

Tak! Metodę Kernel#itself dodano w Ruby 2.2.0. Metoda ta po prostu zwraca obiekt był nazywany dalej, więc można napisać:

some_array.group_by(&:itself) 

Można zobaczyć obszerną dyskusję o tej funkcji tutaj: https://bugs.ruby-lang.org/issues/6373. Łata została przedłożona przez Rafaela Françę w wiadomości nr 53. Możesz go zobaczyć w oficjalnym źródle Ruby, szukając w object.c.

Jeśli używasz wersji Ruby starsze niż 2.2.0, można łatwo dodać Kernel#itself do projektu umieszczając ten kod gdzieś w swoim projekcie i upewniając się, że pobiera wymagane:

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

jednak łatanie małpy w taki sposób jak rdzeń Ruby może być niebezpieczne i nie polecałbym go, jeśli tworzysz kod wielokrotnego użytku, jak klejnot.Zamiast tego polecam tylko tworzyć własne funkcje tożsamości, jak sugeruje user2246674:

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

    array.group_by(&IDENT) 
end 
Powiązane problemy