背景:
阅读文章

轻轻松松学PIKE

[日期:2007-05-05] 来源:  作者:super [字体: ]

轻轻松松学PIKE之一
----神奇的PIKE
PIKE是一种基于解释的脚本语言,语法和C极其类似,并且有着十分强大的面向对象
编程机制。下面我们来看段hello world的代码:

int main()
{
    write("hello world!\n");
    return 0;


}

这样就是一段简单的PIKE代码了,从表面上来看,跟C简直没有一点区别,那么我们
怎么来执行它呢?假如这个程序的文件名为:my_first_program.pike
那么我们就在命令符下执行:pike my_first_program.pike那么我们就可以看到这段
代码的执行结果了。

其实如果大家接触过LPC的话,会发现PIKE实际上更象LPC一点,无论是语法还是编程
思想,都跟LPC同出一辙。但在功能上比LPC语言显得更加强大一点。

跟LPC做比较,PIKE语言有以下几个改进:
一,新增multiset和program两种新的数据类型。

multiset跟mapping十分相似,都属于hash表数据结构,但是不同的是multiset只有
key,而没有values,举个例子吧。
mapping里面每一个key所对应的地址都有一个values.格式如下:
mapping a = ([
"aaa" : 1,
"bbb" : 2,
"ccc" : "hello",
..
]);
如此,key和values存在一种一一对应的关系。
而在multiset里面则不是这样,我们这样来声明一个multiset:
multiset a;
随后可以赋值:a = (<1,2,"hello",3>);
至于multiset的特殊用处,将在以后的章节中做详细介绍,这里仅仅只是对multiset
做个简单的介绍。

然后我们来看看program类型,了解LPC的人都知道,在LPC里面存在一种.b代码,也就
是大家常说的二进制(binary)代码,LPC里面的这种代码是以文件的形式保存在硬盘上
的,而在PIKE里面,则有专门的program类型来储存该种代码。任何一个文件,在生成
object前,都必须先生成program,相同的文件生成出来的program是相同的,而相同
的program生成出来的object则是不同的,举个例子:
program p = compile_file("aaa.pike");
//上面的代码可以简写成program p = (program)"aaa.pike";
program p1 = compile_file("aaa.pike");
那么这个时候p == p1是返回true的。
随后,我们:
object a = p();
object b = p();
这个时候a == b是返回false的,也就是说,同一个文件生成的program在内存中永远只
有一个副本,而同一个program可以复制出很多不同的object.
该类型的详细应用将在以后的章节中做详细介绍。

二,支持多线程。
PIKE里面加入了multi threads模块的支持。
其中可以很方便的对线程进行各种各样的操作。
下面来看一个简单的例子:
void run_me(string);
int main()
{
    thread_create(run_me,"thread 1");
    thread_create(run_me,"thread 2");
    run_me("main");
    return 0;
}
void run_me(string a)
{
    for (int i=0;i<5;i++)
          write("I come from " + a + ".\n");
}
那么就可以看到多线程的威力了。
值得注意的是,在PIKE里面thread_create()返回的是一个object型的值,同时也可以在
所以我们要中断一个线程,就只需要destruct()掉thread_create()返回出来的object值
就行了,操作十分方便。
有一点值得注意的是,多线程只能在支持POSIX或者UNIX的操作系统上运行。

三,运算符重载。
运算符号重载是面向对象编程里面十分重要也是十分有用的一点。
在PIKE里面,提供了十分强大的运算符重载功能,可以重载任意运算符。
下面来看个例子:
比如,我们要让a-b的值变成a+b,则可以这么做:
mixed `-(mixed b)
{
    if (!intp(b) || !floatp(b)) return 0;
    return ::`+b;
}
然后在这以后,只要碰到a-b之类的运算都会转换为a+b了。
另外PIKE还支持LPC中的@运算符,即把@后面的array变量里面的每个元素作为参数传递
给@前面的函数,具体使用方法在这里就不做详细介绍了,看下面一个例子即可:
string *a = ({ "123","321"});
write(@a);
那么则会显示:123321
有一点值得注意的是在PIKE里面任何一个运算符都被看成是一个函数,因此我们可以用
调用函数的方式来使用运算符,即:
a + b我们可以写成`+(a,b)。
关于运算符重载的深入应用,将在以后的章节做详细介绍。

四,支持插入模块。
PIKE的各种各样的功能实际上都是模块的作用,比如说多线程,实际上是thread模块的
作用,PIKE目前的功能模块十分的多,目前有:
Image,Protocols,System,Process,Regexp,Gmp,Gdbm,Getopt,Gz,Yp,ADT,Yb,MIME,Mysql,
Crypto,Simulate,Calendar,Locale,Parser,Math
等等,模块的使用方法是xxx.yyy这样子,xxx是模块名称,yyy是模块内建函数名称。
由于模块的支持,使得PIKE具有了强大的扩展性。
下面来看一个自己写模块的例子:
我们创建一个文件:hello.pmod

void hello_world()
{
    write("hello world!\n");
    return 0;
}
并把它放在add_module_path()里面,就可以这样使用:
int main()
{
    .hello.hello_world();
    return 0;
}
或者可以这样写:
import .hello;
int main()
{
    hello_world();
    return 0;
}
=========================================================================
super@mudbuilder.net at 01/10/2002

轻轻松松学PIKE 之二
-----复杂而又简单的PIKE
由于这一系列文章面向的读者是已经有一定的编程基础的LPC程序员。
所以一些基本的语法或者基本概念在这里将不做详细介绍。

下面我们来看一看PIKE里面的面向对象思想。

在PIKE里面,除了直接执行的程序以外,任何一个代码都可以看成是
一个物件。跟LPC不同的是,PIKE里面所有物件里面的任何局部变量
都可以直接访问,其访问方式类似与mapping这种数据结构。
下面举个例子:
//aaa.pike
mapping a;
int b;
void aa();
...

然后我在另外一个程序里面写:
object ob = ((program)"aaa.pike")();
那么这个时候,假如我们要执行ob里面的aa()这个函数有两个路径。
第一,执行ob->aa();
第二,执行ob["aa"]();

这样让面向对象的观念变得十分的明显了,无论任何变量或者函数,都
是该物件的一种属性,这样更容易让人的思维所理解。由此一来,我们
在设计我们的PIKE代码的时候,能够更加直观的来实现。任何成员都可
以通过成员名来直接访问,不管成员的类型是什么。

在PIKE里面,淡化了函数这一概念,使其变得更加随意了,下面来看个
例子:
//aaa.pike
void aa() {...}

然后我在另外一个程序里面:
object ob = ((program)"aaa.pike")();
这个时候我们用ob->aa来访问aa这个成员,并且可以用
ob->aa = bb(); //假如bb()是一个function类型。
这样的形式来给aa这个成员重新赋值。也就是说,在PIKE里面无论是
什么类型的成员,都可以通过->运算符进行访问和修改。那么这些看起
来似乎很有趣的思想,在实际应用中有什么用途呢?下面我就来展现一
段给物件动态增减函数的代码:
mapping efun = ([]);
void add_func(string fname,function f)
{
    efun[fname] = f;
}
function `->(string func)
{
    function f;
    if (f = this_object()[func]) return f;
    else return efun[func];
}
void del_func(string fname)
{
    if (!zero_type(efun[fname]))
          m_delete(efun,fname);
}
那么任何继承了这段代码的物件,都可以用ob->add_func(string,function);
和ob->del_func(string)这样的形式来增减外部函数。

