在使用 GWA2Perl 开发时遇到一些破费周折才发现的 Bug或改进的功能,分析记录如下,备忘。 GWA2 是一套跨语言的网络应用软件开发框架,目前有PHP、Java和Perl版本可供下载选用,也即 GWA2PHP, GWA2Java 和 GWA2Perl。
1. 应用 Tiny::Try 的Catch模块无法执行退出循环的问题
…
use Tiny::Try
….
foreach my $i(keys %alist){
try{
# something
}
catch{
if(aCondition==1){
next; # cannot?
}
}
}
…
此处的 next 无法按预期执行. 改进的措施是,预先顶一个 $tryresult = 0; 然后在成功的时候,将 $tryresult =1; 在 try::catch 执行完毕之后再对 $tryresult 进行判断,以决定是否退出循环. 修改后的代码大致如下。
…
use Tiny::Try
….
foreach my $i(keys %alist){
my $tryresult = 1;
try{
# something
}
catch{
if(aCondition==1){
next; # cannot?
}
$tryresult = 0;
}
if($tryresult == 0){
next;
}
}
…
2. Perl方法传递参数应用传值的问题
my %alist = (‘a’=>1, ‘b’=>2);
&functionA(\%alist);
&functionA(%alist); # wrong!
&functionA($alist) # wrong!
my $blist = \%alist;
&functionA($blist);
&functionA(\%blist); # wrong!
Perl的方法参数传递问题,在此前的贴文中进行过相应的讨论,如 -R/H2SP 和 -R/32SJ , 这次重新再三的提及,主要还是由于在Perl的参数传递过程中,极易发生误解,对Perl依靠形式来获取数据类型的做法认识的不够深刻。如给定同一个变量名称,可能表述不同的意思。
$varA = undef; –> 一个普通的未知类型的变量 varA;
$varA[0] –> 一个数组变量 varA ;
$varA{‘a’} –> 一个哈希变量 varA ;
$varA = []; –> 一个hashref变量 varA;
正是这种随意性使得Perl语言的变量掌握起来让人容易出错,再结合传值或者传引用,迷惑性更大。
3. Perloop/Perlobj 面向对象的Perl进行多数据库同时连接的问题
3.1.问题描述
在 GWA2Perl的实现中,对象连接数据库通过 WebApp –> Dba –> Conn –> Driver 的过程( -R/12SL )。 设若有对象ObjectA,需要连接数据库DatabaseA; 有对象ObjectB,需要连接数据库DatabaseB。
在此设置下,若单独运行实例化的 ObjectA,或者ObjectB均没有问题,或者同时运行ObjectA/ObjectB,同时连接到数据库DatabaseA,也没有问题。 当我们希望同时运行实例化的ObjectA/ObjectB,并分别连接数据库DatabaseA/DatabaseB时,问题就发生了,Perl的运行时环境中,总是留存最后一个活跃的数据库连接信息。
类似的问题并不会在非PerlOOP的环境中产生,如果在通过的函数式编程中,可以通过声明不同的 $dbi 实例来映射到不同的数据库连接上,并保持到一个session执行结束或者手工关闭。比如 $dbiDatabaseA 连接到DatabaseA上,$dbiDatabaseB连接到DatabaseB上。
3.2. 通过对象实例的UniqueId来区别实例
根据对问题的描述,在 PerlOOP中,实例化后的对象共享数据库连接,如果其中以参数的方式带入不同的数据库连接信息,实例化后对象的无法保持数据库信息与具体实例的对应关系。
解决的思路是在 WebApp一层增加如下设施:
1) + getUniqueId
2) + _checkDbConn
其中 1) 是在对象实例化后根据对象 Scalar::Util 的方法 refaddr 来获取对象的唯一 Id号,然后在 WebApp 中,实现对象与数据库信息做绑定;
2) 在 WebApp 中每当进行数据库读写操作时,获取当前实例化对象的 唯一Id,然后从环境变量 %hmf 中获得其绑定的 数据库信息,从数据库对象 $dba 中获得当前活跃的数据库信息,然后对两者做比较,当两者相符时,继续前行;当两者不一致时,重置/切换数据库连接至实例化对象所绑定的数据库上。
也许这是临时解决方案,在后续的PerlOOP中能得到解决,或者在 Perl 6中能够将对象封装的更严密些。
3.3 实例化后的对象根据唯一Id扩展
实现了可以同时操作多个数据库的PerlOOP,GWA2Perl的能力将进一步扩增,其他类似的资源读取均可以实现多源读取,如Session,Cache,File等其他网络资源。
这一问题是第二次碰到,起初遇到时,想到的是在程序中临时切换数据库连接,当其时并没有更好的解决方案,今次深入分析,获得一个可以自动化的持续解决方法,可以实现:
1) 同一个对象在一个时期内,总是持续一致地维持对资源的连接;
2) 不同的对象,拥有不同的资源连接,且可以同时并行。
-GWA2 是”通用网络应用架构( General Web Application Architeture )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .
-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for NativeApp, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.
-GWA2 is E.A.S.Y
Easy Along, Swift Yield
轻松启动, 快速产出.