最新最强的单元测试工具--VcTester上场了

作者在 2009-09-19 13:54:10 发布以下内容
详情请登陆:http://www.cse-soft.org,可免费下载使用,并提供网上论坛(http://groups.google.com/group/VcTester)解决用户在使用过程中遇到的问题,也方便大家交流。  
  1、工具简单介绍:  
  VcTester是与VC(注:Visual   C++及Visual   Studio开发套件是微软发布的产品)配套使用的新一代单元测试工具,分共享版与商用版两大系列,其主要功能包括:脚本化测试驱动(包括修改变量与调用函数)、脚本桩、支持持续集成测试、测试覆盖率统计(仅商用版本)、生成测试报告(仅商用版本)等。  
  VcTester共享版由CSE共享软件基金(CSF,CSE   Shareware   Foundation)赞助开发,拥有自主版权,共享版系列版本按最终用户许可协议(EULA,End-User   License   Argeement)方式授权,终端用户可免费获取、免费使用。  
  2、相关评价:  
  VcTester除了白盒测试工具所具有的常规功能如:测试驱动、函数打桩、测试覆盖率统计(商用版本)、生成测试报告(商用版本)、测试消息编辑器/解析器(商用版本)外,VcTester还集成了第四代白盒测试的核心思想。共享版本可免费获得,相比同类测试工具,它的最大特点是在线测试,包括对变量的在线修改和函数在线调用、测试结果在线评估及改进。在线测试提供了所见即所得的操作模式,因为直观易用,符合程序员的思维习惯,相信该工具会给大家带来耳目一新的感觉。
