浏览 594 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2008-04-23
隐约记得以前用Java序列化一个对象是多么的繁琐,以至于我不想回忆。。。。
今天在翻看FXRuby的时候,看到其中一个例子利用YAML对应用程序需要持久化保存的对象进行了序列化,以便能够让应用程序记住当前的配置信息。之前对 YAML的了解不多,只是听说过Ruby有专门的库对其支持,以及YAML适合轻量级对象序列化存储等介绍。为进一步了解,遂写了一段简单的测试性代码,瞬间就被Ruby+YAML的简便快捷性所震撼。 例如我们在ruby中简单的创建一个Person类,保存人的相关信息,我们创建了Person类的两个具体实例对象,出于某种需求,我们要长久保存这两个(或更多)对象,但又不想应用数据库这样过分重量级的技术,我们就应该使用YAML了。 为什么使用YAML,以及YAML是什么?可以参看我从IBM摘过来的一段简介: YAML Ain't Markup Language 和GNU一样,YAML是一个递归着说“不”的名字。不同的是,GNU对UNIX说不,YAML说不的对象是XML。 YAML不是XML。 YAML LOGO 为什么不是XML呢?因为: * YAML的可读性好。 * YAML和脚本语言的交互性好。 * YAML使用实现语言的数据类型。 * YAML有一个一致的信息模型。 * YAML易于实现。 上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点: * YAML可以基于流来处理; * YAML表达能力强,扩展性好。 总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。 好吧,还是让我们来看一下我们的测试代码: 代码如下: class Person attr_accessor :name,:age,:email def initialize(name,age,email) @name = name @age = age @email = email end end anth = Person.new("Anthrax",29,"anthraxcn@tom.com") haha = Person.new("haha",28,"haha@tom.com") person_list = [] person_list << anth << haha File.open("person.yaml","w") do|io| YAML.dump(person_list,io) end YAML.load_file("person.yaml").each do|p| puts p.name puts p.age puts p.email puts p.class puts "===================" end 上面的代码中,我们首先创建了一个类,然后实例化了这个类的两个对象,保存有具体的两个人的信息,然后我们把这两个人压入了一个数组,我们需要持久化保存着两个兑现,于是我们借助了YAML的dump方法把对象数组持久化了.dump方法接收两个参数,参数1是一个要保存的对象,通常我们可以传递给他一个对象数组,一遍一次性的持久化n个对象。参数2是一个输入输出流,方便我们将对象数据写入到要保存的YAML文件中。 我们来看一下YAML在person.yaml中保存的数据: --- - !ruby/object:Person age: 29 email: anthraxcn@tom.com name: Anthrax - !ruby/object:Person age: 28 email: haha@tom.com name: haha 代码的后半部分利用YAML库的load_file方法读出了保存在person.yaml文件中的对象信息,并给我们返回了一个对象数组,我们的代码测试的数组中每个对象的类型,Person!看到了把。 上述程序运行结果: Anthrax 29 anthraxcn@tom.com Person =================== haha 28 haha@tom.com Person =================== 序列化一组对象在Ruby语言中,借助YAML的良好支撑,就变得如此简单。 原文出处:anthraxcn.blog.163.com 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2008-04-23
ruby core library在序列化BigDecimal对象时有个bug,当运行:
YAML::load( BigDecimal.new('1.1').to_yaml )
会抛出异常: TypeError: BigDecimal can't be coerced into BigDecimal
from c:/ruby/lib/ruby/1.8/irb.rb:298:in `inspect'
from c:/ruby/lib/ruby/1.8/irb.rb:298:in `output_value'
from c:/ruby/lib/ruby/1.8/irb.rb:151:in `eval_input'
from c:/ruby/lib/ruby/1.8/irb.rb:259:in `signal_status'
from c:/ruby/lib/ruby/1.8/irb.rb:147:in `eval_input'
from c:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:244:in `each_top_level_statement'
from c:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:in `loop'
from c:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:230:in `each_top_level_statement'
from c:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:in `catch'
from c:/ruby/lib/ruby/1.8/irb/ruby-lex.rb:229:in `each_top_level_statement'
from c:/ruby/lib/ruby/1.8/irb.rb:146:in `eval_input'
from c:/ruby/lib/ruby/1.8/irb.rb:70:in `start'
from c:/ruby/lib/ruby/1.8/irb.rb:69:in `catch'
from c:/ruby/lib/ruby/1.8/irb.rb:69:in `start'
from c:/ruby/bin/irb.bat:15
Maybe IRB bug!!
原因是序列化生成的串是坏的,才导致在load时出错:
irb(main):016:0> BigDecimal.new('1.1').to_yaml
=> "--- !ruby/object:BigDecimal {}\n\n"
生成的串居然连数值信息都可耻的丢掉了。 对于rails应用,装个名为yaml_big_decimal_fix的plugin,让它定制序列化和反序列化行为(代码就几行,所以对于普通ruby程序拿去用也没问题)。加载这个plugin后的运行结果:
>> BigDecimal.new('1.1').to_yaml
=> "--- !induktiv.at,2007/BigDecimal 1.1\n"
>> YAML.load(BigDecimal.new('1.1').to_yaml)
=> #<BigDecimal:7786084,'0.11E1',8(8)>
参考: http://blog.chrispcritter.com/articles/2007/02/11/bigdecimal-and-yaml-dont-get-along http://code.whytheluckystiff.net/syck/ticket/24 |
|
| 返回顶楼 | |
|
最后更新时间:2008-04-24
测试了下:
require 'bigdecimal'
num = BigDecimal.new("1.1")
str = "hello"
int_num = 1234
contrainer = []
contrainer << num << str <<int_num
File.open("big_num.yaml","w") do|io|
YAML.dump(contrainer,io)
end
确实有问题,生成的yaml文件中只有BigDecimal对象保存的值是空的,下面是生成的yaml文件中的内容: --- - !ruby/object:BigDecimal {} - hello - 1234 |
|
| 返回顶楼 | |




