3
、使用Marshal
完成有限制的"
深层拷贝"
我们提供了一个途径来处理一个有限制的深层拷贝( 它有限制,是因为它还以Marshal 为基础所以有同样内在限制) :
def deep_copy(obj)
Marshal.load(Marshal.dump(obj))
end
a = deep_copy(b)
4 、Better Object Persistence with PStore
PStore 库提供了文件为基础的Ruby 对象的永续存储。PStore 对象可以持有许多Ruby 对象层次。每个层次通过一个键有个被识别的根。开始时从磁盘文件上读取层次结束时写回文件。这儿是个例子:
require "pstore"
# save
db = PStore.new("employee.dat")
db.transaction do
db["params"] = { "name" => "Fred", "age" => 32,
"salary" => 48000 }
end
# retrieve
require "pstore"
db = PStore.new("employee.dat")
emp = nil
db.transaction {
emp = db["params"] }
典型地,我们将Pstore 对象传入到处理块内。但是,我们也可以直接使用调用者。
这个技术是事务导向的;块开始时,数据被从磁盘文件中取回并进行处理。然后,它被显式地写回到磁盘上。
require "pstore"
store = PStore.new("objects")
store.transaction do |s|
a = s["my_array"]
h = s["my_hash"]
# Imaginary code omitted, manipulating
# a, h, etc.
# Assume a variable named "condition" having
# the value 1, 2, or 3...
case condition
when 1
puts "Oops... aborting."
s.abort
# Changes will be lost.
when 2
puts "Committing and jumping out."
s.commit
# Changes will be saved.
when 3
# Do nothing...
end
puts "We finished the transaction to the end."
# Changes will be saved.
end
在一个事务内部,你也可以使用方法roots 来返回根的数组( 或root? 测试成员) 。同样,delete 方法将有效地移除一个根。这儿个例子:
store.transaction do |s|
list = s.roots
# ["my_array","my_hash"]
if s.root?("my_tree")
puts "Found my_tree."
else
puts "Didn't find # my_tree."
end
s.delete("my_hash")
list2 = s.roots
# ["my_array"]
end
5 、Using the dbm Library
dbm 库是一个简单依赖系统的,以字符为基础的哈希表的,以文件存储的机制。它存储键和关联的数据,两者必须是字符串。Ruby 的dbm 接口是被标准按装的。
要使用这个类,创建一个与文件名字关联的dbm 对象,并且你希望以字符为基础的哈希表工作。当你完成时,你应该关闭文件。这儿是个例子:
require 'dbm'
d = DBM.new("data")
d["123"] = "toodle-oo!"
puts d["123"]
# "toodle-oo!"
d.close
puts d["123"]
# RuntimeError: closed DBM file
e = DBM.open("data")
e["123"]
# "toodle-oo!"
w=e.to_hash
# { "123"=>"toodle-oo!"}
e.close
e["123"]
# RuntimeError: closed DBM file
w["123"]
# "toodle-oo!
这儿,dbm 被做为混插了Enumerable 的单独类实现的。两个类方法,new 和open ,是单态的,它的意思是任何时候,你的每个数据文件只可以有一个dbm 对象:
q=DBM.new("data.dbm")
#
f=DBM.open("data.dbm")
# Errno::EWOULDBLOCK:
#
Try again - "data.dbm"
它有34 个实例方法,很多都是别名或与Hash 方法类似。基本上,如果你能熟练地使用哈希表,你可以对一个dbm 对象应用同样的操作。
方法to_hash 将在内存中为哈希表文件制做一个拷贝,close 方法将永久地关闭与哈希表文件的连接。其余的方法和Hash 方法类似,但没有rehsh,sort,default, 和efault= 方法。to_s 方法只返回用字符串表示的对象ID 。
三、连接外部数据库
Ruby 可以连接由许多不同的人开发的,各种各样的数据库。这些范围从整体系统譬如Oracle 到对更小的MySQL 。
1 、连接到MySQL
Ruby 的MySQL 接口是最稳定的和有完整功能的数据库接口。它是扩展的,必须在Ruby 和MySQL 被安装并运行后才可安装。如果你升级Ruby ,你将需要重新安装它。它的安装很简单,使用Ruby 的make 过程。
一旦你安装了它,可以有三个步骤来使用它。首先,在你的脚本中加载它;然后连接到数据库。最后,用你的表工作。连接请求通常使用的参数主机名,用户名,口令,数据库,等等,像这儿显示的:
require 'mysql'
m = Mysql.new("localhost","ruby","secret","maillist")
r = m.query("SELECT * FROM people ORDER BY name")
r.each_hash do |f|
print "#{ f['name']}
- #{ f['email']} "
end
这儿是部分输出:
John Doe - jdoe@rubynewbie.com
Fred Smith - smithf@rubyexpert.com
Don Jackson - don@perl2.com
Jenny Williams - jwill27@miss-code.com
类方法Mysql.new 和MysqlRes.each_hash 是非常有用的,还有随同的实例方法query 。
这个模块由四个类组成: Mysql, MysqlRes, MysqlField, 和MysqlError, 分别在README 文件中描述。我们在这儿总结了一些有用的方法,但你可以实际文档中找到更多信息。
类方法Mysql.new 接受几个字符串参数,所有都被定义为nil ,并且它返回一个connection 对象。参数是host,user,passwd,db,port,sock, 和flag 。 new 的别名real_connect 和connect 。
方法create_db, select_db, 和drop_db 都接受数据库名称做为参数;它们用法显示在下面( 方法close 将关闭与服务端的连接) :
m=Mysql.new("localhost","ruby","secret")
m.create_db("rtest")
# Create a new database
m.select_db("rtest2")
# Select a different database
m.drop_db("rtest")
# Delete a database
m.close
# Close the connection
The method 方法list_dbs 将返回有效的数据库名称列表在一个数组内:
dbs = m2.list_dbs
# ["people","places","things"]
query 接受一个字符串参数并缺省地返回一个MysqlRes 对象。这依赖于query_with_result 是如何被设置的,它可以返回一个Mysql 对象。
如果事件出现错误,错误号码可由errno 取回;换句话说,error 将返回实际的错误信息。这儿是个例子:
begin
r=m.query("create table rtable
(
id int not null auto_increment,
name varchar(35) not null,
desc varchar(128) not null,
unique id(id)
)")
# exception happens...
rescue
puts m.error
# Prints: You have an error in your SQL syntax
# near 'desc varchar(128) not null ,
#
unique id(id)
# )' at line 5"
puts m.errno
# Prints 1064
# ('desc' is reserved for descending order)
end
MysqlRes 内很少被使用的方法被总结列在下面:
1.
fetch_fields 从下一行中返回MysqlField 对象的数组。
2.
fetch_row 从下一行中返回字段值的数组。
3.
fetch_hash(with_table=false) 返回包含下一行的名称和值的哈希表。
4.
num_rows 返回结果集中行数。
5.
each 按次序返回字段值数组的迭代器。
6.
each_hash(with_table=false) 按次序返回一个{fieldname => fieldvalue} 样哈希表的迭代器。( 使用x['field name'] 来获取字段值。)
这儿是MysqlField 的一些实例方法:
1.
name 返回指定字段的名字。
2.
table 返回指定字段所属表的名字。
3.
length 返回字段定义长度。
4.
max_length 从结果集中返回长度最长的字段。
5.
hash Returns a hash with a name and values for name, table, def, type, length, max_length, flags, and decimals
这儿的材料总是代替不了在线文档的。更多信息可参考MySQL Web 站点 ( www.mysql.com) 和Ruby 应用文档。
Ruby没有深层拷贝"deep copy"操作符。方法dup和clone不会总像你想像的那样工作。 对象可以包含嵌套的对象引用,它转向一个拷贝操作到Pick Up Sticks中。
我们提供了一个途径来处理一个有限制的深层拷贝( 它有限制,是因为它还以Marshal 为基础所以有同样内在限制) :
def deep_copy(obj)
Marshal.load(Marshal.dump(obj))
end
a = deep_copy(b)
4 、Better Object Persistence with PStore
PStore 库提供了文件为基础的Ruby 对象的永续存储。PStore 对象可以持有许多Ruby 对象层次。每个层次通过一个键有个被识别的根。开始时从磁盘文件上读取层次结束时写回文件。这儿是个例子:
require "pstore"
# save
db = PStore.new("employee.dat")
db.transaction do
db["params"] = { "name" => "Fred", "age" => 32,
"salary" => 48000 }
end
# retrieve
require "pstore"
db = PStore.new("employee.dat")
emp = nil
db.transaction {
emp = db["params"] }
典型地,我们将Pstore 对象传入到处理块内。但是,我们也可以直接使用调用者。
这个技术是事务导向的;块开始时,数据被从磁盘文件中取回并进行处理。然后,它被显式地写回到磁盘上。
在事务的中间,我们即可以中断也可放弃;但前者将保留我们做的修改,而后者将丢掉它们。参考Listing4.2这个更长的例子。
Listing 4.2 Using PStorerequire "pstore"
store = PStore.new("objects")
store.transaction do |s|
a = s["my_array"]
h = s["my_hash"]
# Imaginary code omitted, manipulating
# a, h, etc.
# Assume a variable named "condition" having
# the value 1, 2, or 3...
case condition
when 1
puts "Oops... aborting."
s.abort
# Changes will be lost.
when 2
puts "Committing and jumping out."
s.commit
# Changes will be saved.
when 3
# Do nothing...
end
puts "We finished the transaction to the end."
# Changes will be saved.
end
在一个事务内部,你也可以使用方法roots 来返回根的数组( 或root? 测试成员) 。同样,delete 方法将有效地移除一个根。这儿个例子:
store.transaction do |s|
list = s.roots
# ["my_array","my_hash"]
if s.root?("my_tree")
puts "Found my_tree."
else
puts "Didn't find # my_tree."
end
s.delete("my_hash")
list2 = s.roots
# ["my_array"]
end
5 、Using the dbm Library
dbm 库是一个简单依赖系统的,以字符为基础的哈希表的,以文件存储的机制。它存储键和关联的数据,两者必须是字符串。Ruby 的dbm 接口是被标准按装的。
要使用这个类,创建一个与文件名字关联的dbm 对象,并且你希望以字符为基础的哈希表工作。当你完成时,你应该关闭文件。这儿是个例子:
require 'dbm'
d = DBM.new("data")
d["123"] = "toodle-oo!"
puts d["123"]
# "toodle-oo!"
d.close
puts d["123"]
# RuntimeError: closed DBM file
e = DBM.open("data")
e["123"]
# "toodle-oo!"
w=e.to_hash
# { "123"=>"toodle-oo!"}
e.close
e["123"]
# RuntimeError: closed DBM file
w["123"]
# "toodle-oo!
这儿,dbm 被做为混插了Enumerable 的单独类实现的。两个类方法,new 和open ,是单态的,它的意思是任何时候,你的每个数据文件只可以有一个dbm 对象:
q=DBM.new("data.dbm")
#
f=DBM.open("data.dbm")
# Errno::EWOULDBLOCK:
#
Try again - "data.dbm"
它有34 个实例方法,很多都是别名或与Hash 方法类似。基本上,如果你能熟练地使用哈希表,你可以对一个dbm 对象应用同样的操作。
方法to_hash 将在内存中为哈希表文件制做一个拷贝,close 方法将永久地关闭与哈希表文件的连接。其余的方法和Hash 方法类似,但没有rehsh,sort,default, 和efault= 方法。to_s 方法只返回用字符串表示的对象ID 。
三、连接外部数据库
Ruby 可以连接由许多不同的人开发的,各种各样的数据库。这些范围从整体系统譬如Oracle 到对更小的MySQL 。
这些包的功能层会持续地被修改。请务必提到网上参考最新的信息。Ruby的应用文档(RAA)总是最好的起点。
1 、连接到MySQL
Ruby 的MySQL 接口是最稳定的和有完整功能的数据库接口。它是扩展的,必须在Ruby 和MySQL 被安装并运行后才可安装。如果你升级Ruby ,你将需要重新安装它。它的安装很简单,使用Ruby 的make 过程。
一旦你安装了它,可以有三个步骤来使用它。首先,在你的脚本中加载它;然后连接到数据库。最后,用你的表工作。连接请求通常使用的参数主机名,用户名,口令,数据库,等等,像这儿显示的:
require 'mysql'
m = Mysql.new("localhost","ruby","secret","maillist")
r = m.query("SELECT * FROM people ORDER BY name")
r.each_hash do |f|
print "#{ f['name']}
- #{ f['email']} "
end
这儿是部分输出:
John Doe - jdoe@rubynewbie.com
Fred Smith - smithf@rubyexpert.com
Don Jackson - don@perl2.com
Jenny Williams - jwill27@miss-code.com
类方法Mysql.new 和MysqlRes.each_hash 是非常有用的,还有随同的实例方法query 。
这个模块由四个类组成: Mysql, MysqlRes, MysqlField, 和MysqlError, 分别在README 文件中描述。我们在这儿总结了一些有用的方法,但你可以实际文档中找到更多信息。
类方法Mysql.new 接受几个字符串参数,所有都被定义为nil ,并且它返回一个connection 对象。参数是host,user,passwd,db,port,sock, 和flag 。 new 的别名real_connect 和connect 。
方法create_db, select_db, 和drop_db 都接受数据库名称做为参数;它们用法显示在下面( 方法close 将关闭与服务端的连接) :
m=Mysql.new("localhost","ruby","secret")
m.create_db("rtest")
# Create a new database
m.select_db("rtest2")
# Select a different database
m.drop_db("rtest")
# Delete a database
m.close
# Close the connection
The method 方法list_dbs 将返回有效的数据库名称列表在一个数组内:
dbs = m2.list_dbs
# ["people","places","things"]
query 接受一个字符串参数并缺省地返回一个MysqlRes 对象。这依赖于query_with_result 是如何被设置的,它可以返回一个Mysql 对象。
如果事件出现错误,错误号码可由errno 取回;换句话说,error 将返回实际的错误信息。这儿是个例子:
begin
r=m.query("create table rtable
(
id int not null auto_increment,
name varchar(35) not null,
desc varchar(128) not null,
unique id(id)
)")
# exception happens...
rescue
puts m.error
# Prints: You have an error in your SQL syntax
# near 'desc varchar(128) not null ,
#
unique id(id)
# )' at line 5"
puts m.errno
# Prints 1064
# ('desc' is reserved for descending order)
end
MysqlRes 内很少被使用的方法被总结列在下面:
1.
fetch_fields 从下一行中返回MysqlField 对象的数组。
2.
fetch_row 从下一行中返回字段值的数组。
3.
fetch_hash(with_table=false) 返回包含下一行的名称和值的哈希表。
4.
num_rows 返回结果集中行数。
5.
each 按次序返回字段值数组的迭代器。
6.
each_hash(with_table=false) 按次序返回一个{fieldname => fieldvalue} 样哈希表的迭代器。( 使用x['field name'] 来获取字段值。)
这儿是MysqlField 的一些实例方法:
1.
name 返回指定字段的名字。
2.
table 返回指定字段所属表的名字。
3.
length 返回字段定义长度。
4.
max_length 从结果集中返回长度最长的字段。
5.
hash Returns a hash with a name and values for name, table, def, type, length, max_length, flags, and decimals
这儿的材料总是代替不了在线文档的。更多信息可参考MySQL Web 站点 ( www.mysql.com) 和Ruby 应用文档。