功能豐富的Perl:用Perl保存

數據存儲是計算機編程中常見的問題。CPAN Persistent 類通過一個簡化數據創建、檢索和管理的通用接口,使數據存儲變得簡單。通過面向對象的方法,可以在項目中將 Persistent 類作爲自己的數據類的父類透明地使用。

持久性介紹

所有程序員都有必須解決數據持久性問題的經曆。例如,對于如將文檔存入文件和將事務存入數據庫等任務,即使最簡單的應用程序也需要大量工作。可以將數據持久性定義爲程序和存儲設備之間達成的契約,該契約指定如何存儲和檢索數據。

CPAN 定義:

“CPAN 是綜合 Perl 檔案網絡。綜合:其目的是包含可能需要的所有 Perl 資料。檔案:從 1999 年 9 月至今,已有 760 兆字節。網絡:全世界有超過一百個 CPAN 鏡像站點。”

本文集中講述在作者和讀者事先都知道對象屬性的情況下,如何使對象屬性持久。本文不討論動態發現對象屬性和存儲屬性以外的特性(如行爲)的主題,因爲需要很多篇幅才能把這些主題講清楚。

熟悉面向對象編程、數據庫、Perl 和 Perl 繼承將對閱讀本文有幫助。

使對象屬性持久只是軟件開發過程的一小部分。首先,必須確定持久性的需求。需要保存什麽?需要恢複什麽?在恢複存儲的數據之前,需要手工編輯嗎?諸如此類的問題將確定軟件如何將持久數據歸檔。不幸地是,沒有一份調查表可以確定項目確切的持久性需要。軟件設計師必須通過智能設計,定義並滿足項目需求。很重要的一點是,最後的解決方案要確實是問題的解決方案,而不只是時髦的行業詞語。例如,XML 解決數據持久性問題的能力比只用磚頭來建造房屋好不到哪裏。

持久數據示例

Perl 文件 simple 顯示了預定義的關鍵字集合如何能夠實現簡單的持久性。這種方法有很多問題:文件格式是任意的,只保存一個關鍵字集合,根本沒有對象、數據值限制到一行文本等等。

Persistent 類的簡單使用:Persistent::File

Persistent 類旨在使數據持久性變得簡單。爲此,您必須閱讀文檔。對于掌握處理持久數據的方便的預制類而言,這只是很小的代價。所以,先花上幾分鍾或幾小時來做這件事,以後將節省您的時間。有關文檔和示例,請參閱 Persistent 類主頁(請參閱參考資料)。

第一個示例 first 將基于 Persistent::File 模塊文檔中給出的 simple 示例,並將描述達到持久性的步驟。

清單 1:定義數據

my %problems = (

'Homework 1, Problem 1' = [0,5,2],

'Homework 1, Problem 2' = [1,8,5],

'Homework 1, Problem 3' = [2,2,4],

'Homework 1, Problem 4' = [3,0,3],

'Homework 1, Problem 5' = [4,1,2],

);

首先,定義要存儲在數據存儲器中的數據。在 Persistent 類中,數據存儲器是抽象存儲設備,例如,它可以是文件或數據庫。該例是自包容的,但是數據也可能來自別處。

清單 2:使用 eval 來捕獲錯誤

use English;

eval

{

};

print "An error occurred: $EVAL_ERROR\n" if $EVAL_ERROR;

因爲不希望程序在出現執行錯誤時終止,所以將所有操作放在 eval 語句中。English 模塊使我們可以使用 $EVAL_ERROR 、而不是 $@ 來表示錯誤消息。

清單 3:定義數據存儲器

# 從文件創建持久對象

my $equation = new Persistent::File('variables.txt');

我們在這裏創建了新的 Persistent::File 對象,其內容將存儲在文件 variables.txt 中。

清單 4:定義屬性

$equation-add_attribute('name', 'ID', 'VarChar', undef, 80);

$equation-add_attribute('x', 'Persistent', 'Number', 0, 10);

$equation-add_attribute('y', 'Persistent', 'Number', 0, 10);

$equation-add_attribute('z', 'Persistent', 'Number', 0, 10);

$equation-add_attribute('answer', 'Transient', 'Number', undef, 10);

我們創建了五個屬性:一個唯一標識、三個持久數據成員和一個非持久(暫時)數據成員。Persistent 類將自動創建必要的函數(例如,$equation-answer())來訪問數據成員。

