-------------2008年6月14日 ruby 做着玩(1)


  这些天总是想要用ruby做点什么,因为喜欢ruby,也因为最近技术上缺少变化,想要主动的搞点不同的东西。想了不少的东西,但是很显然现在很忙,白天也不会有时间,只有晚上做,因此不能太大了,完整的系统就不要想了,但是找些耦合性不大的,有点意思的模块还是没有问题的,不如就做一个编号生成模块吧。
  今天周六,在床上睡得七荤八素的,想到左右没有事情,或者想到些事情也不想动,不如写写这个模块,动手。
  先看看需求
  A. Feat:做一个编号生成模块
  1. 通过类似${yyyy}-${mm}-${dd}-string-${autonum}样式来生成编码,这样生成的编号在今天就是2008-06-14-string-1,依次递增。
  2. 可以配置上面的格式化字符串
  3. 可以生成一个新的编号,并且不会重复,前面字符串变化后,后面的autonum可以归零再来。

  B. 技术限定:用函数,不要动不动就是数据库,想都不能想;总在做数据库,早就烦了,这次至少要改变些什么,要不然太没有意思了。

  C. 我要做的就是这个函数
   function GenenateSerialNo(serial_format,last_serial_no,last_num)
     当然需要通过下面的测试。实际上有了测试,这个函数才完整。
  D. testcase :
    assert_equal("2008-6-14-string-1",GenenateSerialNo("${yyyy}-${mm}-${dd}-string-${autonum}","",0))
    assert_equal("2008-6-14-string-4",GenenateSerialNo("${yyyy}-${mm}-${dd}-string-${autonum}","2008-6-14-string-3",3))
    assert_equal("2008-6-14-string-9",GenenateSerialNo("${yyyy}-${mm}-${dd}-string-${autonum}","2008-6-14-string-8",8))
      assert_equal("2008-6-14-string-1",GenenateSerialNo("${yyyy}-${mm}-${dd}-string-${autonum}","2008-6-13-string-8",8))

  如果用数据库的思路,现要考虑数据库表如何规划,上一个num和上一个格式化字符串的位置,还有这3张表的关系,耦合大了去了,又如何去重用呢?

  E. Testcase换成Ruby的表达,更详细的设计

  可是我不知道在ruby中如何表达单元测试?
  google "ruby unit test"
  找到一个例子:
  少许调整,改成自己想要的东西。然后....ruby serail_test
  架子成了,休息下,听音乐,音乐好啊。

  F. 开始写代码 - 表意代码,但是必须替换为ruby的样子,ruby估计不会有什么now.month,也不会有replace的方法。
    def GenenateSerialNo(serial_format,last_serial_no,last_num)
     serial_format.replace("${yyyy}",now.year);
     serial_format.replace("${mm}",now.month);
     serial_format.replace("${dd}",now.day);
     temp = serail.replace("${autonum},last_num")
     if (temp == last_serial_no)
         serial_format.replace("${autonum}",last_num+1);
     else
         serial_format.replace("${autonum}",1);
     serial_format
    end
        这些代码只能算是伪代码,表达意思没有问题,但是ruby显然不是这样表达的,其中的日期函数肯定不是这样的,replace函数恐怕也没有,就算有,恐怕也不能用一个数字来替换,比如last_num,必须转成string才可以。
  G. 如何表达string.replace ? 继续google "ruby string replace ",知道gsub可以干这个事情
     用irb验证
     "abc".gsub("ab","c)
     ==> cc
     就是它。
  H. 那么now.year 呢? google :"ruby date year",每个语言对日期的处理都不一样,不过也没有必要说那么多,都是知识性的,总之找到,然后用irb来测试。
      irb(main):011:0> Time.now.day
    => 14
    irb(main):012:0> Time.now.year
    => 2008
    irb(main):013:0> Time.now.month
    => 6
    irb(main):015:0> Time.now.month.to_s()
    => "6"
    irb(main):016:0> Time.now.month.to_s
    => "6"
      这样基本库函数的就比较明确了,正式编码了。
   J. 废话少说,看代码,然后通过第一个测试,随后以及也就通过了,懒得在看了。
       def GenenateSerialNo(serial_format,last_serial_no,last_num)
     serial = serial_format
     serial = serial.gsub("${yyyy}",Time.now.year.to_s)
     serial = serial.gsub("${mm}",Time.now.month.to_s)
     serial = serial.gsub("${dd}",Time.now.day.to_s)
     temp = serial.gsub("${autonum}",last_num.to_s)
     if (temp == last_serial_no)
         serial = serial.gsub("${autonum}",(last_num+1).to_s);
     else
         serial = serial.gsub("${autonum}",1.to_s);
     serial
     end
    end
   K. 总结
   一开始通过测试驱动的方式来,更加容易集中于代码,而不是考虑数据库如何,表如何.
   因为和数据库,表没有关系,更加容易重用。
   因为和数据库没有关系,也就有了新意,好玩,并且代码也就不多。
   不要着急进入代码细节,先表意,然后用ruby翻译,当然如果ruby比较熟悉了,可以一步到位,而我现在不熟悉,就干脆从顶到下,思路更加清晰。人的头脑不适合在层次中切换,如果先考虑好上一层,然后在进入下一层,当然更加容易。
   irb可以交互执行,看库函数,或者快速看结果更合适,不像ruby.exe 那么死板。可以在刚刚提到的场合多用,这个工具更加容易看到脚本比编译的灵活快速的特点。

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