Ruby中方法的静态局部变量?
Posted
技术标签:
【中文标题】Ruby中方法的静态局部变量?【英文标题】:Static local variables for methods in Ruby? 【发布时间】:2011-11-02 08:40:48 【问题描述】:我有这个:
def valid_attributes
:email => "some_#rand(9999)@thing.com"
end
Rspec 测试对吗?但我想做这样的事情:
def valid_attributes
static user_id = 0
user_id += 1
:email => "some_#user_id@thing.com"
end
我不希望 user_id
可以从除该方法之外的任何地方访问,
Ruby 可以做到这一点吗?
【问题讨论】:
简短的回答是否定的,Ruby 中没有static
这样的东西。为什么不让数据库处理你的自增键呢?
因为它是一种为Rspec测试生成有效属性的方法,有些东西必须是唯一的。
【参考方案1】:
这是一个结案案例。试试这个
拉姆达 用户 ID = 0 self.class.send(:define_method, :valid_attributes) 做 用户 ID += 1 :email => "some_#user_id@thing.com" 结尾 。称呼在 lambda 中包装所有内容允许在 lambda 中定义的变量仅存在于作用域中。您也可以添加其他方法。祝你好运!
【讨论】:
我在你的代码后面加了两个p valid_attributes
,但我得到了Error NoMethodError: undefined method '+' for nil:NilClass
。我猜user_id
里面的def
是一个初始化为nil
的局部变量。也许你可以用另一种方式使用闭包。 :)
嗨索尼,我忘记了 def。我已经将它更改为define_method,所以它现在应该能够访问user_id。以这种方式在 lambda 中定义的其他方法也可以共享 user_id 变量。
好的,但是你必须使用self.class.send :define_method, :valid_attributes
,因为define_method
是一个私有类方法。无论如何,我更喜欢您的解决方案而不是 mine,因为在我的情况下,valid_attributes
是一个过程(在 1.8.7 中必须使用 call
或 []
调用),而在您的情况下,它是一种真正的方法。
【参考方案2】:
这个答案的范围比你的问题要大一些,但我认为它是你想要做的事情的根源,并且将是最简单和最可维护的。
我认为您在这里真正寻找的是工厂。尝试使用 factory_girl 之类的东西,这将使很多测试变得更加容易。
首先,您将设置一个工厂来创建您正在测试的任何类型的对象,并为电子邮件属性使用序列:
FactoryGirl.define do
factory :model do
sequence(:email) |n| "person#n@example.com"
# include whatever else is required to make your model valid
end
end
然后,当你需要有效的属性时,你可以使用
Factory.attributes_for(:model)
您还可以使用Factory.create
和Factory.build
创建模型的已保存和未保存实例。
getting started document 中有更多功能的解释,以及如何将工厂添加到项目的说明。
【讨论】:
谢谢!我会明确地检查那个宝石! ^^【参考方案3】:你可以使用闭包:
def validator_factory
user_id = 0
lambda do
user_id += 1
:email => "some_#user_id@thing.com"
end
end
valid_attributes = validator_factory
valid_attributes.call #=> :email=>"some_1@thing.com"
valid_attributes.call #=> :email=>"some_2@thing.com"
这样user_id
将无法在外面访问。
【讨论】:
【参考方案4】:我会使用实例变量:
def valid_attributes
@user_id ||= 0
@user_id += 1
:email => "some_#@user_id@thing.com"
end
【讨论】:
【参考方案5】:Ruby 仅有的变量是局部变量、实例变量、类变量和全局变量。它们都不适合你的追求。
您可能需要一个存储 user_id 并每次都为您提供新 ID 号的单例。否则,您的代码将不是线程安全的。
【讨论】:
以上是关于Ruby中方法的静态局部变量?的主要内容,如果未能解决你的问题,请参考以下文章
java中静态成员变量、实例变量、局部变量何时创建、何时销毁?