清單 5:清除數據存儲器

$equation-restore_all();

$equation-delete while $equation-restore_next();

restore_all 方法檢索整個數據存儲器的內容。restore_where 和 restore 方法分別用來選擇符合某些標准的對象和單一對象。delete 方法除去當前等式,restore_next 方法移至下一個恢複的對象。

清單 6:存儲對象數據

# 現在將問題存儲到數據存儲器

foreach my $key (keys %problems)

{

$equation-clear;

$equation-name($key);

$equation-x($problems{$key}-[0]);

$equation-y($problems{$key}-[1]);

$equation-z($problems{$key}-[2]);

$equation-save;

}

我們清除舊屬性,設置新屬性,並將對象存儲到數據存儲器。因爲剛剛清除過數據存儲器,所以我們知道,不會有 name 鍵沖突,但是,通常要進行檢查,以便在用 save 方法試圖重寫現有鍵時不會導致異常。

清單 7:檢索 homework 1 等式

# 在數據存儲器中查詢 homework 1 中的等式

$equation-restore_where(qq{name =~ 'Homework 1'});

while ($equation-restore_next())

{

# do something with each equation

}

最後,遍曆數據存儲器,查找那些 name 鍵包含字符串 'Homework 1' 的對象,然後對這些對象中的每一個執行操作。

這個例子本身並不使人難忘,但是,請考慮:

現在可以將任何數量的屬性添加到持久對象

可以有選擇地檢索任何存儲的對象

任何知道對象屬性的其它程序都可以使用同樣的數據存儲器(這方面的詳細信息在“從 Persistent 類繼承”中)。

通過使用預制的模塊,我們已經用簡單的方法解決了棘手的問題。這很有趣。

使用 Persistent::DBI

請閱讀 Persistent::DBI 文檔,來獲得有關 Persistent::DBI 和 Persistent::Base 類之間區別的最新討論。基本上,Persistent::DBI 允許我們連接到數據庫,並在建立連接之後,象其它 Persistent::Base 類那樣操作。可以將清單 3 中顯示的代碼行用以下替代:

清單 8:定義要作爲數據庫的數據存儲器

my $database = 'test_database';

my $host

= 'db_host';

my $user

= 'dali';

my $password = 'MeltingClocks';

my $table

= 'persistence_test_table';

my $equation = new Persistent::MySQL(

"DBI:mysql:database=$database;host=$hostname",

$user,

$password,

$table);

請注意,Persistent::MySQL 是 Persistent::DBI 的子類。只使用 Persistent::DBI 本身沒什麽用,必須使用特定于我們數據庫的模塊。令人欣慰的是,除了通過名稱來引用 Persistent::MySQL 之外(例如 use 語句和 new 語句),在切換數據庫時不需要更改代碼。有關通過使用繼承來將程序與數據庫選項隔離的方法,請參閱“從 Persistent 類繼承”。

清單 9:不同的查詢語法

# 在數據存儲器中查詢 homework 1 中的等式

$equation-restore_where(qq{name LIKE '%Homework 1%'});

因爲現在使用的是 SQL SELECT 語句,所以 restore_where 自變量從 Perl 模式匹配改成 SQL WHERE 子句。

表必須事先存在,Persistent::MySQL 將不創建表。編寫一個單獨的程序來創建表,或者繼承時在類中添加必需的功能。

表必需與屬性定義匹配,例如,等式表的主數據庫鍵必須也是 Persistent 類的主鍵。(這是在實現工作之前必須有良好設計的情況。)

清單 8 和清單 9 只顯示了爲使用 SQL 而必須在 first 中做的更改。腳本 second 包含這些更改。

從 Persistent 類繼承

文件 Equation.pm 包含從 Persistent::DBI 類繼承所需的所有代碼。很簡單,不是嗎?基本上,在本地 initialize 方法中執行 add_attribute 調用。在這裏還可以做更多操作:例如,如果數據庫中不存在表,則創建表。但是,基本方法很簡單。

安全性注意事項:

通常,只有數據庫中的特權用戶才能創建表,所以最好與數據庫管理員討論表的創建,以確保不會因爲安全性策略而導致您辛苦創建的表無法工作。

