2016-01-14 10 views
6

Mam prostą klasę, która po inicjalizacji pobiera od jednego do ośmiu parametrów. Ustawia te akcesory do użycia później. Rubocop próbuje mnie aresztować, ponieważ ABC jest zbyt wysoka, ale nie jestem pewien, czy coś jest nie tak z tym, co zrobiłem. Czy to jest przypadek, w którym po prostu wyłączam inspekcję na moim inicjowaniu?Stan gałęzi przydziału za wysoki

class Foo 
    attr_accessor :one, :two, :three, :four 
    attr_accessor :five, :six, :seven, :eight 

    def initialize(p={}) 
    @one = p[:one] if p[:one].present? 
    # ... 
    @eight = p[:eight] if p[:eight].present? 
    end 
end 

Jedyna myśl na zmniejszenie rozmiaru byłoby zrobić coś jak iteracja wszystkich moich attr_accessors na initialize, sprawdzając, czy istnieje odpowiedni symbol przepuszcza w ma, a jeśli tak, przypisując go.

Ale wydaje się to trochę słabe.

Odpowiedz

4

Oto jeden ze sposobów, aby osiągnąć to, co staramy się robić:

class Foo 
    %i(one two three four five six seven eight).each { |attribute| attr_accessor attribute } 

    def initialize(p = {}) 
    p.keys.each { |k| instance_variable_set("@#{k}", p.fetch(k, nil)) } 
    end 
end 

sprawdzić na Hash#fetch metody.

Można również użyć go tylko dostęp pary klucz-wartość p zmiennej jeśli zamiast 8 zmienne decydują się przejść z jednego (@p)


EDIT

prostu z ciekawość napisał tę wersję (niektóre meta programowania używany) - będzie dynamicznie dodać attr_accessor dla dodawanych zmiennych instancji:

class Foo 
    def initialize(p = {}) 
    p.keys.each do |k| 
     instance_variable_set("@#{k}", p.fetch(k, nil)) 
     self.class.__send__(:attr_accessor, k) 
    end 
    end 
end 

Co się dzieje, przyjmujemy argument metody initialize (hash p), otrzymujemy jego klucze i tworzymy z nich zmienne instancji, przypisując każdą zmienną wartością odpowiadającą kluczowi. Następnie definiujemy attr_accessor dla każdego z kluczy.

a = Foo.new(a: 2, b: 3) 
#=> #<Foo:0x00000002d63ad8 @a=2, @b=3> 
+0

To wygląda podobnie do tego, co myślałem, że może być policjantem. Pun przeznaczone. Chociaż zgadzam się, że jest to sposób na rozwiązanie tego problemu, czy istnieje odniesienie, które można wskazać, abym mógł przeczytać więcej o tym, dlaczego jest to "właściwy" sposób? Dzięki za poświęcenie czasu na odpowiedź! – CarlyL

+0

@CarlyL Odnośnie właściwej drogi - Ruby jest językiem bardzo elastycznym, więc można robić różne rzeczy. I często "właściwa droga" jest kwestią osobistych preferencji. Myślę, że możesz przeczytać Ruby Style Guides, aby zobaczyć, co ** nie ** zrobić, ale wątpię, by ktoś twierdził, że coś jest w 100% słuszne :) –

+0

Możesz również umieścić nazwy atrybutów w zamrożonej tablicy, np. '' 'ATTR_NAMES =% i (jeden dwa trzy cztery pięć sześć siedem osiem) .freeze'''' i wywołaj' '' attr_accessor (* ATTR_NAMES) '' ' –

2

Nie należy przypisywać każdej z nich jako różnych zmiennych. Powinieneś raczej zapisać to jako zmienną jako pojedynczy hash i uzyskać dostęp do skrótu, gdy potrzebujesz wartości. W rzeczywistości wydaje się, że masz zmienną p. Zachowaj to jako @p = p.

+0

Dzięki za poświęcenie czasu na odpowiedź. Obie odpowiedzi mówią, że mogę mieć tylko jeden attr_accessor p, który jest hash, ale wydaje mi się to trochę dziwne. Czy masz jakieś referencje, które mogę przeczytać, dlaczego to byłby najlepszy sposób? – CarlyL

Powiązane problemy