2013-08-23 19 views
23

Czy ktoś może wyjaśnić opcje skrótów? Pracuję na kursie ruby ​​od testfirst.org. Ćwiczenie 10 (temperatura_obiektu) wymaga znajomości opcji skrótów.Co to są opcje skrótów?

Odpowiedz

44

Mieszanie opcji jest ładną koncepcją włączoną przez funkcję analizatora składni ruby. Powiedzmy, że masz metodę z pewnymi wymaganymi argumentami. Możesz także przekazać kilka opcjonalnych argumentów. Z biegiem czasu możesz dodać więcej argumentów opcjonalnych lub usunąć stare. Aby deklaracja metody była czysta i stabilna, można przekazać wszystkie te opcjonalne argumenty w haszowaniu. Taki sposób będzie wyglądać następująco:

def foo(arg1, arg2, opts = {}) 
    opts.to_s # just return a string value of opts 
end 

Więc to ma dwa wymagane wartości i ostatni argument z domyślnej wartości hash. Jeśli nie masz żadnych argumentów opcjonalnych do przekazania, to nazwać tak:

foo(1, 2) # => "{}" 

Jeśli masz coś opcjonalne, to nazwać tak:

foo(1, 2, {truncate: true, redirect_to: '/'}) # => "{:truncate=>true, :redirect_to=>\"/\"}" 

Kod ten jest tak idiomatyczne ruby, że jego parser rzeczywiście pozwala pominąć nawiasy klamrowe podczas przechodzenia hash jako ostatni argument do metody:

foo(1, 2, truncate: true, redirect_to: '/') # => "{:truncate=>true, :redirect_to=>\"/\"}" 

Jeśli używasz szyny, na przykład, zobaczysz opcje nagłówków lub wszędzie. Tutaj, otworzyłem tylko losowy kontrolera w mojej aplikacji:

class ProductsController < ApplicationController 
    before_filter :prepare_search_params, only: :index 
            # ^^^^^^^^^^ options hash here 

Tak więc, w krótkim: Opcje mieszania jest argumentem metody, który znajduje sie ostatni i ma domyślną wartość {}. I zwykle przekazuje się do niego hashe (stąd nazwa).

+7

W nowoczesnej wersji Ruby powinieneś naprawdę używać argumentów słów kluczowych zamiast skrótu opcji. –

+0

@ JörgWMittag czy możesz wyjaśnić? – Dennis

+1

@Dennis: google "argumenty ruby ​​słów kluczowych" –

5

z opcjami mieszania odnosi się do konwencji możliwości przejścia do metod przy użyciu mieszania ({}) podobnie jak

my_func(arg1, arg2, {:opt1 => 'foo', :opt2 => 'bar'}) 

Konwencja dla opcji Hash jest ostatnim argumentem tak, że może być opcjonalnie . Na przykład.

def my_func(argument1, argument2, options = {}) 
    ... 
end 

A więc hash opcji nie jest niczym specjalnym. To tylko opcjonalny końcowy argument, który jest hash. Opcje hashe są tak poręczne i powszechne, że interpreter pozwala także zostawić poza nawiasami (jest to jeden „specjalne” część o nich)

my_func(arg1, arg2, :opt1 => 'foo', :opt2 => 'bar') 

połączeniu z symbolem krzyżyka klawisz skrótu Ruby i opcjonalnych nawiasach, to może skończyć patrząc naprawdę czyste:

my_func arg1, arg2, opt1: 'foo', opt2: 'bar' 
2

Odwrócona Merge jest najlepszym sposobem wdrożenia opcji mieszań w ruby ​​/ szyny:

def set_state_application(options_hash) 
    options_hash.reverse_merge!(send_email: true, other_default_val: 'a') #will set defaults 
    self.update_column(:status_id, VendorEnums::VendorStatus::APPLICATION) 
    VendorMailer.email_application(self) if options_hash[:send_email] 
    save_state 
end 
9

opcje skróty stosowane są dużo gdy n przekazać opcjonalne argumenty do metody.

Na przykład, jeśli metoda ma jeden-dwa opcjonalne argumenty, można napisać

def method(arg1, arg2 = nil, arg3 = nil) 
    ... 
end 

Ale jeśli masz więcej opcjonalnego argumentu robi się brzydkie, aby przypisać je do zera za każdym razem. Nadchodzi hash opcji, które pozwala na pisanie

def method(arg1, options={}) 
    @arg1 = arg1 
    @arg2 = options[:arg2] 
    .... 
    @arg15 = options[:arg15] 
end 
2

Ponieważ wszystkie te odpowiedzi są poprawne, rubin 2 ulepszone wsparcie dla słów kluczowych argumentów.

Możesz zdefiniować swoją metodę z domyślnymi hashami jako *args i usunąć options = {}.

def foo(bar: 'initial') 
    puts bar 
end 

foo # => 'initial' 
foo(bar: 'final') # => 'final' 

Wymagane argumenty trzeba dwukropek po kluczu (również trzeba ruby ​​2.1)

def foo(bar:) 
    puts bar 
end 

foo # => ArgumentError: missing keyword: bar 
foo(bar: 'baz') # => 'baz' 

opcjonalne argumenty, można ustawić domyślne do nil

def foo(bar: nil, baz: 'aaa') 
    puts "#{bar}:#{baz}" 
end 

foo # => ':aaa' 
foo(baz: 'zab') # => ':zab' 
foo(bar: 'rab', baz: 'zab') # => 'rab:zab' 
foo(bin: 'bin') # => ArgumentError: unknown keyword: bin 

także może wykorzystywać standardowe argumenty pozycyjne z tą nową notacją parametrów skrótu. Więcej informacji można znaleźć w tym dokumencie: blog i oficial.

Bonus: Refaktor jest łatwy, ponieważ możesz pozbyć się opcji mieszania swojej metody bez zmiany jej połączeń. Ale ... to nie jest do końca prawdą, jeśli masz połączenie z nieoczekiwaną opcją, dostaniesz ArgumentError: unknown keyword: invalid_arg.