默认分类 | 阅读 2444 次
文章评论,共1条
vfdff(作者)
2009-09-19 13:54
1
CSE vs Python<br />
Python是一门优秀的脚本语言,CSE无疑也是一门优秀语言,要不,本文不会将它们相提并论的作比较。<br />
<br />
事实上,要准确比确两门语言的特性差异不是一件容易的事。因为,既然一门语言能够存在,就有她存在的理由,她总有一些特殊的应用定位。由于定位不同,导致语言比较很难在对等的层面上展开,有谁尝试比较汇编语言与C#的异同吗?----所以,本文尝试比较Python与CSE,首先因为这两门语言的应用范围与表现特征有较高的重合度,可比性有了,其次,从两者的发展渊源来看,CSE是新生语言,从Python继承较多的风格,当然也摈弃了不少东西,比较这两者,不难管窥现今语言的承递脉络与发展趋势。<br />
<br />
CSE从推出第一个版本到现在还不到一年,打个比方,她还是一个婴儿,而Pyhton有数十年的发展历史,已经是个中年人了。两者在语言成熟度、应用广泛度、拥有资源丰富程度上,都存在很大差距,这是显而易见,不是我们比较的重点,本文更多的从核心语法语义上对比,也即重点比较两门语言的内涵,而非外延,新生语言的外延若假以时日,外部条件也具备了,总能很快抺平与他人差距的。而内涵相对稳定,如果核心语法有了很大改变,那可能演生出一门新语言,语言比较所假定的基础不存在了。<br />
<br />
现在比较CSE与Python就可能存在这个风险,还不是因为CSE尚处于快速发展中,更重要的是,CSE将适应语言发展变化当作她固有的一个特性,她好比是一部强大的进化机器,核心语法语义演化不只被认为可能,而且被认为是应该,或者说是必然。本人时隔3个月再次试用CSE新版本就大吃一惊,prop属性、yield产生式、测试脚本自动生成等令人惊异的特性好似一夜之间突然冒出来的。所以,本文不只比较CSE与Python的语法差异(否则一两年后这篇文章就成垃圾了),也比较两者的行事风格、运作模式、商业定位等方面的异同,有赖于与CSE缔造者wayne chan多年朋友关系,本文获得一些独家“内幕消息”,希望能给大家提供一点帮助。<br />
<br />
CSE与Python的总体感观差异<br />
CSE具备两面特性,她的第一面是脚本语言,另一面是编译语言,某种程度上说,前者是软语言,后者是硬语言,前者更富动态变化,或者说具备有机体特征,而后者是命令式架构,缺失一些变化,但具有更强的能力与更高的运行性能。拿wayne chan本人的话来说,他希望CSE是狮身人面像,在古埃及,狮身人面像被认为是智慧与权力的象权,CSE具备LISP语言特征,展现“拥有人的智慧”一面,同时还具备命令式语言特征,展现“如狮子般敏捷与强大”的另一面。<br />
<br />
这种两面性是CSE区别于其它语言的本质特征,可以说,CSE相比于Python,多数差异都源于此,把握住这一点就能很好理解什么是CSE了。CSE的“人面”已揭开面纱了,遗憾的是,“狮身”还无缘谋面,CSE编译器还没开发,我们无从揣测其特性。<br />
<br />
CSE的脚本表述方式与Python比较接近,函数、类、模块的组织方式很类似,一些命名风格,如系统保留命名__init__、__del__、__str__等都是一致。两者的外在脚本表现较接近,但内在的体系架构却存在天壤之别,可以说,CSE相比Python,外在表述的创新远逊于其内核组织机制的创新,外部创新甚至有点归于平淡。另外,试用过CSE后不难感觉她的行事风格与Python还是有很大差别的。<br />
<br />
比如,CSE的GUI界面是与生俱来的,第一个CSE版本发布时,IDE(集成开发界面)就已经比较完整,CSE的扩展模块还很少,但单元测试框架、跨进程MVC布署框架却已具备了,CSE的IDE还完整的支持单步调试功能。Python是另一种风格,先有命令行界面,集成IDE是后加的,而且其风格相对于内核比较另类,随正式版本发布的Python GUI(即IDLE)是用TCL/TK做的。这些差异,我们还不能简单的将之归结于初创者个人风格的差别,更多的,我们应理解为时代的差异,有人将前者称为Windows风格,使用风格倾向于终端用户,而后者称为Unix风格,使用风格倾向于开发者。毕竟时代变了,Python产生于上世纪80年代,那是Unix与Dos盛行的年代,CSE产生于21世纪初,是一个强调个性与客户体验的时代。<br />
<br />
再如,CSE还专注于为软件研发过程提供配套服务,而不只是提供一个执行器,Python软件缺少这种工程化思路。CSE推出第一个版本就宣称支持第4代白盒测试方法(4GWM,The 4th Generate White-box-testing Methodology),CSE后续版本还将内嵌XML解析器,注意,不是简单扩展出一个能解析XML的模块,而是直接使用CSE内核封一门可解析XML的语言,本质上说,CSE语言也是CSE内核的一种实例化实现,有点类似于.NET平台,CLR是核心平台,C#、VB.NET等是都是它的实例化实现。当CSE体系有了CSE执行器与XML执行器这两根支柱后,在IT工程服务方面必能大展身手,.Net号称是基于XML信息集成的系统,它的XML支持仍属外在扩展,当然这也没有太多坏处,只是某些内嵌紧耦合的应用无法支持,比方,CSE集成XML后,实际模糊了代码、文档、规格化数据三者之间的界限,无论对代码文档化,或文档代码化,还是UML表述及MDA转换支持,都是非常便利的。所以,仅此一点而论,CSE比.NET具有更高的起点,.NET使用XML保证了静态集成性,而CSE除静态集成性,还拥有更多的动态(或在线)集成特性。<br />
<br />
以上两点是本人初次接触CSE就有深刻体会的,除此之外,我们形而上的概括,CSE比Python更加FP(Functional Programming),Python的语法分析与字节码机制中尚保留强烈的命令式语言特征,CSE语法分析及解释执行增加不少生命气息(这个提法较抽象,不要紧,下文还有叙述),操作符与命令字(或称保留字)都是在线可定义的,不是语法分析固定规定的。<br />
<br />
由于这个原因,CSE语法表达显得非常灵活,当然,过于灵活不见得都是好事,一些不合规范的CSE脚本,解释器并不认为它是错的,这导致一些错误引入后不容易被发现。不合语法规则的脚本,许多时候CSE解释器只是忽略它,或者直接返回一个缺省值,并不报错。Python具备更多命令式风格,比较明确的限定哪些语句是合法的,哪些非法,能够检测的语法错误也就更多。比如下面2条CSE语句:<br />
<br />
raise EMyError, 'Here raise error.'; <br />
raise(EMyError, 'Here raise error.');<br />
<br />
这两个语句都是合法的,第一条CSE把它看成两个表达式,等效于“raise(EMyError),'Here raise error.';”,第二条CSE能正确解析成raise调用,很显然,这两个语句的执行效果不同的。<br />
<br />
CSE核心语法过于灵活,相比其它语言更容易误用,比如:<br />
<br />
iValue = 0;<br />
if iValue == nil:<br />
&nbsp;&nbsp;print('OK');<br />
end;<br />
<br />
&gt;&gt;&gt; executing script...<br />
ESyntaxError:Error at line 586, LNotator(if) not closed.<br />
<br />
上述报错多少有点让人摸不到头脑,分析一下,错误发生在nil误用了,因为nil注册为变元操作,变元操作可以有如下书写格式:<br />
<br />
&gt;&gt;&gt; nil&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# same to nil()<br />
0<br />
&gt;&gt;&gt; nil()<br />
0<br />
&gt;&gt;&gt; nil(0)&nbsp;&nbsp;# careful, nil not same to 0, but &quot;nil == 0&quot; is true<br />
0<br />
&gt;&gt;&gt; nil: 0; end;<br />
<br />
0<br />
<br />
因为变元操作可以写成以“:”开头、“end”结尾的语句块,所以前面报错是因为nil吃掉其后从“:”到“end”的语句块,使得if语句无法正常结束。上面例子若按CSE推荐格式,应写成:<br />
<br />
iValue = 0;<br />
if nil(iValue):&nbsp;&nbsp;# or, you can write &quot;if nil == iValue:&quot; as you like, but it is not same meaning<br />
&nbsp;&nbsp;print('OK');<br />
end;<br />
<br />
&gt;&gt;&gt; executing script...<br />
0<br />
<br />
与nil类似用法的还有dummy关键字。<br />
<br />
CSE与Python的核心语言要素差异<br />
CSE与Python一样,都是一门解释执行、动态交互、面向对象的编程语言,集合了模块化结构、异常处理、动态类型、高度抽象动态数据类型、类与类继承等特性。下面我们重点比较两者异性,相同之处只稍微提及,不展开说明。我们分如下五个方面展开叙述:<br />
<br />
&sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;编码风格 <br />
<br />
&sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据类型 <br />
<br />
&sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;函数定义 <br />
<br />
&sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;类与模块 <br />
<br />
&sup2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;扩展接口 <br />
<br />
先讲编码风格,两者的指令风格、保留字设置比较近似,他们的注释风格完全相同,都以“#”作为注释起始标记。编码风格差异主要表现在以下几个方面:<br />
<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;行缩进,Python采用行缩进风格,CSE无此要求<br />
<br />
Python代码:<br />
<br />
if isTrue:<br />
<br />
&nbsp;&nbsp;print 'OK'<br />
<br />
else:<br />
<br />
&nbsp;&nbsp;print 'fail'<br />
<br />
CSE代码:<br />
<br />
if isTrue: print('OK'); end else print('fail');<br />
<br />
换行符及每行缩进字符在Python是有语法含义的,在CSE中不具语法含义,换行符在Python中作为语句自然结束标记,CSE中各语句或表达式必须以逗号或分号分隔。两者均以“:”作为语句块起始标记,但Python以行缩进指示语块何处结束,CSE必须明确用end关键字指示。<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;前后缀风格<br />
<br />
Python使用&quot;_&quot;前缀指示变量或函数是否私有,CSE除了使用前缀指示变量类型,还使用“_”后缀指示变量或函数是否私有。之所以要用前缀标识数据类型,是因为CSE要兼容解释执行与编译执行两种运行模式。<br />
<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;构词法<br />
<br />
Python与CSE均可用单引号或双引号构造字串,不同的是,Python使用单引号或双引号构造字串不可以跨行,CSE可以跨行。Python要构造跨行字串应使用longstring标记,即起止为连续3个单引号(或双引号)。<br />
<br />
Python支持迭代方式构造List数据,比如:[i for i in range(5)],CSE不支持。<br />
<br />
另外,CSE中的分号(;)与冒号(:)只是分隔符,语法含义与“,”等同。比如:Python构造字典数据“{key1:value1,key2:value2}”,CSE也支持这种书写格式,另外还可以写成:“{key1,value1,key2,value2}”,再如:<br />
<br />
tt = (1,2,3);<br />
print(tt);<br />
<br />
将上面两行CSE脚本的逗号与分号互换,写成如下样子也是可以的:<br />
<br />
tt = (1;2;3), print(tt),<br />
<br />
接下来我们看看CSE与Python的数据类型差异,CSE中的int、float、string、buff、dict类型与python中相关数据类型一一对应,其中Python中的list在CSE中改叫buff了,个人揣测:“l”前缀比较难看,容易与数字1弄混,CSE干脆改称list为buff,用“b”作前缀了。CSE与Python主要数据类型差异如下:<br />
<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE放弃Python中的tuple类型,而增加了Tier类型<br />
<br />
Python中的tuple与buff都能保存任意类型的数据,两者功能重复了,至少表面上如此(实际上tuple在Python中还来表达immutable数据、函数调用参数等)。CSE认为tuple类型并非必须,而且,用户面对tuple与list,到底选择哪一个常有困扰,这个类型毫无悬念的被喀嚓掉了。<br />
<br />
同时,Python中的string实际上是字符数组,list实际上是任意类型的数组,int数据最常用,却没有int数组,只能用list去构造。CSE认为这是不充分的,尤其在增加编译支持后,应尽量用int数组代替list数据,int数组直译为数据块,无论加快运行速度还是节约内存空间,都是很有益的,所以CSE语言新增设了Tier类型。<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE的WideInt对应Python的long,但CSE的WideInt宽度限定于int的2倍,而Python的long是不限宽度的 <br />
<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE新增了ID与Notator数据类型 <br />
<br />
一个变量名或函数名在表达式中计算时,它是变量或函数,但它在描述一种指示体时,是ID类型,ID被计算1次就是变量或函数,或者这么认为,ID是“域名查找”计算0次时的值,而变量或函数是“域名查找”计算1次的值。<br />
<br />
CSE还使用Notator类型表达操作运算,比如“3+5”被描述成&lt;+:3,5&gt;,“print(3+5)”被描述成:&lt;print:&lt;+:3,5&gt;&gt;,当“&lt;+:3,5&gt;”被计算0次时,它是Notator数据,而被计算1次时,就得到计算结果8了。<br />
<br />
Notator与ID反映了程序代码的静态特性,把常见的表达式也描述成一种数据,所CSE的表达式是可以自由传递的。Python也提供类似机制,CodeType就是这种运行代码的数据形式表达,不同的是,Python封装这种“执行体数据”仅让用户可以从中读取一些简单信息,并没有很好的抽象其组成要素并开放出去,即,Python的CodeType还不是完整意义上的可读写的数据类型。<br />
<br />
有了ID与Notator类型,CSE更象一个可以自我成长的有机体了。下面举一个例子,先定义TRemoteModule:<br />
<br />
uses:<br />
&nbsp;&nbsp;'duality.cse';<br />
<br />
&nbsp;&nbsp;'bases.cse';<br />
<br />
&nbsp;&nbsp;'rpc.cse';<br />
end;<br />
<br />
<br />
class TRemoteModule:<br />
<br />
&nbsp;&nbsp;sPeer_ := '';<br />
<br />
&nbsp;&nbsp;iWait_ := 5000; # 5 seconds<br />
<br />
 <br />
