Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 规范不作为创建动态类的“沙盒”运行_Ruby_Rspec_Metaprogramming_Ruby 2.0 - Fatal编程技术网

Ruby 规范不作为创建动态类的“沙盒”运行

Ruby 规范不作为创建动态类的“沙盒”运行,ruby,rspec,metaprogramming,ruby-2.0,Ruby,Rspec,Metaprogramming,Ruby 2.0,我有一个带有define方法的模块,它动态创建一个类,如下所示: require "active_support/all" class SomeBaseClass # code end module MyModule def self.define(_class_name) class_name = _class_name.classify Object.const_set(class_name, Class.new(SomeBaseClass)) end end

我有一个带有define方法的模块,它动态创建一个类,如下所示:

require "active_support/all"

class SomeBaseClass
  # code
end

module MyModule
  def self.define(_class_name)
    class_name = _class_name.classify
    Object.const_set(class_name, Class.new(SomeBaseClass))
  end
end
然后,如果我这样做:MyModule.define:myu类,我将得到:MyClass

我的规格:

describe "#define" do
  it "creates a dynamic class" do
    MyModule.define("my_class")
    expect(subject.const_defined?("MyClass")).to be_truthy
  end
end
这个很好用。。。但是当我创建一个定义MyClass的新规范时,我得到以下警告:警告:已初始化常量MyClass

发生这种情况是因为我在以前的规范中创建了MyClass。所以,问题是:如何避免这种情况?我希望每个规格都有一个新的开始

更新:基于@giglemad答案的解决方案


您可以根据名称+某种约定每次定义不同的类名。我使用时间戳这样做

def nano_timestamp_string
  Time.now.to_f.to_s.sub('.','')
end
当您需要一些独特的东西,但仍然希望以相同的方式编写测试时,您几乎可以重用该约定。例如,我用它来发送独特的电子邮件。如果您仍然要定义一个同名的常量,然后再定义它,那么您可能需要使用

Object.send(:remove_const,:Myconst)

rspec有stub_const,它允许您定义类之类的常量,并在测试后自动清理它们。我认为选项2更干净。
Object.send(:remove_const,:Myconst)