系统函数eval的完整使用语法是:
result:= eval("expression"[, "decimal", "separator"])
该函数的作用是计算由参数expression指定的表达式,并将结果赋予变量result。可选参数decimal用于指定在expression中作为小数点的字符(默认的小数点是 . ),separator用于指定在expression中作为参数分隔符的字符(默认的分隔符是 , )。例如,eval函数可用于执行复杂的数学运算:
result:=eval("3*9-6*8**2") --result的值是-357
但是eval函数的真正作用是在程序运行期间动态构造并执行表达式。假设有24个显示设计图标graphic0~graphic23,分别包含了用于一天中每个小时的图像。如果希望在程序开始运行时能够自动根据当前时间显示对应的设计图标,那么通过以下1行代码就可以达到目的:
eval( "displayicon(@/"graphic"^hour^"/")" )
如果现在是12:00,则上述代码实际上等价于:
eval( "displayicon(@/"graphic12/")")
即
displayicon(@"graphic12")
函数eval()不仅可以在程序运行期间动态构造设计图标名称,还可以灵活地选择变量名(当然这些设计图标和变量事先要存在于程序中)。假设程序中存在变量choice1~coice5,并希望根据条件变量condition的值决定返回哪一个变量的值,通常可以采取以下方式编程:
if condition=1 then result:= choice1
else if condition=2 then result:= choice2
else if condition=3 then result:= choice3
else if condition=4 then result:= choice4
else if condition=5 then result:= choice5
通过函数eval(),可以将上述代码精简为1行:
result:= eval( "choice" ^ condition )
当变量condition的值为4时,eval语句就是:
result:=eval("choice"^4)
等价于:
result:=eval("choice4")
等价于:
result:=eval(choice4)
等价于:
result:=choice4
许多设计图标或对象的属性在程序运行期间需要通过条件进行控制,但是条件判断过程通常比较复杂(类似于上述条件语句),不可能直接在属性检查器中使用。通过eval()函数,将多行语句精简为1行,就可以直接将复杂的条件判断过程保存到各种属性文本框中。
本书3.2.2小节中介绍过一个根据屏幕分辨率选择动态地不同背景图像的范例,在该范例中要求所有图像文件都要精确地命名。如果利用eval函数,就可以方便地通过变量名引用不同的图像文件,首先将不同的图像文件名保存在以下变量之中(每个变量存储对应于一种屏幕分辨的图像文件名和路径信息,但此时图像可以根据用户的喜好随意命名):
graphic_12801024:=filelocation^"largest.jpg"
graphic_1152864:=filelocation^"large.jpg"
graphic_1024768:=filelocation^"normal.jpg"
graphic_800600:=filelocation^"small.jpg"
graphic_640480:=filelocation^"smallest.jpg"
然后在图像对象属性对话框中的file文本框内输入表达式:
=eval("graphic_"^screenwidth^screenheight)
就可以达到根据屏幕分辨率选择不同背景图像的目的。
chapter03文件夹下的范例程序evalbackground.a7p演示了利用eval函数选择背景图像的过程。
可以看出,eval()是一个功能强大的aws表达式执行器,可以执行任意aws表达式甚至模拟程序语句。
eval()在应用上存在一个限制,那就是在表达式中不能包含赋值运算符。函数evalassign()弥补了这一点,它的使用方式与eval()相同,但是在表达式中可以使用赋值运算符,从而能够实现更为复杂的过程。
假设程序中存在变量result1~ result5,并希望根据条件变量condition的值将变量choice的值保存在一个对应的变量中,通常是采取以下方式编程:
ifcondition=1 then result1:= choice
else if condition=2 then result2:= choice
else if condition=3 then result3:= choice
else if condition=4 then result4:= choice
else if condition=4 then result5:= choice
通过函数evalassign(),可以将上述代码精简为1行:
evalassign( "result" ^ condition ^ ":= choice" )
当变量condition的值为4时,evalassign语句就是:
evalassign( "result4" ^ ":= choice" )
等价于:
evalassign( "result4:= choice" )
等价于:
evalassign( result4:= choice )
等价于:
result4:= choice
如果需要在程序运行期间根据用户的选择(是或否)动态设置多个显示设计图标(例如graphic0~graphic23)的movable状态,通常需要编写以下代码:
movable@"graphic0":=choice
movable@"graphic1":=choice
……
movable@"graphic22":=choice
movable@"graphic23":=choice
这种做法效率十分低,通过函数evalassign(),可以将上述24行代码精简为3行:
repeat with i:=0 to 23
evalassign("movable@/"graphic"^ i ^ "/":=choice")
end repeat
由于eval()和evalassign()都可以执行包含在字符串中的表达式,因此也可以将表达式集中放置在文本文件中,在程序运行的过程中读取这些表达式并加以执行。例如可以将范例程序evalbackground.a7p中对graphic_系列变量命名的赋值语句都存储在文本文件evalassign.txt中,在程序将文件内容读取到字符串变量中之后,通过一个循环过程逐行执行这些程序语句:
evalstring:=readextfile(filelocation^"evalassign.txt")
repeat with i:=1 to linecount(evalstring)
evalassign(getline(evalstring,i,i))
end repeat
对应的范例程序是chapter03文件夹下的evalassignbackground.a7p。
如果以后需要使用其他的图像,无需对程序做出任何修改,直接修改文本文件evalassign.txt中的图像文件名称就可以达到目的,这种简单的维护工作甚至可以交给用户自己完成。如果设计人员更加注重代码的安全性,也可以利用本书3.5.2小节中介绍过的encode()和decode()脚本函数,对存储在程序外部的aws代码进行加密和解密。加密后的aws代码可以通过以下方式执行解密:
evalstring:= callscripticon(@"decode", readextfile(filelocation^"evalassign.txt"))
repeat with i:=1 to linecount(evalstring)
evalassign(getline(evalstring,i,i))
end repeat
authorware 7.0还提供另外两个eval类的函数:evaljs()和evaljsfile()。这两个函数用于构造和执行js代码,从而使同一程序中的aws过程与js过程可以更好地相互沟通。
假设程序中已经定义了两个js变量:
var i=10, j=0;
则在aws中就可以通过evaljs()访问这两个变量:
i:= evaljs( "i" ) --将js变量i的值传递到aws变量i之中
evaljs( "++i ; ++j") --在aws中直接修改js变量的值
在一个字符串中通过"/r"可以包含多行代码,以下是一个简单的js循环过程:
for ( ; i<100; ) {
j=j+10;
i=i+10
}
可以通过以下方式直接在aws中执行该循环过程:
evaljs("for ( ; i<100; ) { /r j=j+10;/r i=i+10 /r}")
也可以将这一循环过程保存在文本文件js.txt中,然后通过以下方式直接执行该文件中包含的js代码:
evaljsfile( "js.txt")
在authorware中,月份名和星期名通过系统变量monthname和dayname以英文表示(例如"september"、"monday"),但是经常会遇到需要以中文显示日期的情况,例如“九月29日星期一”。下面是一个js函数chinesedate()的定义过程,通过date对象和array对象实现计算并返回当前中文日期的功能。
function chinesedate(){
var currentdate=new date(); //创建日期对象
var weekday=new array("星期日","星期一","星期二",
"星期三","星期四","星期五","星期六"); //创建星期名数组对象
var monthname=new array("一月","二月","三月","四月","五月",
"六月","七月","八月","九月","十月","十一月","十二月"); //创建月份名数组对象
var result;
//通过日期对象get系列的方法获取当前具体日期,并以下标方式获取数组中的对应
//元素
result=currentdate.getfullyear()+"年"+monthname[currentdate.getmonth()]+
currentdate.getdate()+"日, "+weekday[currentdate.getday()];
return result;
}
将上述代码保存在文本文件jscode.txt中之后,就可以在aws中通过以下两种方式获取以中文表示的当前日期:
evaljsfile(filelocation^"jscode.txt") //完成函数声明
chinesedate:=evaljs("chinesedate()") //调用js函数
或者
jscode:=readextfile(filelocation^"jscode.txt")
evaljs(jscode) //完成函数声明
chinesedate:=evaljs("chinesedate()") //调用js函数
如果以第2种方式对文本文件中的js代码进行调用,也可以利用脚本函数encode和decode对js代码进行加密和解密。
对应的范例程序是chapter03文件夹下的jsexample.a7p,在同一文件夹下也提供了文本文件jscode.txt。
当编写js代码时,单击【运算】窗口的【插入片段】按钮,会打开insert javascript snippet对话框(如图3-53所示),其中以函数方式提供了大量js代码片段,从进制转换到数组冒泡排序算法应有尽有。这些函数可以看成是对authorware系统函数的补充,除了可以在使用js编程时直接调用之外,在利用aws编程时也可以通过函数evaljs()对这些js函数进行调用。例如以下aws代码:
result:=evaljs("areaofcircle(10)")
图3-53 js代码片段
就计算出半径为10的圆的面积值。在此之前,必须将定义函数areaofcircle()的js代码片段粘贴到js【运算】设计图标之中,完成对函数的声明。否则会遇到以下错误提示信息:
"referenceerror: areaofcircle is not defined"
如果eval类函数(包括eval,evalassign,evaljs和evaljsfile)在执行时发现aws表达式或js代码中存在有语法错误,就会将错误代号和错误信息存储在系统变量evalstatus和evalmessage之中。经常检查这两个系统变量的值,有助于快速排除代码中存在的问题。
新闻热点
疑难解答