尝试检查字符串值类型时出现奇怪的结果

时间:2014-03-05 11:30:16

标签: ruby rspec metaprogramming

我有一个类来封装mime类型,用于与外部系统通信。 这是该课程中与该问题相关的部分。

module Types
   class MetaType
      def self.validator(&block)
         define_singleton_method :is_valid?, &block
      end
   end

   class Float < MetaType
      validator { |v| v.is_a? Numeric }
   end

   class String < MetaType
      validator { |v| v.is_a? String }
   end


   Map = { :Time => Float, :Float => Float , :String => String }

   def self.get_type(name)
      name = name.intern

      raise ArgumentError, "Unknown type #{name}" unless Map.has_key? name
      return Map[name]
   end
end

这是规范

describe Types do
   context "When calling get_type with 'Float'" do
      subject { Types.get_type('Float') }
      it "should validate a float" do
         expect(subject.is_valid? 3.5).to be_true
      end
   end
   context "When calling get_type with 'String'" do
      subject { Types.get_type('String') }
      it "should validate a string" do
         expect(subject.is_valid? "tmp").to be_true
      end
   end
end

规范的输出

Types
  When calling get_type with 'Float'
    should validate a float
  When calling get_type with 'String'
    should validate a string (FAILED - 1)

Failures:

  1) Types When calling get_type with 'String' should validate a string
     Failure/Error: expect(subject.is_valid? "tmp").to be_true
       expected: true value
            got: false
     # ./tmp/type_error.rb:37:in `block (3 levels) in <top (required)>'

代码不传递字符串。
我已经在元类的验证器函数中尝试puts val.is_a? String,但确实打印错了?
当我尝试puts "tmp".is_a? String时,我确实是我所期待的......

代码使用int,float,bool,hash,但我无法使用String,我没有看到任何错误。
我不能解决这个问题,任何帮助将不胜感激。
谢谢

1 个答案:

答案 0 :(得分:3)

我认为这里有一个名字冲突。

validator { |v| v.is_a? String }

在这种情况下String不是您认为的那样。它是Types::MetaType::String。当然,价值"tmp"不属于这种类型。您想要引用顶级核心类String,如下所示:

class String < MetaType
  validator { |v| v.is_a? ::String }
end