<br />
&nbsp;&nbsp;func __init__(me,sPeer,iWait=5000):<br />
<br />
&nbsp;&nbsp;&nbsp; me.sPeer_ = sPeer;<br />
<br />
&nbsp;&nbsp;&nbsp; me.iWait_ = iWait;<br />
<br />
&nbsp;&nbsp;end;<br />
<br />
 <br />
<br />
&nbsp;&nbsp;func __get__:<br />
<br />
&nbsp;&nbsp;&nbsp; declare(me,$var);<br />
<br />
&nbsp;&nbsp;&nbsp; if str($var)[-1] == '_':<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setRet(me.$var@1);<br />
<br />
&nbsp;&nbsp;&nbsp; end else setRet(rpc.evalEx(local.(bArg_[0]),[$var],<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me.iWait_,me.sPeer_));<br />
<br />
&nbsp;&nbsp;end;<br />
<br />
 <br />
<br />
&nbsp;&nbsp;func __set__:<br />
<br />
&nbsp;&nbsp;&nbsp; declare(me,$var,value);<br />
<br />
&nbsp;&nbsp;&nbsp; setRet(value);<br />
<br />
&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp; if str($var)[-1] == '_':<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me.$var@1 = value;<br />
<br />
&nbsp;&nbsp;&nbsp; end else rpc.evalEx(local.(bArg_[0])=bArg_[1],[$var,value],<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me.iWait_,me.sPeer_);<br />
<br />
&nbsp;&nbsp;end;<br />
<br />
end;<br />
<br />
TRemoteModule用于将本机其它CSE进程映射为本程序的一个类对象。比如当前程注册RPC端口为CseWin,启动本机另一个进程,注册RPC端口为CseClient,假定CseClient程序已定义一个变量sValue,其值为“I am at CseClient.”,之后我们在当前CseWin程序中远读写CseClient中变量sValue:<br />
<br />
&gt;&gt;&gt; CseClient = TRemoteModule('CseClient')<br />
<br />
&lt;instance of TRemoteModule:15423226&gt;<br />
<br />
&gt;&gt;&gt; CseClient.sValue<br />
<br />
I am at CseClient.<br />
<br />
&gt;&gt;&gt; CseClient.sValue = 'Yes, I know.'<br />
<br />
Yes, I know.<br />
<br />
&gt;&gt;&gt; CseClient.sValue&nbsp;&nbsp;# the value should changed<br />
<br />
Yes, I know.<br />
<br />
这个例子中,读写对端变量的表达式很方便的透传到另一个程序执行了,而且,应用接口封装可以不留痕迹,就象读写远程变量就像操作本地的变量一样。<br />
<br />
4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE未支持unicode字串<br />
<br />
准确来讲,CSE内核未支持针对unicode字串的相关操作。因为unicode直接面向应用,CSE仅将它理解为字串的特定应用,比如取字串长度调用函数“len(s)”,如果支持unicode或许应增加一个函数“uniStrLen(s)”,应该在扩展库中实现这些定义。Python则是另一思路,把unicode支持合到内核去了。基于相同理由,CSE也没象Python那样支持复数类型。<br />
<br />
从中我们不难看出,CSE与Python遵循了两种行事风格,CSE尽力维持精简的内核,把内核当成DNA,然后在外围将DNA组装成细胞,根据不同功能制造不同细胞,比方能运载氧气的红细脑,能抵御外敌的白细胞,具有记忆功能的脑细胞等,最后才组合各类细胞制造有机体。所以,CSE内核之上可以封装新语言,不只形成CSE,完全可以仿真C、Python等语言。<br />
<br />
Python内核处于更高一个层面,它已经是细胞了,库模块type.py记录了Python内嵌的数据类型,除了int、float、string、tuple、list、dict等基本类型外,还有Unicode、函数、类、类实例、类方法、lambda对象、文件对象、产生式等30多种类型,这已经是种类齐全的细胞库了。<br />
<br />
5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Python用中括号([])操作字典,CSE用花括号({})操作字典,如:<br />
<br />
Python字典操作:<br />
<br />
&gt;&gt;&gt; dd = {1:'One',2:'Two'}<br />
&gt;&gt;&gt; dd[2]<br />
<br />
'One'<br />
<br />
&gt;&gt;&gt; dd[3] = 'Three'<br />
<br />
CSE字典操作:<br />
<br />
&gt;&gt;&gt; dd = {1:'One',2:'Two'}<br />
<br />
{1:'One',2:'Two'}<br />
<br />
&gt;&gt;&gt; dd{2}<br />
<br />
One<br />
<br />
&gt;&gt;&gt; dd{3} = 'Three'<br />
<br />
Three<br />
<br />
&gt;&gt;&gt; dd{4:'Unknow'}&nbsp;&nbsp;# if key(4) not exist, return default value('Unknow')<br />
<br />
Unknow<br />
<br />
CSE的函数定义要比Python复杂,因为CSE函数还同时承担Iter迭代功能,Python的迭代器是后期版本追加的,如果算上迭代功能,CSE函数定义附加的规则与Python相当。这两者都支持缺省参数与变长参数,他们主要差别如下:<br />
<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;调用CSE固定格式函数时,可用“:=”赋值指示函数返回,Python无类似功能<br />
<br />
该功能可心让代码书写更加紧凑,比如:<br />
<br />
s = 'Coverage:%s, rate:%d';<br />
<br />
strJoin(s,',Test passed.');&nbsp;&nbsp;# return new string length<br />
<br />
print(s % ['LICC',95]);<br />
<br />
可以改写为:<br />
<br />
print(strJoin(s := 'Coverage:%s, rate:%d',',Test passed.') % ['LICC',95]);<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Python支持Documentation Strings,CSE无此功能<br />
<br />
Python中Documentation Strings常用于函数接口提示,如:<br />
<br />
def my_function():<br />
<br />
&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;Do nothing, but document it.&quot;&quot;&quot;<br />
<br />
&nbsp;&nbsp;&nbsp; pass<br />
<br />
 <br />
