| 導購 | 订阅 | 在线投稿
分享
 
 
 

功能丰富的Perl:用Perl保存

2008-05-19 06:25:45  編輯來源:互聯網  简体版  手機版  評論  字體: ||
 
 
  数据存储是计算机编程中常见的问题。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

  
 
 
 
  数据存储是计算机编程中常见的问题。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   
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
王朝网络微信公众号
微信扫码关注本站公众号 wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味著赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有