Ruby 中方法的静态局部变量?

发布于 2024-12-01 05:22:45 字数 347 浏览 4 评论 0原文

我有这个:

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 来说可能吗?

I have this:

def valid_attributes
  { :email => "some_#{rand(9999)}@thing.com" }
end

For Rspec testing right? But I would like to do something like this:

def valid_attributes
  static user_id = 0
  user_id += 1
  { :email => "some_#{user_id}@thing.com" }
end

I don't want user_id to be accessible from anywhere but that method,
is this possible with Ruby?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

和我恋爱吧 2024-12-08 05:22:45

这是一个结案案例。尝试

lambda {
  user_id = 0

  self.class.send(:define_method, :valid_attributes) do
    user_id += 1
    { :email => "some_#{user_id}@thing.com" }
  end

}.call

将所有内容包装在 lambda 中允许 lambda 中定义的变量仅存在于作用域中。您还可以添加其他方法。祝你好运!

This is a closure case. Try this

lambda {
  user_id = 0

  self.class.send(:define_method, :valid_attributes) do
    user_id += 1
    { :email => "some_#{user_id}@thing.com" }
  end

}.call

Wrapping everything in lambda allows the variables defined within lambda to only exist in the scope. You can add other methods also. Good luck!

单身情人 2024-12-08 05:22:45

这个答案的范围比你的问题大一点,但我认为它是你想要做的事情的根源,并且将是最简单和最可维护的。

我认为你在这里真正寻找的是工厂。尝试使用类似 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 .createFactory.build 用于创建已保存和未保存的模型实例。

入门文档中对更多功能进行了解释,以及有关如何将工厂添加到项目中的说明。

This answer is a little larger in scope than your question, but I think it gets at the root of what you're trying to do, and will be the easiest and most maintainable.

I think what you're really looking for here is factories. Try using something like factory_girl, which will make a lot of testing much easier.

First, you'd set up a factory to create whatever type of object it is you're testing, and use a sequence for the email attribute:

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

Then, when you need valid attributes, you can use

Factory.attributes_for(:model)

You can also use Factory.create and Factory.build to create saved and unsaved instances of the model.

There's explanation of a lot more of the features in the getting started document, as well as instructions on how to add factories to your project.

毅然前行 2024-12-08 05:22:45

您可以使用闭包:

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=>"[email protected]"}
valid_attributes.call  #=>  {:email=>"[email protected]"}

这样外部就无法访问 user_id 了。

You can use a closure:

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=>"[email protected]"}
valid_attributes.call  #=>  {:email=>"[email protected]"}

This way user_id won't be accessible outside.

红ご颜醉 2024-12-08 05:22:45

我会使用实例变量:

def valid_attributes
  @user_id ||= 0
  @user_id += 1
  { :email => "some_#{@user_id}@thing.com" }
end

I'd use an instance variable:

def valid_attributes
  @user_id ||= 0
  @user_id += 1
  { :email => "some_#{@user_id}@thing.com" }
end
喜爱纠缠 2024-12-08 05:22:45

Ruby 唯一的变量是局部变量、实例变量、类变量和全局变量。它们都不符合您所追求的。

您可能需要的是一个存储 user_id 的单例,并每次都为您提供一个新的 ID 号。否则,您的代码将不是线程安全的。

The only variables Ruby has are local variables, instance variables, class variables and global variables. None of them fit what you're after.

What you probably need is a singleton that stores the user_id, and gives you a new ID number each time. Otherwise, your code won't be thread-safe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文