系統(tǒng)函數(shù)eval的完整使用語法是:
result:= eval("expression"[, "decimal", "separator"])
該函數(shù)的作用是計算由參數(shù)expression指定的表達式,并將結(jié)果賦予變量result。可選參數(shù)decimal用于指定在expression中作為小數(shù)點的字符(默認的小數(shù)點是 . ),separator用于指定在expression中作為參數(shù)分隔符的字符(默認的分隔符是 , )。例如,eval函數(shù)可用于執(zhí)行復雜的數(shù)學運算:
result:=eval("3*9-6*8**2") --result的值是-357
但是eval函數(shù)的真正作用是在程序運行期間動態(tài)構(gòu)造并執(zhí)行表達式。假設(shè)有24個顯示設(shè)計圖標graphic0~graphic23,分別包含了用于一天中每個小時的圖像。如果希望在程序開始運行時能夠自動根據(jù)當前時間顯示對應(yīng)的設(shè)計圖標,那么通過以下1行代碼就可以達到目的:
eval( "displayicon(@/"graphic"^hour^"/")" )
如果現(xiàn)在是12:00,則上述代碼實際上等價于:
eval( "displayicon(@/"graphic12/")")
即
displayicon(@"graphic12")
函數(shù)eval()不僅可以在程序運行期間動態(tài)構(gòu)造設(shè)計圖標名稱,還可以靈活地選擇變量名(當然這些設(shè)計圖標和變量事先要存在于程序中)。假設(shè)程序中存在變量choice1~coice5,并希望根據(jù)條件變量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
通過函數(shù)eval(),可以將上述代碼精簡為1行:
result:= eval( "choice" ^ condition )
當變量condition的值為4時,eval語句就是:
result:=eval("choice"^4)
等價于:
result:=eval("choice4")
等價于:
result:=eval(choice4)
等價于:
result:=choice4
許多設(shè)計圖標或?qū)ο蟮膶傩栽诔绦蜻\行期間需要通過條件進行控制,但是條件判斷過程通常比較復雜(類似于上述條件語句),不可能直接在屬性檢查器中使用。通過eval()函數(shù),將多行語句精簡為1行,就可以直接將復雜的條件判斷過程保存到各種屬性文本框中。
本書3.2.2小節(jié)中介紹過一個根據(jù)屏幕分辨率選擇動態(tài)地不同背景圖像的范例,在該范例中要求所有圖像文件都要精確地命名。如果利用eval函數(shù),就可以方便地通過變量名引用不同的圖像文件,首先將不同的圖像文件名保存在以下變量之中(每個變量存儲對應(yīng)于一種屏幕分辨的圖像文件名和路徑信息,但此時圖像可以根據(jù)用戶的喜好隨意命名):
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文本框內(nèi)輸入表達式:
=eval("graphic_"^screenwidth^screenheight)
就可以達到根據(jù)屏幕分辨率選擇不同背景圖像的目的。
chapter03文件夾下的范例程序evalbackground.a7p演示了利用eval函數(shù)選擇背景圖像的過程。
可以看出,eval()是一個功能強大的aws表達式執(zhí)行器,可以執(zhí)行任意aws表達式甚至模擬程序語句。
eval()在應(yīng)用上存在一個限制,那就是在表達式中不能包含賦值運算符。函數(shù)evalassign()彌補了這一點,它的使用方式與eval()相同,但是在表達式中可以使用賦值運算符,從而能夠?qū)崿F(xiàn)更為復雜的過程。
假設(shè)程序中存在變量result1~ result5,并希望根據(jù)條件變量condition的值將變量choice的值保存在一個對應(yīng)的變量中,通常是采取以下方式編程:
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
通過函數(shù)evalassign(),可以將上述代碼精簡為1行:
evalassign( "result" ^ condition ^ ":= choice" )
當變量condition的值為4時,evalassign語句就是:
evalassign( "result4" ^ ":= choice" )
等價于:
evalassign( "result4:= choice" )
等價于:
evalassign( result4:= choice )
等價于:
result4:= choice
如果需要在程序運行期間根據(jù)用戶的選擇(是或否)動態(tài)設(shè)置多個顯示設(shè)計圖標(例如graphic0~graphic23)的movable狀態(tài),通常需要編寫以下代碼:
movable@"graphic0":=choice
movable@"graphic1":=choice
……
movable@"graphic22":=choice
movable@"graphic23":=choice
這種做法效率十分低,通過函數(shù)evalassign(),可以將上述24行代碼精簡為3行:
repeat with i:=0 to 23
evalassign("movable@/"graphic"^ i ^ "/":=choice")
end repeat
由于eval()和evalassign()都可以執(zhí)行包含在字符串中的表達式,因此也可以將表達式集中放置在文本文件中,在程序運行的過程中讀取這些表達式并加以執(zhí)行。例如可以將范例程序evalbackground.a7p中對graphic_系列變量命名的賦值語句都存儲在文本文件evalassign.txt中,在程序?qū)⑽募?nèi)容讀取到字符串變量中之后,通過一個循環(huán)過程逐行執(zhí)行這些程序語句:
evalstring:=readextfile(filelocation^"evalassign.txt")
repeat with i:=1 to linecount(evalstring)
evalassign(getline(evalstring,i,i))
end repeat
對應(yīng)的范例程序是chapter03文件夾下的evalassignbackground.a7p。
如果以后需要使用其他的圖像,無需對程序做出任何修改,直接修改文本文件evalassign.txt中的圖像文件名稱就可以達到目的,這種簡單的維護工作甚至可以交給用戶自己完成。如果設(shè)計人員更加注重代碼的安全性,也可以利用本書3.5.2小節(jié)中介紹過的encode()和decode()腳本函數(shù),對存儲在程序外部的aws代碼進行加密和解密。加密后的aws代碼可以通過以下方式執(zhí)行解密:
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類的函數(shù):evaljs()和evaljsfile()。這兩個函數(shù)用于構(gòu)造和執(zhí)行js代碼,從而使同一程序中的aws過程與js過程可以更好地相互溝通。
假設(shè)程序中已經(jīng)定義了兩個js變量:
var i=10, j=0;
則在aws中就可以通過evaljs()訪問這兩個變量:
i:= evaljs( "i" ) --將js變量i的值傳遞到aws變量i之中
evaljs( "++i ; ++j") --在aws中直接修改js變量的值
在一個字符串中通過"/r"可以包含多行代碼,以下是一個簡單的js循環(huán)過程:
for ( ; i<100; ) {
j=j+10;
i=i+10
}
可以通過以下方式直接在aws中執(zhí)行該循環(huán)過程:
evaljs("for ( ; i<100; ) { /r j=j+10;/r i=i+10 /r}")
也可以將這一循環(huán)過程保存在文本文件js.txt中,然后通過以下方式直接執(zhí)行該文件中包含的js代碼:
evaljsfile( "js.txt")
在authorware中,月份名和星期名通過系統(tǒng)變量monthname和dayname以英文表示(例如"september"、"monday"),但是經(jīng)常會遇到需要以中文顯示日期的情況,例如“九月29日星期一”。下面是一個js函數(shù)chinesedate()的定義過程,通過date對象和array對象實現(xiàn)計算并返回當前中文日期的功能。
function chinesedate(){
var currentdate=new date(); //創(chuàng)建日期對象
var weekday=new array("星期日","星期一","星期二",
"星期三","星期四","星期五","星期六"); //創(chuàng)建星期名數(shù)組對象
var monthname=new array("一月","二月","三月","四月","五月",
"六月","七月","八月","九月","十月","十一月","十二月"); //創(chuàng)建月份名數(shù)組對象
var result;
//通過日期對象get系列的方法獲取當前具體日期,并以下標方式獲取數(shù)組中的對應(yīng)
//元素
result=currentdate.getfullyear()+"年"+monthname[currentdate.getmonth()]+
currentdate.getdate()+"日, "+weekday[currentdate.getday()];
return result;
}
將上述代碼保存在文本文件jscode.txt中之后,就可以在aws中通過以下兩種方式獲取以中文表示的當前日期:
evaljsfile(filelocation^"jscode.txt") //完成函數(shù)聲明
chinesedate:=evaljs("chinesedate()") //調(diào)用js函數(shù)
或者
jscode:=readextfile(filelocation^"jscode.txt")
evaljs(jscode) //完成函數(shù)聲明
chinesedate:=evaljs("chinesedate()") //調(diào)用js函數(shù)
如果以第2種方式對文本文件中的js代碼進行調(diào)用,也可以利用腳本函數(shù)encode和decode對js代碼進行加密和解密。
對應(yīng)的范例程序是chapter03文件夾下的jsexample.a7p,在同一文件夾下也提供了文本文件jscode.txt。
當編寫js代碼時,單擊【運算】窗口的【插入片段】按鈕,會打開insert javascript snippet對話框(如圖3-53所示),其中以函數(shù)方式提供了大量js代碼片段,從進制轉(zhuǎn)換到數(shù)組冒泡排序算法應(yīng)有盡有。這些函數(shù)可以看成是對authorware系統(tǒng)函數(shù)的補充,除了可以在使用js編程時直接調(diào)用之外,在利用aws編程時也可以通過函數(shù)evaljs()對這些js函數(shù)進行調(diào)用。例如以下aws代碼:
result:=evaljs("areaofcircle(10)")
圖3-53 js代碼片段
就計算出半徑為10的圓的面積值。在此之前,必須將定義函數(shù)areaofcircle()的js代碼片段粘貼到j(luò)s【運算】設(shè)計圖標之中,完成對函數(shù)的聲明。否則會遇到以下錯誤提示信息:
"referenceerror: areaofcircle is not defined"
如果eval類函數(shù)(包括eval,evalassign,evaljs和evaljsfile)在執(zhí)行時發(fā)現(xiàn)aws表達式或js代碼中存在有語法錯誤,就會將錯誤代號和錯誤信息存儲在系統(tǒng)變量evalstatus和evalmessage之中。經(jīng)常檢查這兩個系統(tǒng)變量的值,有助于快速排除代碼中存在的問題。
新聞熱點
疑難解答