2012-02-11 53 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 
相关问题