• 2008-11-17

    退一步,海阔天空

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/31481796.html

    我正在写的一个库,摆在我面前的是这样一段代码:

    class CONSTANT_Utf8 < MyModule::String
      size :type => :u2
     
      define_type :constant_utf8
    end

    这里定义了一个类型,它定义了字符串类型,size的类型是u2,类型的名字叫constant_utf8。我翻遍了所有的代码,这个类型的名字(CONSTANT_Utf8)除了定义这里,根本没有人会用到。没有用的东西是否还有存在的价值,这是我面对它思考的问题,尽管这是我想当初费劲心力想出的名字。经过一番痛苦的思索,我打算把这段代码改成这样:

    MyModule.Type.string(:constant_utf8, :size => {:type => :u2})

    如此一来,那个完全没有必要存在的类名字便也烟消云散了。想清楚之后写代码还是容易的。

    module MyModule
      class << Type
        ...

        def string(name, options)
          type(name, MyModule::String, options)
        end

        def type(name, super_type, options)
          klass = Class.new(super_type)
          options.each {|key, value| klass.send(key, *value) }
          define_type(name, klass)
        end
      end
    end

    于是,我兴致高昂把后面类似的代码用同样方法处理。突然,一个测试失败了,真正的问题在这段代码:

    MyModule::Type.struct(:constant_long, :u4 => :high_bytes, :u4 => :low_bytes)

    经过分析,让这段代码失败的理由是,后面两项居然都用:u4做键值,于是原本是两项,传进hash之后,就只有一项了。于是,我的思路开始发散,加上括号,改hash为array……

    结论是,没有哪个让我满意,不是实现不了,而是着实没有美感可言。不知道大脑中的哪个弦跳动了一下,既然在这个思路下,问题没法解决,我不妨换一个方式,于是,代码被改成了这样:

    MyModule::Type.struct(:constant_long) do
      u4 :high_bytes
      u4 :low_bytes
    end

    如此一来,hash可能带来的冲突便不再存在了,而且,这和最初的用类定义形式上也更加接近,还有,这里也不用再为symbol点那个冒号了。当然实现也是要相应调整。

    module MyModule
      class << Type
        ...

        def string(name, &block)
          type(name, MyModule::String, &block)
        end

        def type(name, super_type, &block)
          klass = Class.new(super_type)
          klass.instance_eval(&block) if block_given?
          define_type(name, klass)
        end
      end
    end

    前两天和胡凯聊天,我们发现公司里有一些更资深的技术人员,他们解决问题并不是通过操起兵器直接上阵,而是通过分析,提出另一种解决方案,从而原本的那个问题也就不是问题了。这里,我跳了两次,躲过命名和hash的烦恼。

    分享到:
    引用地址:

    评论

  • http://www.javaeye.com/topic/161468

    这个是我的一篇帖子,总觉得我们好像在干同样的事情。
    回复庄表伟说:
    http://code.google.com/p/rojam/

    没错,差不多!
    2008-11-18 22:43:03