文字MUD游戏论坛-天下泥潭群英会-水泊梁山  

返回   文字MUD游戏论坛-天下泥潭群英会-水泊梁山 > 西游之旅 > 『 巫师天下 』

『 巫师天下 』 学习如何挂MUD,如何制作MUD。讨论如何管理好一个MUD,做好一个巫师。

发表新主题 回复
 
LinkBack 主题工具 主题评分 显示模式
旧 2011-12-03   #1
高级会员
级别:6 | 在线时长:109小时 | 升级还需:31小时级别:6 | 在线时长:109小时 | 升级还需:31小时级别:6 | 在线时长:109小时 | 升级还需:31小时
 
Odysseus 的头像
 
注册: 08年04月11日
来自: 盘丝洞
帖子: 311
声望力: 20
声望: 50 Odysseus 初领妙道
现金:29两梁山币
资产:1245两梁山币
致谢数: 0
获感谢文章数:0
获会员感谢数:0
LPC帮助文档—变量类型—函数

作者:jjgod  发表时间:2001年8月4日 10:39

--------------------------------------------------------------------------------

一篇偶翻译的文档,请指正。

LPC帮助文档—变量类型—函数
基本概念:

MudOS 有一个叫做“function”的变量类型,这种变量可以
用于指向一种普遍的函数。你可能已经熟悉传递一个函数到
某个 efun 的主意。拿取,比如说 filter_array这个efun,
它获取一个数祖,然后返回一个其每个元素都在某个函数中
返回非零的数组。习惯上,这个过程是由传递一个物件和一
个函数的名称来完成的。现在呢,它还可以由传递一个函数
型的表达式来完成,这个表达式只是包括了了一个可以稍后
进行计算的函数。
函数指针可以被创建和分派到一个变量,例如:

function f = (: local_func :);

以及被传递到其他的常规情况或者 efuns,就像普通的值一
样:

foo(f); map_array( ({ 1, 2 }), f);

或者在稍后进行计算:

x = evaluate(f, "hi");

当最后一行被运行后,f 指出的这个函数就被呼叫了,而“
hi”则被作为一个实参。这样做将达到与下面同样的效果:

x = local_func("hi");

使用一个函数指针的优势是:如果此后你想运行的是另一个
函数,你可以仅仅改变变量的值就行了。

值得注意的是,如果 evaluate() 被输入一个不是函数的值,
它将原封不动的把这个值再传回来。你可以这样试试:

void set_short(mixed x) { short = x; }
mixed query_short() { return evaluate(short); }

这么做的话,一般的物件可以仅仅是:set_short("任意"),
而特殊些的就可以通过:set_short((: short_func :));
来多样化的改变自己的短描述。

有用的几种函数指针:

上面这个就是一个最简单的函数指针,它们仅仅是指向同一
个物件中的一个本地函数。调用时,参数也可以包括在内,
例如:

string foo(string a, string b)
{
return "(" + a "," + b + ")";
}

void create()
{
function f = (: foo, "left" :);
printf("%s %s\n", evaluate(f), evaluate(f, "right"));
}

将会打印出:(left,0) (left,right)

第二种情况则是仅仅是像 (: efun_name :) 这样的 efun指
针。这种这本地函数指针是很相似的,例如 objects efun
可以获取一个可选的函数,返回所有通过此函数的结果是真
值的物件,因此:objects((: clonep :)) 将会返回一个包
括游戏中所有是复制品的物件。当然,也可以带上参数:

void create()
{
int i;
function f = (: write, "Hello, world!\n" :);

for (i = 0; i < 3; i++) { evaluate(f); }
}

将会打印出:
Hello, world!
Hello, world!
Hello, world!

注意 simul_efun 在和函数指针的关系上是与 efun一样的。

第三种是和 MudOS 通常支持的类似的 call_other函数指针,
格式是:(: object, function :)。如果要使用参数,参数
要被假如一个在函数名前面的数组中。下面是例子:

void create()
{
string *ret;
function f = (: this_player(), "query" :);

ret = map(({ "name", "short", "long" }), f);
write(implode(ret, "\n"));
}

这样将会打印出 this_player()->query("name")、
this_player()->query("short") 和
this_player()->query("long") 的结果。
要使一个函数指针直接呼叫 query("short"),可以使用:

f = (: this_player(), ({ "query", "short" }) :)

下面是其他的一些同样效果的方法提供参考:

