系統函數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之中。經常檢查這兩個系統變量的值,有助于快速排除代碼中存在的問題。
新聞熱點
疑難解答