2012-02-11 73 views
2

我試圖保留一個本地散列函數,該函數可以記住函數調用之間的狀態。但是我不知道如何在沒有關閉的情況下聲明它(如同一些用戶在類似的線程中所建議的那樣)。在ruby中,我該如何聲明C++等價的「靜態」函數變量?

我知道C++比紅寶石更徹底,並在C++中,我會通常被使用的static局部變量,像在第一個例子在這裏:http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx

我設法在紅寶石使用defined?功能一起砍東西:

def func x 
    if not defined? @hash 
    @hash = Hash.new 
    end 

    if @hash[x] 
    puts 'spaghetti' 
    else 
    @hash[x] = true 
    puts x.to_s 
    end 
end 

func 1 
func 1 

這打印,下面,這是我想要的。唯一的問題是@hash可以在該函數之外訪問。

1 
spaghetti 

是否有任何「更清潔」,更喜歡用這種行爲聲明變量的方法(沒有工廠)?我打算創建兩個或三個變量,如@hash,所以我正在尋找一個更好的方式來簡潔地表達這一點。

+0

你真的想要做什麼?將C++解決方案轉譯成Ruby可能不是一個好主意。將你的「靜態局部函數」包裝在一個單獨的對象中可能更有意義。 – 2012-02-11 06:20:55

+0

在我的實際問題中,我寫了一個函數'generate_prime n',它生成第n個素數,而另一個函數'prime?檢查它的論點是否是主要的。這兩個函數都會有很多重複的參數,所以我試圖在Hashes/Bignum對象中緩存一些結果。 – 2012-02-11 07:20:51

回答

1

你在做什麼在Ruby中很常見,但也很常見,你不需要大驚小怪。所有@類型的實例變量僅對該實例是本地的。請記住,「實例」一般指的是一個類的實例,但它也可以指類的實例

您可以使用@@從實例的上下文中引用類實例變量,但這在實踐中往往會變得混亂。

你想要做的是以下之一。

該方法調用之間仍然存在,但僅在單個對象實例的上下文中的變量:

def func(x) 
    # Instance variables are always "defined" in the sense that 
    # they evaluate as nil by default. You won't get an error 
    # for referencing one without declaring it first like you do 
    # with regular variables. 
    @hash ||= { } 

    if @hash[x] 
    puts 'spaghetti' 
    else 
    @hash[x] = true 
    puts x.to_s 
    end 
end 

該方法調用之間仍然存在,但只有內的所有對象的上下文的可變實例:

def func(x) 
    # Instance variables are always "defined" in the sense that 
    # they evaluate as nil by default. You won't get an error 
    # for referencing one without declaring it first like you do 
    # with regular variables. 
    @@hash ||= { } 

    if @@hash[x] 
    puts 'spaghetti' 
    else 
    @@hash[x] = true 
    puts x.to_s 
    end 
end 

這通常通過將@@hash包裝到類方法中變得更清潔。這具有使測試更容易的次要效果:

def self.func_hash 
    @func_hash ||= { } 
end 

def func(x) 
    if self.class.func_hash[x] 
    puts 'spaghetti' 
    else 
    self.class.func_hash[x] = true 
    puts x.to_s 
    end 
end