Ruby on Rails中YAML

YAML

YAML Ain't Markup Language。

YAML是一个类似GNU的递归式定义。GNU对Unix说“No”,YMAL则是对XML说“No”。而在Ruby的世界里,YAML可以说是Ruby流动的血液。YAML 之于Ruby,犹如XML之于Java。

为什么要向XML说“No”呢?因为:

* YAML的可读性好。
* YAML和脚本语言的交互性好。
* YAML使用宿主语言的数据类型。
* YAML有一个一致的信息模型。
* YAML易于实现。

上面5条也就是XML不足的地方。同时,YAML也有XML的下列优点:

* YAML可以基于流来处理;
* YAML表达能力强,扩展性好。

总之,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。

YAML示例

首先用一个在Rails开发中一定会遇到的YAML文件——database.yml——作为示例。在你创建一个Rails工程后,Rails会自动给你创建一个这样的文件,它的路径是config/database.yml:

# MySQL (default setup). Versions 4.1 and 5.0 are recommended.
# 此处省略一些注释。
development:
adapter: mysql
database: demo_development
username: root
password:
host: localhost

# Warning: The database defined as 'test' will be erased and
# re-generated from your development database when you run 'rake'.
# Do not set this db to the same as development or production.
test:
adapter: mysql
database: demo_test
username: root
password:
host: localhost

production:
adapter: mysql
database: demo_production
username: root
password:
host: localhost


似乎很直观,对么?除去注释,会发现有三个组,分别用development、test和production标识。这三个组每个又有adapter、database、username、password和host这些属性。作为一个聪明的程序员,你一定已经意识到空格在这里发挥了作用!

完全正确!空格(注意:Tab不是)在YAML中用来表示代码的结构。上面的YAML文件可以被解析为一个哈希对象,它有三个元素,当然,每个元素又是一个哈希对象,下面是使用YAML::load(File.read(“database.yml”)) 方法获得的对象描述(为了保护视力和大脑,我进行了一些排版):

{
'development'=> {'adapter' => 'mysql', 'database' => 'demo_development',
‘username’ => 'root', ‘password’ => nil, ‘host’ => 'localhost'},
‘test’=> {‘adapter’ => 'mysql', ‘database’ => 'demo_test',
‘username’ => 'root', ‘password’ => nil, ‘host’ => 'localhost'},
‘production’=> {‘adapter’ => 'mysql', ‘database’ => 'demo_production',
‘username’ => 'root', ‘password’ => nil, ‘host’ => 'localhost'}
}

有了这个,你几乎就已经明白了所有在Rails中能遇到的YAML文件了,Rails中用到的YAML文件几乎永远是这种格式。例如,Rails为每个模型都会生成一个供单元测试使用的夹具(Fixture)文件,也是使用这种格式。

不过,Rails还加入了另外的灵活性。在这些属性中还可以使用Ruby代码!当然,对于数据库配置来说,这似乎用处不大,但是对于单元测试,有时你可能希望某个日期属性是当前测试的日期,那么这个功能就特别有用了。

Rails是怎样做到这个的,其实很简单。它在调用YAML::load方法之前先进行了ERB的解析,把Ruby代码执行后的结果再交给YAML进行加载,就可以得到这个小魔术了。下面是Rails加载数据库配置文件的代码:

YAML::load(ERB.new(IO.read(database_configuration_file)).result)

尽管Rails一般总是这样使用YAML,YAML实际上还有其他的一些用法,我们将在下面进行一些介绍。

YAML语言元素

下面对YAML的语言元素做一个简要介绍:

1. 列表(List)

表示一个列表很简单,在每个条目前加入一个短横线。比如

- Item1
- Item2
- Item3


在Ruby中会被解释为数组对象(Array),上例为:

[“Item1”, “Item2”, “Item3”]

2. 哈希表(Hash)

我们在前面的例子中已经大量使用了哈希表对象。哈希表的键/值之间用冒号(:)进行分隔。

key1 : value1
key2 : value2
key3 : value3

在Ruby中会被解释为如下的哈希对象:

{"key1"=>"value1", "key2"=>"value2", "key3"=>"value3"}

3. 字符串和其它基本类型

YAML会自动判断类型,一般性的文字都会被解释为字符串。在有可能发生歧义的情况下,可以为字符串加上单引号或者双引号(在双引号下转义字符会被转义,转义方式与C语言类似)来避免歧义。

下面是一个例子,包含了字符串、整数、浮点数和日期类型:

1 : 1.0
1.0 : "1.0"
"1.0" : 2006-01-01

它会被解释为:

{1=>1.0, "1.0"=>#<Date: 4907473/2,0,2299161>, 1.0=>"1.0"}

可以看出它的类型被很好的识别出来。

4. 字符串块

字符串可能会占据多行,可以用两种方式来处理这种情况,一种是保留换行符,另外一种则去除换行符。

用| 表示保留换行符:

|
This is line1.
This is line2.
This is line3.

它会被解释为:

"This is line1.\nThis is line2.\nThis is line3."

用>表示删除换行符:

>
Hello,
world.

会被解释为:

"Hello, world."

以上是一些常用的基本类型,当然它们还可以组合为更复杂的结构,比如列表的内容可以是列表本身,也可以是哈希表;哈希表的内容也可以是列表或哈希表,它们可以嵌套使用,来获得非常复杂的结构。

对于重复出现的项目,可以用&进行定义,然后用*进行引用。下面用一个比较完整的例子来说明这些内容(该例子取自http://en.wikipedia.org/wiki/YAML#Sample_Document)。

logEvent: Purchase Invoice
date: 2007-08-06
customer:
given: Dorothy
family: Gale

bill-to: &id001
street: |
123 Tornado Alley
Suite 16
city: East Westville
state: KA

ship-to: *id001

items:
- part_no: A4786
descrip: Water Bucket (Filled)
price: 1.47
quantity: 4

- part_no: E1628
descrip: High Heeled "Ruby" Slippers
price: 100.27
quantity: 1

specialDelivery: >
Follow the Yellow Brick
Road to the Emerald City.
Pay no attention to the
man behind the curtain.

它表示Ruby对象如下:

{
"items"=>[
{"price"=>1.47, "quantity"=>4, "part_no"=>"A4786", "descrip"=>"Water Bucket (Filled)"},
{"price"=>100.27, "quantity"=>1, "part_no"=>"E1628", "descrip"=>"High Heeled \"Ruby\" Slippers"}
],
"bill-to"=>{"city"=>"East Westville", "street"=>"123 Tornado Alley\nSuite 16\n", "state"=>"KA"},
"specialDelivery"=>"Follow the Yellow Brick Road to the Emerald City. Pay no attention to the man behind the curtain.",
"date"=>#<Date: 4908637/2,0,2299161>,
"ship-to"=>{"city"=>"East Westville", "street"=>"123 Tornado Alley\nSuite 16\n", "state"=>"KA"},
"customer"=>{"given"=>"Dorothy", "family"=>"Gale"},
"logEvent"=>"Purchase Invoice"
}

YAML和JSON

近来火热的JSON可以看作是(几乎是)YAML的一个子集,一般说来,YAML的解析器都可以解析JSON文档。关于JSON的说明可以参见JSON的主页(http://json.org/),这里甚至还提供了一个中文版本的文档(http://json.org/json-zh.html)。

YAML资源

· YAML主页:http://www.yaml.org/

· YAML维基百科:http://en.wikipedia.org/wiki/YAML

· Developerworks上的YAML简介:http://www.ibm.com/developerworks/cn/xml/x-cn-yamlintro/index.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值