这个时候也许大家会问,PIKE这样的特性是否会带来安全上的隐患呢?下
面我们就这个问题来讨论讨论。

我们可以通过对各种运算符进行重载,在重载中对各种情况进行判断。在
上一章节中我们讲过同一个文件生成的program是完全相同的,由此我们就
可以在重载过程中对object_program(this_object())的结果进行判断,从
而得出该object的源头,然后再做一些限制和相应的判断。由此说来,PIKE
的安全性能是要比LPC还要高的。

在下一章节里面,我们将介绍PIKE在工程建设中的优势和长项。


轻轻松松学PIKE  之三
PIKE在工程建设中也有相当大的威力的。
大家都知道,每个程序都有一个出口,程序运行完以后,程序的代码就会
从内存中清除,如果要运行一个不会中断的程序,比如一个WEB SERVER
要怎么做呢?在PIKE里面只需要在main()函数里面简单的一个return -17;
即可。return -17不会做任何事,只是告诉系统这个进程还没执行完,不
要结束。

由于PIKE的->运算符前面的必须是一个物件,而不象LPC一样可以是一个
string,所以类似设计LPC里面的#define LOGIN_D "/adm/daemons/logind.c"
是不太好办的,当然,你完全可以
#define LOGIN_D ((program)"/adm/daemons/logind.pike")();来代替
但是这样做的弊端就是每出现LOGIN_D的地方就会重新复制出一个logind.pike
严重浪费资源,完全没有达到我们想要的效果。
在PIKE里面,我们可以用add_constant(string,mixed)来做。
add_constant()所做的就是根据一个固定的key绑定到一个固定的地址上。
跟mapping类似,都是使用了HASH表,不同的是,add_constant()出来的东西
可以出现在代码的任何地方。比如我:add_constant("hello",1);
那么之后只要在代码中出现了hello,都将替换成"hello"指向的地址上的内容。

跟JAVA一样,PIKE有自动回收垃圾(Garbage collection)的功能。
这使得我们在设计和组建某项工程的时候,可以把更多时间放在设计,而不是
实现上。

PIKE的多线程也是一个亮点,就如同LPC里面的call_other()一样简单,实在。
不过对于多线程间的同步也是一个相当大的问题,对此,可以用线程队列来解决。
使用方法如下:
import Thread;
inherit Queue : queue;
int n = 0;
void foo()
{
  write("I'm " + n +"\n");
n++;
}
void create()
{
  function f() { return foo(sth); };
for(int i = 0;i<5;i ++)
queue::write(f);
thread_create(queue::read()());
}
这样就是一个大小为5的线程队列的模型了。其中write()是把一个线程加入队列。
read()是从队列中读出一个线程,由于我写入的是一个function,所以read()出来
的也是一个function,所以用read()()来执行这个function。

------------------------------------------------------------------
super@mudbuilder.net

安装PIKE完全手册。
首先!
从super.tomud.com下载usr.rar和pike.rar这两个文件。
usr.rar解开到C盘的根目录下(记得!一定是C盘)
然后解开pike.rar到任意盘的根目录下,比如:H:\pike\
然后把pike.rar里面主目录下的master.pike覆盖
c:\usr\local\pike\7.2.197\lib\master.pike
并且拷贝一份覆盖master.pike.in,然后把master.pike.o文件随便改个什么名字。
然后!
就可以运行了!在pike.rar解开的那个盘的根目录下,执行
path c:\usr\local\pike\7.2.197\bin
pike start
即可,如果不能执行,请把出错信息mail给我,我将以最快的速度给您答复。

最后,打开ZMUD,连接localhost 777就可以了。 

 

尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
本文评论   [发表评论]   全部评论 (0)
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论