// 使用 call_other efun 的 efun 指针
f = (: call_other, this_player(), "query", "short" :)
// 一个表达式的功能,看看下边
f = (: this_player()->query("short") :)

第四种则是表达式函数指针。这是以 (: expression :) 的
形式来使用的。在一个表达式函数指针中,参数可以写成类
似于 $1、$2、$3...这样的形式,例如:

evaluate((: $1 + $2 :), 3, 4) // 返回 7.

在用到 sort_array 时,它将很有用,例如:
top_ten = sort_array(player_list,
(: $2->query_level() - $1->query_level :) )[0..9];


第五种可以称为无名的函数指针:

void create()
{
function f = function(int x)
{
int y;

switch(x)
{
case 1: y = 3;
case 2: y = 5;
}
return y - 2;
};

printf("%i %i %i\n", (*f)(1), (*f)(2), (*f)(3));
}

将会打印出:1 3 -2

注意那个 (*f)(...) 是和 evaluate(f, ...)一样而且被保
留作向后兼容。凡是在一般函数中合法的东西在无名函数中
就是合法的。

函数将在什么时候被运行呢?

有一条原则是:在 efun、本地函数和 simul_efun函数指针
被创建时,作为其参数的函数就被运行了。如果是一个表达
式形式的函数指针,则是要等到此函数指针确实地被使用时
才运行:

// 当此函数指针创建时它就将 destruct 所有是
// this_player() 的人
(: destruct, this_player() :)
// 当此函数运行时才 destruct 所有是 this_player()
// 的人
(: destruct(this_player()) :)

因此,在一个表达式指针中,使用一个本地变量是违法的。
因为等到这个函数指针运行的时候,可能这个变量已经不存
在了。然而,还是有一种解决的方法:

// 和上面的第一个例子一样
(: destruct($(this_player)) :)

$(whatever) 的意思就是立即计算whatever,保持着这个值,
直到这个函数被运行的时候再拿出来用。这还可以使事情做
得更有效率:

map_array(listeners,
(: tell_object($1, $(this_player()->query_name()) + " bows.\n") :));

上面的这个 $(this_player()->query_name()) 只需要被计
算一次,而不是每次消息时都再计算一次。当然增加的那段
也可以预先做好:

map_array(listeners,
(: tell_object($1, $(this_player()->query_name() + " bows.\n")) :));

注意,在这种情况下我们也可以这样做(效率最低的方式):

map_array(listeners,
(: tell_object, this_player()->query_name() + " bows.\n" :));

翻译使用的词汇:
evaluate : 运行、计算
function pointer : 函数指针
argument : 参数
local : 本地
variable : 变量
whatever : 任意

--------------------------------------------------------------------------------
莫愁前路无知己,天下谁人不识君?

原文


作者:jjgod  发表时间:2001年8月4日 10:42

--------------------------------------------------------------------------------

General Concept:
----------------

MudOS has a variable type named 'function'. Variables of this type may
be used to point to a wide variety of functions. You are probably already
familiar with the idea of passing a function to certain efuns. Take, for
example, the filter efun. It takes an array, and returns an array containing
the elements for which a certain function returns non-zero. Traditionally,
this was done by passing an object and a function name. Now, it can also
be done by passing an expression of type 'function' which merely contains
information about a function, which can be evaluated later.

Function pointers can be created and assigned to variables:

function f = (: local_func :);

Passed to other routines or efuns, just like normal values:

foo(f); map_array( ({ 1, 2 }), f);

Or evaluated at a later time:

x = evaluate(f, "hi");

When the last line is run, the function that f points to is called, and "hi"
is passed to it. This will create the same effect as if you had done:

x = local_func("hi");

The advantage of using a function pointer is that if you later want to
use a different function, you can just change the value of the variable.

Note that if evaluate() is passed a value that is not a function, it just
returns the value. So you can do something like:

void set_short(mixed x) { short = x; }
mixed query_short() { return evaluate(short); }

This way, simple objects can simply do: set_short("Whatever"), while objects
that want their shorts to change can do: set_short( (: short_func :) );



Available kinds of function pointers:
-------------------------------------

The simplest function pointers are the ones shown above. These simply
point to a local function in the same object, and are made using
(: function_name :). Arguments can also be included; for example:

string foo(string a, string b) {
return "(" + a "," + b + ")";
}

void create() {
function f = (: foo, "left" :);

printf( "%s %s\n", evaluate(f), evaluate(f, "right") );
}

Will print: (left,0) (left,right)