清單 10:Equation.pm 模塊,擴展 Persistent::MySQL

#! /usr/bin/perl -w

package Equation;

@ISA = qw(Persistent::MySQL);

use strict;

use Persistent::MySQL;

sub initialize

{

my $self = shift;

$self-SUPER::initialize(@_);

# define attributes of the object (the contract)

# this is the primary object identifier key, a 10-character name

$self-add_attribute('name', 'ID', 'VarChar', undef, 80);

# x, y, and z are persistent numbers with default values of 0 and length of 10

功能豐富的Perl:遺傳算法仿真多細胞機體
  我的前兩篇關于使用 Perl 實現遺傳算法(GA)的文章(參閱 參考資料)講述的是個體細胞的變異與生命周期,它的適合度(fitness)完全依賴于它們自己的 DNA。本文將介紹如何仿真一個多細胞機體。具體的應用程序將...查看完整版>>功能豐富的Perl:遺傳算法仿真多細胞機體
 
功能豐富的Perl:遺傳算法仿真多細胞機體
  我的前兩篇關于使用 Perl 實現遺傳算法(GA)的文章(參閱 參考資料)講述的是個體細胞的變異與生命周期,它的適合度(fitness)完全依賴于它們自己的 DNA。本文將介紹如何仿真一個多細胞機體。具體的應用程序將...查看完整版>>功能豐富的Perl:遺傳算法仿真多細胞機體
 
功能豐富的Perl:Perl自動化系統管理
  UNIX 系統管理總是一個棘手的問題,運用正確的工具會使這個問題變得容易。在這一部分中,Teodor 提出了關于使用 Perl 來簡化和牢固系統管理的想法。在這種環境中,系統配置引擎 cfengine 是一個極其重要的工具。...查看完整版>>功能豐富的Perl:Perl自動化系統管理
 
功能豐富的Perl:JustAnotherPerlHacker
  JAPH:“Just another Perl hacker”  據我們所知,JAPH 格式是在二十世紀九十年代由 Randal Schwartz 推廣的(好幾處信息來源都同意這個說法)。今天,JAPH 到處可見,它們是由該流派的那些不知疲倦的藝術家們...查看完整版>>功能豐富的Perl:JustAnotherPerlHacker
 
功能豐富的Perl:用Perl讀寫Excel文件
  Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel  在 2000 年,Takanori Kawai 和 John McNamara 編寫出了 Spreadsheet::WriteExcel 和 Spreadsheet::ParseExcel 模塊並將它們張貼在 CPAN 上,這兩個模塊...查看完整版>>功能豐富的Perl:用Perl讀寫Excel文件
 
功能豐富的Perl:編寫說英語的Perl程序
  設計程序的用戶界面可能很困難而且耗時。Teodor Zlatanov 討論了如何使用 Parse::RecDescent 模塊來用簡單的英語創建用戶界面文法。他還展示了向程序添加功能或從程序除去功能時,更改文法是如何的方便。另外還與...查看完整版>>功能豐富的Perl:編寫說英語的Perl程序
 
功能豐富的Perl:輕松調試Perl的技巧
  錯誤所帶來的麻煩  軟件開發人員通常都低估了軟件測試的重要性。這一現象的根本原因很簡單:處理錯誤很困難!因爲錯誤往往暴露了代碼的根本缺陷,所以有時候開發人員甚至會爲了幾個錯誤而從頭開始重新編寫項目...查看完整版>>功能豐富的Perl:輕松調試Perl的技巧
 
功能豐富的Perl:Perl用于實現遺傳算法
  如果您的機器上已經安裝了 Perl 5.005 或者更高的版本,您可以運行一下文章中的例子。您的系統最好應該是安裝了最近的(2000 年或者更遲些)主流的 UNIX(Linux,Solaris,BSD),但其它種類的操作系統可能也可以...查看完整版>>功能豐富的Perl:Perl用于實現遺傳算法
 
功能豐富的Perl:用于系統管理
  cfengine(配置引擎)是一種 UNIX 管理工具,其目的是使簡單的管理的任務自動化,使困難的任務變得較容易。它的目標是使系統從任何狀態收斂(convergence)到一種理想狀態。依照它的作者 Mark Burgess 所說,cfe...查看完整版>>功能豐富的Perl:用于系統管理
 
 
回到王朝網路移動版首頁