<br />
&gt;&gt;&gt; print my_function.__doc__<br />
<br />
Do nothing, but document it.<br />
<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE的IterScript函数可以传递表达式的原始数据,Python无此功能<br />
<br />
比如:<br />
<br />
func showVar:<br />
<br />
 <br />
<br />
&nbsp;&nbsp;declare($var);<br />
<br />
&nbsp;&nbsp;print($var, &quot;:&quot;, $var @ -1);<br />
<br />
end;<br />
<br />
 <br />
<br />
&gt;&gt;&gt; iValue = 55;<br />
<br />
55<br />
<br />
&gt;&gt;&gt; showVar(iValue)<br />
<br />
iValue : 55<br />
<br />
4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;产生式定义<br />
<br />
CSE与Python的产生式都按无堆栈计算方式实现,两者都以yield与return指定产生值,用法也相同,两者都支持在异常处理语句中(try..except..finally)返回产生值。两者也都支持在for语句及迭代器对象(CSE是TIter类,Python中是generator对象)中调用产生函数。<br />
<br />
CSE中函数未尾的yield并非最后一次返回,而在python中是最后一次返回,如CSE中:<br />
<br />
func test:<br />
<br />
&nbsp;&nbsp;declare(i);<br />
<br />
&nbsp;&nbsp;yield i;<br />
<br />
&nbsp;&nbsp;i = i + 1;<br />
<br />
&nbsp;&nbsp;setRet(i);<br />
<br />
&nbsp;&nbsp;yield i + 1;<br />
<br />
end;<br />
<br />
 <br />
