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

Zeq*_*uez 6 ruby variables methods static local

我有这个:

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

对于Rspec测试吧?但我想做这样的事情:

def valid_attributes
  static user_id = 0
  user_id += 1
  { :email => "some_#{user_id}@thing.com" }
end
Run Code Online (Sandbox Code Playgroud)

我不想user_id从任何地方访问,但这种方法,这可能与Ruby有关吗?

Rub*_*tic 8

这是一个封闭案例.试试这个

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中定义的变量仅存在于范围中.您也可以添加其他方法.祝好运!


Emi*_*ily 6

这个答案的范围比你的问题要大一些,但我认为它是你想要做的事情的根源,并且将是最容易和最易维护的.

我认为你真正想要的是工厂.尝试使用像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
Run Code Online (Sandbox Code Playgroud)

然后,当您需要有效属性时,您可以使用

Factory.attributes_for(:model)
Run Code Online (Sandbox Code Playgroud)

您还可以使用Factory.createFactory.build创建模型的已保存和未保存实例.

有关入门文档中的更多功能的说明,以及有关如何向项目添加工厂的说明.


Son*_*tos 5

你可以使用一个闭包:

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"}
Run Code Online (Sandbox Code Playgroud)

这种方式user_id无法在外面访问.