The second kind is the efun pointer, which is just (: efun_name :). This
is very similar to the local function pointer. For example, the objects()
efun takes a optional function, and returns all objects for which the
function is true, so:

objects( (: clonep :) )

will return an array of all the objects in the game which are clones.
Arguments can also be used:

void create() {
int i;
function f = (: write, "Hello, world!\n" :);

for (i=0; i<3; i++) { evaluate(f); }
}

Will print:
Hello, world!
Hello, world!
Hello, world!

Note that simul_efuns work exactly like efuns with respect to function
pointers.



The third type is the call_other function pointer, which is similar to the
type of function pointer MudOS used to support. The form is
(: object, function :). If arguments are to be used, the should be added
to an array along with the function name. Here are some examples:

void create()
{
string *ret;
function f = (: this_player(), "query" :);

ret = map( ({ "name", "short", "long" }), f );
write(implode(ret, "\n"));
}

This would print the results of this_player()->query("name"),
this_player()->query("short"), and this_player()->query("long").
To make a function pointer that calls query("short") directly, use:

f = (: this_player(), ({ "query", "short" }) :)

For reference, here are some other ways of doing the same thing:

f = (: call_other, this_player(), "query", "short" :) // a efun pointer using
// the call_other efun
f = (: this_player()->query("short") :) // an expression functional; see
// below.



The fourth type is the expression function pointer. It is made using
(: expression :). Within an expression function pointer, the arguments
to it can be refered to as $1, $2, $3 ..., for example:

evaluate( (: $1 + $2 :), 3, 4) // returns 7.

This can be very useful for using sort_array, for example:

top_ten = sort_array( player_list,
(: $2->query_level() - $1->query_level :) )[0..9];


The fifth type is an anonymous function:

void create() {
function f = function(int x) {
int y;

switch(x) {
case 1: y = 3;
case 2: y = 5;
}
return y - 2;
};

printf("%i %i %i\n", (*f)(1), (*f)(2), (*f)(3));
}

would print: 1 3 -2

Note that (*f)(...) is the same as evaluate(f, ...) and is retained for
backwards compatibility. Anything that is legal in a normal function is
legal in an anonymous function.


When are things evaluated?
--------------------------

The rule is that arguments included in the creation of efun, local function,
and simul_efun function pointers are evaluated when the function pointer is
made. For expression and functional function pointers, nothing is evaluated
until the function pointer is actually used:

(: destruct, this_player() :) // When it is *evaluated*, it will destruct
// whoever "this_player()" was when it
// was *made*
(: destruct(this_player()) :) // destructs whoever is "this_player()"
// when the function is *evaluated*

For this reason, it is illegal to use a local variable in an expression
pointer, since the local variable may no longer exist when the function
pointer is evaluated. However, there is a way around it:

(: destruct( $(this_player) ) :) // Same as the first example above

$(whatever) means 'evaluate whatever, and hold it's value, inserting it
when the function is evaluated'. It also can be used to make things more
efficient:

map_array(listeners,
(: tell_object($1, $(this_player()->query_name()) + " bows.\n") :) );

only does one call_other, instead of one for every message. The string
addition could also be done before hand:

map_array(listeners,
(: tell_object($1, $(this_player()->query_name() + " bows.\n")) :) );

Notice, in this case we could also do:

map_array(listeners,
(: tell_object, this_player()->query_name() + " bows.\n" :) );
Odysseus 当前离线  
回复时引用此帖

发表新主题 回复

添加到书签


发帖规则
不可以发表主师
不可以回复帖子
不可以上传附件
不可以编辑自己的帖子

论坛启用 vB 代码
论坛启用 表情图标
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用


相似的主题
主题 主题作者 论坛 回复 最后发表
zmud内键常用函数集 Odysseus 『 机器人制作及下载 』 3 2016-03-19 13:50
zmud函数入门 wolf_iori 『 机器人制作及下载 』 6 2011-11-14 01:25
【马帮】 机器讲座(一) zmud内建函数 argus 『 帮派传说 』 12 2010-09-02 09:16
zmud函数入门 wolf_iori 『 机器人制作及下载 』 3 2008-05-11 19:41
zmud函数入门1 wolf_iori 『 机器人制作及下载 』 4 2008-05-11 19:38


所有时间均为格林尼治时间 +9, 现在的时间是 09:11.


Powered by SPLS
版权所有 2001-2023 水泊梁山
皖ICP备05012024号

站长 fengyue

Content Relevant URLs by vBSEO 3.6.1