<br />
&gt;&gt;&gt; for i in test(3): print(i); end;<br />
<br />
3<br />
<br />
5<br />
<br />
4<br />
<br />
在Python中:<br />
<br />
def test(i):<br />
<br />
&nbsp;&nbsp;yield i<br />
<br />
&nbsp;&nbsp;i = i + 1<br />
<br />
&nbsp;&nbsp;yield i + 1<br />
<br />
end;<br />
<br />
 <br />
<br />
&gt;&gt;&gt; for i in test(3): print(i)<br />
<br />
3<br />
<br />
5<br />
<br />
在for语句之外取产生值的书写方式两者有差异,在CSE中:<br />
<br />
&gt;&gt;&gt; test(3)<br />
<br />
[3,5,4]<br />
<br />
&gt;&gt;&gt; IterObj = TIter(test,3)<br />
&lt;instance of TIter:15512334&gt;<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
3<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
5<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
4<br />
<br />
&gt;&gt;&gt; assert( dummy(IterObj.next()) )<br />
<br />
1<br />
<br />
CSE中以TIter类实例包装迭代器,而Python采用一次调用赋值得到迭代器,CSE中一次调用产生式函数得到产生值列表,在Python中要用list函数调用得到产生值列表。另外,CSE的迭代器对象在迭代调用结束后,再取产生值得到的始终是dummy,Python在迭代结束后再取产生值引发StopIteration异常。如:<br />
<br />
&gt;&gt;&gt; list(test(3))<br />
<br />
[3,5]<br />
<br />
&gt;&gt;&gt; IterObj = test(3)<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
3<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
5<br />
<br />
&gt;&gt;&gt; IterObj.next()<br />
<br />
Traceback (most recent call last):<br />
&nbsp;&nbsp;File &quot;&lt;stdin&gt;&quot;, line 1, in ?<br />
StopIteration<br />
<br />
5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作符与保留字定义<br />
<br />
在CSE中定义一个函数后,可以将该函数注册为一元、二元或多元操作,也可以注册该函数为编程语言的保留字(如if、else、return等),Python没有这种动态定义新语法的功能。我们取duality.cse中的代码作说明:<br />
<br />
func `%`(v1,v2):<br />
&nbsp;&nbsp;iType1 = type(v1);<br />
&nbsp;&nbsp;if equal(iType1,iIntType):<br />
&nbsp;&nbsp;&nbsp; setRet(intMod(v1,v2));<br />
&nbsp;&nbsp;end else if equal(iType1,iStrType):<br />
&nbsp;&nbsp;&nbsp; setRet(strFormat(v1,v2));<br />
&nbsp;&nbsp;end else raise(ETypeError,'Type mismatch in operator:%');<br />
end;<br />
<br />
<br />
<br />
registDuality('%',65);<br />
<br />
这里按常规语法义定义一个取余函数,再将“%”注册为二元操作符,其优先级为65。然后,下面语句就可以正常执行了:<br />
<br />
&gt;&gt;&gt; 5 % 3<br />
<br />
2<br />
<br />
&gt;&gt;&gt; 'Coverage:%s, rate:%d' % ['LICC',95]<br />
<br />
Coverage:LICC, rate:95<br />
<br />
定义一元操作符,如:<br />
<br />
&gt;&gt;&gt; registUnary('print',1)<br />
<br />
0<br />
<br />
&gt;&gt;&gt; print 'Coverage:%s, rate:%d' % ['LICC',95]<br />
<br />
Coverage:LICC, rate:95<br />
<br />
0<br />
<br />
上面将print注册为一元操作,设为优先级为1,因print函数已存在,这里不须重复定义它。之后,我们就可以象Python的print语句一样使用了,不必非得按函数方式。<br />
<br />
定义Notator命令字,如:<br />
<br />
&gt;&gt;&gt; registVariety('lambda',0)<br />
<br />
0<br />
<br />
&gt;&gt;&gt; i1 = 3; i2 = 4<br />
<br />
4<br />
<br />
&gt;&gt;&gt; lambda: i1,i2; (i1 &lt; 3) or i2; end<br />
<br />
4<br />
<br />
前面例子我们演示的lambda是普通函数调用,这里,将lambda注册为变元操作符后,我们既可以象普通函数一样调用它,也可以用类似if、else、while等句式,即,以“:”开启语句块、以end结束语句块的方式调用它,lambda成为编程语言的关键字了。<br />
<br />
介绍过函数定义的差别后,我们再来分析两门语言在类与模块方面的差异。尽管Python支持类与类继承,但对完整的类封装概念来说,是不够完整的。CSE尝试提供完整的类封装与继承,对比这两者,除了Python支持多重继承,CSE只支持单继承外,Python在类特性可以说只是CSE的子集,下面我们罗列主要差异:<br />
<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE解决了Python中“可见性倒置”问题。<br />
<br />
如下Python代码:<br />
<br />
class T1:<br />
<br />
&nbsp;&nbsp;def getName(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return 'George'<br />
<br />
&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;def test(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return self.getName() + ' is wonderful.'<br />
<br />
&nbsp;&nbsp;<br />
<br />
class T2(T1):<br />
<br />
&nbsp;&nbsp;def getName(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return 'Peter'<br />
<br />
&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;def show(self):<br />
<br />
&nbsp;&nbsp;&nbsp; print self.test()<br />
<br />
&nbsp;&nbsp;<br />
<br />
&gt;&gt;&gt; v1 = T1()<br />
<br />
&gt;&gt;&gt; v1.test()<br />
<br />
'George is wonderful.'<br />
<br />
&gt;&gt;&gt; v2 = T2()<br />
<br />
&gt;&gt;&gt; v2.show()<br />
<br />
'Peter is wonderful.'<br />
<br />
所谓可见性倒置,是指基类中函数定义被继承类下同名函数定义覆盖,如上例,基类T1下的方法test调用后打印“George is wonderful.”,该方法被T2继承后再调用,打印结果却不幸被篡改成“Peter is wonderful.”。也就是说,设计T1的test函数时,设计师并不假定他当前调用T1.getName方法会发生意外,而事实上T2类定义时因不小心因同名将基类中函数屏蔽了。<br />
<br />
可见性倒置破坏了类对象封装性,基类已固化的函数不应看到(或调用)继承类中的函数。如果程序逻辑需要这么做,那是回调函数的设计思路,规划基类时就应预留接口了,比如:<br />
<br />
class T1:<br />
<br />
&nbsp;&nbsp;def __init__(self):<br />
<br />
&nbsp;&nbsp;&nbsp; self.getName = self.getBaseName;<br />
<br />
&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;def getBaseName(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return 'George'<br />
<br />
 <br />
<br />
&nbsp;&nbsp;def test(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return self.getName() + ' is wonderful.'<br />
<br />
&nbsp;&nbsp;<br />
<br />
class T2(T1):<br />
<br />
&nbsp;&nbsp;def __init__(self):<br />
<br />
&nbsp;&nbsp;&nbsp; self.getName = self.getNewName;<br />
<br />
 <br />
<br />
&nbsp;&nbsp;def getNewName(self):<br />
<br />
&nbsp;&nbsp;&nbsp; return 'Peter'<br />
<br />
&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;def show(self):<br />
<br />
&nbsp;&nbsp;&nbsp; print self.test()<br />
<br />
CSE的类方法域名查找总与定义它的class类相关联,解决了这个问题。<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE支持可持久化的类属性,Python无此内容<br />
<br />
CSE提供一种函数化的属性操作,类似于Pascal中的“property xxx read getXX write setXX”,如下:<br />
<br />
class TT:<br />
<br />
&nbsp;&nbsp;iValue_ = 0;<br />
&nbsp;&nbsp;sValue_ = 'example';<br />
<br />
 <br />
<br />
&nbsp;&nbsp;prop iValue(me,value=nil):<br />
<br />
&nbsp;&nbsp;&nbsp; if nil(iValue):<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setRet(me.iValue_);<br />
<br />
&nbsp;&nbsp;&nbsp; end else:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me.iValue_ = value;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setRet(value);<br />
<br />
&nbsp;&nbsp;&nbsp; end;<br />
<br />
&nbsp;&nbsp;end;<br />
<br />
 <br />
<br />
&nbsp;&nbsp;prop sValue(me):<br />
&nbsp;&nbsp;&nbsp; setRet(me.sValue_);<br />
&nbsp;&nbsp;end;<br />
<br />
end;<br />
<br />
&gt;&gt;&gt; v = TT()<br />
&lt;instance of TT:15002786&gt;<br />
&gt;&gt;&gt; v.iValue<br />
0<br />
&gt;&gt;&gt; v.iValue = 3<br />
3<br />
&gt;&gt;&gt; v.sValue<br />
example<br />
&gt;&gt;&gt; v.sValue = 'abc'&nbsp;&nbsp;# TT.sValue is readonly<br />
EArgsError:sValue expect 1 arguments, but 2 passed.<br />
<br />
把类属性定义成函数调用方式,可以方便的为属性存取过程添加特定控制,同时,也便于操作接口变得持久,维护的需求可反映在prop函数定义上,接口能一直维持稳定,JAVA持久化技术也采用类似方案,JAVA持久化类包含特定的getXX与setXX方法,用于属性读写控制。<br />
<br />
从上面例子还看出,CSE的prop定义可用于只读属性控制。<br />
<br />
3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE提供protected方法继承,Python未支持,如:<br />
<br />
class T1:<br />
&nbsp;&nbsp;intValue_ := 95;<br />
&nbsp;&nbsp;strValue_ := '';<br />
<br />
&nbsp;&nbsp;prop showMsg_(me,sName):<br />
&nbsp;&nbsp;&nbsp; print('%s got score:%d' % [sName,me.intValue_]);<br />
&nbsp;&nbsp;end;<br />
<br />
&nbsp;&nbsp;prop sValue_(me):<br />
&nbsp;&nbsp;&nbsp; setRet(me.strValue_);<br />
&nbsp;&nbsp;end;<br />
<br />
end;<br />
<br />
class T2(T1):<br />
&nbsp;&nbsp;func test(me):<br />
&nbsp;&nbsp;&nbsp; me.showMsg_('George');<br />
&nbsp;&nbsp;end;<br />
end;<br />
<br />
&gt;&gt;&gt; v = T2()<br />
&lt;instance of T2:15423662&gt;<br />
&gt;&gt;&gt; v.test()<br />
George got score:95<br />
&gt;&gt;&gt; v.showMsg_('george') # should raise error<br />
EAttrError:Attribute not exist:showMsg_<br />
<br />
上面showMsg_函数在T1及其继承类T2类定义中可见,但在外部不可见。大家或许会问,私有命名的prop函数在继承类可见,是不是破坏了封装原则,如上例sValue_希望在继承类不可见,遇到这种情况只需将prop函数改成常规函数,丝毫不影响其功能实现。<br />
<br />
4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE解决了Python中保留方法__get__、__set__嵌套循环的问题<br />
<br />
拿前面TRemoteModule的例子,__get__函数定义如下:<br />
<br />
class TRemoteModule:<br />
<br />
&nbsp;&nbsp;sPeer_ := '';<br />
<br />
&nbsp;&nbsp;iWait_ := 5000; # 5 seconds<br />
<br />
 <br />
<br />
&nbsp;&nbsp;func __init__(me,sPeer,iWait=5000):<br />
<br />
&nbsp;&nbsp;&nbsp; me.sPeer_ = sPeer;<br />
<br />
&nbsp;&nbsp;&nbsp; me.iWait_ = iWait;<br />
<br />
&nbsp;&nbsp;end;<br />
<br />
 <br />
<br />
&nbsp;&nbsp;func __get__:<br />
<br />
&nbsp;&nbsp;&nbsp; declare(me,$var);<br />
<br />
 <br />
<br />
&nbsp;&nbsp;&nbsp; s = str($var)<br />
<br />
 <br />
<br />
 <br />
<br />
&nbsp;&nbsp;&nbsp; if s == 'sPeer_':<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setRet(me.sPeer_);<br />
<br />
&nbsp;&nbsp;&nbsp; end else if s == 'iWait_':<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setRet(me.iWait_);<br />
<br />
&nbsp;&nbsp;&nbsp; end else setRet(rpc.evalEx(local.(bArg_[0]),[$var],<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; me.iWait_,me.sPeer_));<br />
<br />
&nbsp;&nbsp;end;<br />
end;<br />
<br />
__get__函数截获TRemoteModule类对象取成员的操作,但如果__get__函数中也有取自身成员的操作呢?如上面脚本中,“me.sPeer_”与“me.iValue_”属于这种情况。是不是再次调用__get__函数呢?若是,就进入无限递归了,Python是按无限递归处理的,CSE附加特别控制,__get__函数尚在运行中是不会重复进入__get__递归调用的。<br />
<br />
Python的__set__调用也存在类似问题,CSE规避了此情况。<br />
<br />
5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;模块与类之间的关系<br />
<br />
Python中的模块与类是按两套机制实现的,两者之间不能自由转换,CSE中的类与模块按同一机制实现,如:<br />
<br />
class TT:<br />
&nbsp;&nbsp;ValueInTT = 100;<br />
<br />
&nbsp;&nbsp;func testFunc():<br />
&nbsp;&nbsp;&nbsp; print('function testFunc() in TT');<br />
&nbsp;&nbsp;end;<br />
end;<br />
<br />
 <br />
<br />
&gt;&gt;&gt; uses TT<br />
{ValueInTT:100,testFunc:&lt;FrmtScript:&gt;}<br />
&gt;&gt;&gt; testFunc()<br />
function testFunc() in TT<br />
<br />
一个类定义可以改用作模块,这一特性使CSE具备更优良的可组合特性,比方打包编译,多个脚本模块可以无歧义的并成成一个模块,原模块定义归并到新模块的一个类定义下。<br />
<br />
最后,我们再介绍CSE与Python的扩展接口差异。CSE也像Python一样,提供多种语言扩展接口,既可以用C/C++实现API扩展,也可以用Delphi或其它高级语言做扩展(CSE有计划要支持C#与VBA的接口扩展),CSE与Python都既可以将扩展命令嵌入到脚本系统中使用,也可以将脚本系统内嵌到其它由C/C++/Delphi等开发的系统中。总体而言,CSE的可扩展性要优于Python,表现在如下方面:<br />
<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CSE扩展函数中多线程处理比Python要简单<br />
<br />
CSE与Python都使用全局锁保证同一时刻仅一个脚本线程在执行,比如在C语言程序开发中,创建一个新线程要调用脚本解释器,Python要求初始化该解释器的线程控制块,比较复杂。而在CSE,只须调用一个API函数,如:<br />
<br />
Cse_lock(1);<br />
// do something call script system<br />
Cse_lock(-1);<br />
<br />
在这两个Cse_lock之间的语句运算CSE脚本都是线程安全的。CSE释放解释器控制权也用到这个API,比如:<br />
<br />
i = Cse_leave();<br />
// do something out of script system<br />
Cse_lock(i);<br />
<br />
Cse_leave用于释放当前线程对脚本解释器的占用,Cse_lock用于重新获得对解释器的控制权。<br />
<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;使用C/C++扩展一个Python内嵌模块非常复杂,而CSE简单多了<br />
<br />
这是两门语言采用了不同机制决定的,Python抽象出不少操作在基础类型定义(PyTypeObject)必须处理,而且Python的模块结构与类结构是两套机制,用户要深入了解其类型格式才能胜任扩展工作。CSE的类与模块使用同一套机制,而且都以字典类型保存,定义一个类对象并不附加特别类型结构。所以,在CSE中用编译语言扩展一个模块非常容易,根据实际经验估算,开发一个规模不大的扩展模块,在CSE中要比Python中快出四、五倍。<br />
<br />
举个例子,如下脚本类定义:<br />
<br />
class TTest:<br />
&nbsp;&nbsp;func test(me):<br />
<br />
&nbsp;&nbsp;&nbsp; print('OK');<br />
&nbsp;&nbsp;end;<br />
<br />
end;<br />
<br />
若改用Delphi定义它,框架代码如下:<br />
<br />
function TTest_test(me:PCseObj):integer; stdcall;<br />
begin<br />
<br />
&nbsp;&nbsp;// to do: define TTest.test<br />
end;<br />
<br />
<br />
Class_TTest := Cse_NewClass('TTest',CseNilValue); // class TTest: end;<br />
<br />
Cse_RegistApi(Class_TTest,'test(me)',@TTest_test,ctFrmtStdcall);<br />
<br />
再把TTest类定义放到某模块下(比如MyModule.csb):<br />
<br />
MyModule := Cse_NewClass('MyModule.csb',CseNilValue);<br />
<br />
Cse_SetRefSpace(Class_TTest,CseBltinModule); // uses '__bltin__.csb'<br />
<br />
key := Class_TTest.entry^[1].value;<br />
<br />
CseDict_set(_CompilerClass,key,Class_TTest,key.count);<br />
<br />
大家感觉一下,是不是很简单。<br />
<br />
到这里,CSE与Python核心语法的主要差异已介绍完毕,需要强调的是,CSE相对Python,对语言要素的改良多过创新,除了类封装与继承有较多改进外,其余基本上是对Python做优化。毕竞Python产生于上世纪80年代,其体系架构成形后就很难推倒重来了,CSE没有历史负担,可以站在更高起点大胆往前走出一步。实际上,就编程语言的表现形式而言,很难再有多少创新了,C#是一门伟大的语言,也只是将现有数种语言的优点揉合一起而已。<br />
<br />
CSE最大亮点应在内核架构上,从词法分析到语法分析,再到语义分析,在常规编程语言中是不可分隔的整体,牵一发而动全身,很少有语言新增关键字而不重写语法分析的。毫无疑问CSE做到了,其内核具有化腐朽为神奇的力量----所有CSE控制结构,包括if、else、while、for、try、except等,都是外部扩展的API,立体式的语法分析过程被改造成平面式条条块块,各个语法要素可以象积木一样组装。大家不妨阅读CseCompiler的源码,所有控制语句都在BltinFlow.pas中定义,区区数百行代码就搞掂了。<br />
<br />
CSE似乎理顺了“鸡生蛋,蛋生鸡”自我进化的最佳路径,常规编程语言是看管着长大的,在外力作用下,可以推倒重来。但如果改成自我进化,就是另一种要求了,首要一点是:进化的演变过程不能中断。1.5亿年前的始祖鸟只能在树间跳跃滑翔,而现在的北极燕鸥来回迁徙一次,飞行4万公里,能绕地球一周了。进化的力量如此强大,但我们不能因为始祖鸟的羽翼比较原始,把它杀了重造一个,或者,把蛋拿过来改一改让它变凤凰。破坏性重构不是有机体的生存之道,CSE最大的创新主是:她很好的解构了编程基本要素,把语言重构需求限定在局部范围。<br />
<br />
CSE与Python的版权与商业运作模式差异<br />
Python从2.1版本开始完全采用与GPL相兼容的开源协议,这是近乎公共域的授权许可,允许免费修改、免费二次发布,而且对商业应用比较友好。CSE除解释器内核(CseKernel.csd)外采用MPL授权,也允许自由获取源码,允许免费修改、免费二次发布,但要求修改后的代码版权归CSE共享软件基金会,CSE的授权形式对商业应用是友好的,甚至,CSF基金组织鼓励商业机构使用CSE。<br />
<br />
MPL中对“发布”的定义是“以源代码方式发布的文件”,意味着MPL允许一个企业在自己现有的代码库上追加一个接口,以这个接口作阻隔引入开源代码,除了接口程序的源代码要以MPL形式对外授权外,产品自身代码就不必按MPL要求强制对外开放。所以,商业应用CSE软件是安全的,即便是CSE内核,由《CSF软件最终用户许可协议(ELUA)》规定,内核模块是免费使用、可自由传播的,因为CseKernel.csd在REDIST列表之中。<br />
<br />
Python的版权形式比CSE要宽松,CSE采取多种授权的策略,为开发者保留了更多权益。其中,CSE内核以共享软件形式提供,用户得不到源码,按作者的话来说,这是为了维护CSE核心语义纯粹性,我们不妨解读为:作者保障大家自由使用CSE的权利,但不希望商业机构重写内核,掺和搅局。<br />
<br />
业界开源组织采用MPL授权的,许多情况是因为还没想清楚以后如何发展,CSE似乎有此考虑,她没打算从CSE语言(包括内核)获得收益,但不排除要从CSE的附属产品(比方相关工具软件)获取回报。另外,CSF全称是“CSE Shareware Foundation”,而不是“CSE Opensource Foundation”,也喻示着CSF组织对依赖社会捐赠的模式并不抱十足信心,一方面因为国内开源氛围没法乐观,另一方面,CSE是一个庞大的系统工程,没有充足资金支持是很难发展的。<br />
<br />
与Python不同,Python完全依赖社会捐赠,CSE走的是一条“具有中国特色”的开源之路,目前CSE扩展模块还很匮乏,CSF并不急着把应用库丰富起来,而是采取稳扎稳打的策略,在良好规划系统框架的前提下,由实实在在的商业应用带动内容建设,用到什么就先开发什么。WAYNE工作室作为CSE发展策略的载体,不只自己开发一些基于CSE的应用,也协助业界开发上层应用,借此方式逐步丰富CSE的内涵。<br />
<br />
<br />
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wayne_chan/archive/2006/09/24/1271780.aspx
游客请输入验证码
浏览1939410次