Статические локальные переменные для методов в Ruby?
у меня есть это:
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?
5 ответов
этот ответ немного больше по объему, чем ваш вопрос, но я думаю, что он попадает в корень того, что вы пытаетесь сделать, и будет самым простым и наиболее доступным.
Я думаю, что вы действительно ищете здесь заводы. Попробуйте использовать что-то вроде 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
для создания сохраненных и несохраненных экземпляров модели.
есть объяснение гораздо больше возможностей в начало документа, а также инструкции по добавлению фабрик в ваш проект.
это дело о закрытии. Попробуйте это
lambda { user_id = 0 self.class.send(:define_method, :valid_attributes) do user_id += 1 { :email => "some_#{user_id}@thing.com" } end }.call
обертывание всего в лямбда позволяет переменным, определенным в лямбда, существовать только в области. Можно добавить и другие методы. Удачи!
Вы можете использовать замыкание:
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
не будет доступен снаружи.
Я бы использовал переменную экземпляра:
def valid_attributes
@user_id ||= 0
@user_id += 1
{ :email => "some_#{@user_id}@thing.com" }
end
единственными переменными Ruby являются локальные переменные, переменные экземпляра, переменные класса и глобальные переменные. Ни один из них не подходит для того, что ты ищешь.
вам, вероятно, нужен синглтон, который хранит user_id и каждый раз дает вам новый идентификационный номер. В противном случае, ваш код не будет потокобезопасным.