首页 分类 关于我
ruby
Nginx 配置示例 工程师的产品观 理理File/Dir/Pathname(一) TracePoint介绍 ruby中的return 如何动态改变某个class的祖先链 ObjectSpace介绍 Rails日志实现探索(3) Rails日志实现探索(2) Rails日志实现探索(1) Rails中的request rescue exception in ruby 设计模式之观察者模式 require 的故事 ruby中的编码 研究ruby的一些小技巧 Rails中间件 ruby对象的序列化 ActiveSupport宝藏之MessageVerifier 如何写rakefile Ruby on Rails 环境及准备 基于Rack的项目初始化
git
如何移除某次提交之前的版本历史 Git 不常用的好用的命令 Git高级技巧之忽略文件
database
Mysql数据库编码 从mongodb向mysql迁移数据
工具
搭建ipsec服务
linux
Linux 常用查看命令

ruby对象的序列化

什么是序列化对象

在ruby中,有时候需要把一个对象存储起来,比如存到数据库里。 一个ruby对象可能是各种各样的,可能是数组,也可能是一个自定义对象。

如果直接把一个对象交给数据库,数据库就会抗议:你给我的这个东西我又不认识,我可不敢保证你来取的时候,我就能原样找出来还给你。 这个时候ruby就会想办法:那我给你之前,我把这个对象包装成一个你能认出来的东西,比如字符。

这个“包装”的过程就是序列化对象的过程,当ruby从数据库里取出对象的时候,是不能直接使用的,还需要还原对象,也就是反序列化。

ruby中序列化对象的方法

Marshal

Marshal可以把对象转化成一个字节流。

# 先生成一个Array对象,包含一个Integer对象和Time对象
time = Time.at(1)
value = [1, time]  # => [1, 1970-01-01 08:00:01 +0800]
# 序列化,序列化的对象是一个String实例
serialize_value = Marshal.dump(value)  
# => "\x04\b[\ai\x06Iu:\tTime\r \x80\x11\x80\x00\x00\x10\x00\a:\voffseti\x02\x80p:\tzoneI\"\bCST\x06:\x06ET"

# 反序列化
obj = Marshal.load(serialize_value)
# => [1, 1970-01-01 08:00:01 +0800]

YAML

# 序列化,
serialize_value = YAML.dump(value)  
# => "---\n- 1\n- 1970-01-01 08:00:01.000000000 +08:00\n"

# 反序列化
obj = YAML.load(serialize_value)
# => [1, 1970-01-01 08:00:01 +0800]

JSON

# 序列化
serialize_value = JSON.dump(value)  
# => "[1,\"1970-01-01 08:00:01 +0800\"]"

# 反序列化
obj = JSON.load(serialize_value)
# => [1, "1970-01-01 08:00:01 +0800"]

obj[1].class
# => String

诶,跟想象中的有点不一样,怎么Time对象还原出来变成String对象了。 这就是不同方法序列化之后的还原能力不同了,很明显Marshal在序列化对象的时候记录了很多信息,除了少数特殊情况,Marshal能够还原出绝大部分对象。 所以尽量采用Marshal序列化对象。

© 2018 www.xinshengyin.com All rights reserved.

版权所有