2010-07-24 7 views
5

Jestem pewien, że jest bardziej idiomatycznych Ruby sposób napisać poniższy kod:Więcej idiomatyczny ruby ​​sposób pisania @var = obj ['blah'] chyba obj ['blah']. Nil?

@var = obj['blah'] unless obj['blah'].nil? 

Mam cały ładunek nich zrobić (patrz poniżej), i nie musi być ładniejszy sposób!

@num_x = obj['num_x'] unless obj['num_x'].nil? 
@num_y = obj['num_y'] unless obj['num_y'].nil? 
@num_iterations = obj['num_iterations'] unless obj['num_iterations'].nil? 
@pe = obj['pe'] unless obj['pe'].nil? 

Mam wrażenie, że operator ||= mogą być przydatne, ale nie może wydawać się dość wypracować jak go używać.

+3

'|| =' służy do sprawdzania, czy sama zmienna jest zerowa. Co próbujesz osiągnąć? Dlaczego jest problem, jeśli te ivars są zerowe? – jtbandes

Odpowiedz

2

najkrótsza mogę myśleć o tej wspólnej potrzebie jest

@var = obj['blah'] or @var 

choć jeśli obj['blah'] może być false, trzeba iść z oryginalnej wersji.

Operator ||= testuje lewą stronę, a nie prawą stronę, więc nie ma tu zastosowania.

+0

Twój kod jest nieco inny: W twoim przykładzie '@ var' nie jest aktualizowany to' obj ['blah'] = false'. W przykładzie OPs jest zawsze aktualizowany, z wyjątkiem wartości 'nil'. – Veger

+0

@Veger: oczywiście. dlatego wspominam, że jeśli 'obj ['blah']' może być fałszywe, potrzebujesz oryginalnej wersji. – Peter

+0

Przepraszam, nie zauważyłem tego! Och, zmieniłeś odpowiedź ... :) Teraz zawsze aktualizujesz '@ var', nie wiem, czy to jest bardzo wydajne, ale jest zwarte w kodzie ... – Veger

3

zależności od okoliczności i jeśli zmienne instancji już istniejącej wartości, które chcesz zachować, jeżeli wartość w obj jest nil to nie może być problem, po prostu pozwolić im być ustawiony nil.

Alternatywnie, można napisać niewiele funkcji pomocnika jak:

def set_instance_variables_for_non_nil_values(h, *keys) 
    keys.each do |key| 
    instance_variable_set "@#{key}", h[key] unless h[key].nil? 
    end 
end 

Następnie w przykładowym kodem byś go używać tak:

set_instance_variables_for_non_nil_values obj, 'num_x', 'num_y', 
    'num_iterations', 'pe' 
+0

To jest dobre rozwiązanie, które robi to, o co pytano. Powiedziałbym jednak, że masowe ustawienie zmiennych instancji, takich jak ten, jest złym pomysłem, chyba że masz naprawdę dobry powód. –

1

Jak to:

obj['blah'] && var = obj['blah'] 
0

jeśli @var ma już wartość, która nie jest zerowa lub fałszywa, można użyć

@var &&= obj['blah'] 

ale byłbym skłonny do znalezienia prostszego rozwiązania, które może być łączone z hasłami , jeśli istnieje wiele wartości.

takich jak:

obj = {:num_x => 23, :num_y => 75, :pe => 99} 

locals = {:num_x => 1, :num_y => 2, :num_iterations => 3, :pe => 4} 

puts locals.inspect #=> {:num_y=>2, :pe=>4, :num_iterations=>3, :num_x=>1} 

locals.merge! obj 

puts locals.inspect #=> {:num_y=>75, :pe=>99, :num_iterations=>3, :num_x=>23} 

który służy do opcji wielu klejnotów widziałem ustawienie.