2009-06-08 78 views
14

我應該使用if defined?在Ruby中,我應該使用|| =還是定義?進行記憶?

return @current_user_session if defined?(@current_user_session) 
@current_user_session = UserSession.find 

或者||=

@current_user_session ||= UserSession.find 

我注意到if defined?方法的使用最近越來越多。對另一個有利嗎?就我個人而言,我更喜歡||=的可讀性。我也認爲Rails可能有一個memoize宏,它透明地提供了這種行爲。是這樣嗎?

+0

它叫做memoize的 – nasmorn 2009-06-08 18:50:10

回答

24

小心:x || = y如果x返回false,則賦值x = y。這可能意味着x是未定義的,無,或錯誤的。

有很多次變量將被定義併爲false,但也許不在@current_user_session實例變量的上下文中。

如果你渴望簡潔,儘量條件結構:

defined?(@current_user_session) ? 
    @current_user_session : @current_user_session = UserSession.find 

或者只是:

defined?(@current_user_session) || @current_user_session = UserSession.find 

,如果你只需要初始化變量。

+1

你的意思是'定義(@ current_user_session)或@current_user_session = UserSession? .find`(`或`而不是`||`)? – Jimothy 2016-01-11 16:28:04

0

此外,更好的||=會產生關於未初始化的實例變量的警告(至少在1.8.6和1.8.7),而更詳細的defined?版本則不會。

在另一方面,這可能是你想要做什麼:

def initialize 
    @foo = nil 
end 

def foo 
    @foo ||= some_long_calculation_for_a_foo 
end 

但是,這幾乎可以肯定不會:

def initialize 
    @foo = nil 
end 

def foo 
    return @foo if defined?(@foo) 
    @foo = some_long_calculation_for_a_foo 
end 

因爲@foo總是可以在這一點定義。

+0

整點定義?是檢查未初始化的實例變量。 – Sam 2009-06-08 15:54:56

+0

另外,定義?(:@ foo)總是返回「表達式」。你的意思是定義?(@ foo)。定義?(@ foo)返回nil或「實例變量」。 – 2009-06-15 18:39:14

1

的Rails確實有記憶化,看看下面的截屏爲一個偉大的介紹:

http://railscasts.com/episodes/137-memoization

class Product < ActiveRecord::Base 
    extend ActiveSupport::Memoizable 

    belongs_to :category 

    def filesize(num = 1) 
    # some expensive operation 
    sleep 2 
    12345789 * num 
    end 

    memoize :filesize 
end 
相關問題