2012-06-22 4 views
15

Açıkçası ||=Ruby'de doğru, yanlış veya sıfır geri dönebilecek bir yöntemi nasıl belleğe alabilirim? ortaya çıkarsa <code>false</code> veya <code>nil</code> ardından <code>expensive_way_to_calculate_x</code> tekrar tekrar çalıştırmak alacak olması nedeniyle

def x? 
    @x_query ||= expensive_way_to_calculate_x 
end 

çalışmaz.

Şu bildiğim en iyi yolu, bir Array içine değerini koymaktır:

def x? 
    return @x_query.first if @x_query.is_a?(Array) 
    @x_query = [expensive_way_to_calculate_x] 
    @x_query.first 
end 

Bunu yapmanın daha geleneksel bir ya da verimli bir yolu var mı?

GÜNCELLEME ben false ilaveten nil memoize istediğini fark - Bu https://rails.lighthouseapp.com/projects/8994/tickets/1830-railscachefetch-does-not-work-with-false-boolean-as-cached-value tüm yolu geri gider - özürlerimi bir başka tamamen doğru cevap verdi Andrew Marshall için. @x_query değeri yerine nil ise

+0

Bu, nil'in ve null'ın tüm kavramının ne için olduğu. – meagar

+0

Sorumu ilk defa doğru şekilde yapmadım çünkü - ben de nil memoize etmek istiyorum. –

cevap

26

Açıkça kontrol edin: Bu bir örnek değişkeni olmasaydı yerine de/tanımlandı, sen, kontrol etmek olurdu

def x? 
    @x_query = expensive_way_to_calculate_x if @x_query.nil? 
    @x_query 
end 

Not her örnek değişkene beri varsayılan olarak nil.

@x_query Güncellemenizin Verilen 'ın memoized değeri nil olabilir, sen gerçeği aşmanın yerine defined? kullanabileceği tüm örnek değişkenleri varsayılan nil için:

def x? 
    defined?(@x_query) or @x_query = expensive_way_to_calculate_x 
    @x_query 
end 

Not olduğunu a = 42 unless defined?(a) won böyle bir şey yaptığını' Çözümleyici a =, a tanımlandığında, koşullu duruma geldikten sonra beklendiği gibi beklendiği gibi çalışır. Ancak, bu örnek, nil varsayılanı olduğundan, örnek değişkenlerde doğru değildir; ayrıştırıcı, = sonucuna ulaştığında bunları tanımlamaz. Ne olursa olsun, or veya unless 'un uzun satır formunu unless yerine unless yerine tutarlı tutmak için kullanmak iyi bir deyim olduğunu düşünüyorum. Değişken tanımlı edilmemiş ise

def x? 
    return @x_query if defined? @x_query 
    @x_query = expensive_way_to_calculate_x 
end 

defined?nil dönecektir veya başka dize "instance_variable":

+0

Bu konuya son vereceğim çünkü bu benim sorumun ilk sürümünün cevabı, fakat lütfen düzenlemelerime bir bakın - yine özür dilerim. –

+0

@SeamusAbshere Cevabımı, güncellemeni yansıtacak şekilde güncelledim:). –

+3

'a = 42 tanımlanmadıkça? (A)' 'n''nı nil yapar, fakat' @ a = 42 tanımlı olmadıkça (a) '' '' '' '' 42 yapar, bu nedenle '' '' '' '' '' '' '' sözdizimi kesinlikle gerekli değildir bu örnekte. –

18

değişken tanımlanmış olup olmadığını görmek için defined? kullanın nil hesaba katmak

irb(main):001:0> defined? @x 
=> nil 
irb(main):002:0> @x = 3 
=> 3 
irb(main):003:0> defined? @x 
=> "instance-variable" 
İlgili konular