Eval
佇一寡程序語言內底,eval是一字共符串當做表達式來執行倒轉來一个結果的函數;佇咧另外一寡內底,伊執行加行的代碼就好親像𪜶予包括佇咧內底,毋是包括 ` eval ` 的這途。` eval ` 的輸入無一定字符串;支持句法抽象的語言(如 Lisp)中,` eval ` 的輸入將會由抽象句法形式組成。
安全風險
當使用 ` eval ` 數據無可信任的來源的時陣,一定愛的特別的注意。譬論講,準講 ` get _ data ( ) ` 函數對 Internet 得著數據,這乎 Python 代碼就是無安全的 :
一个攻擊者會當予字符合 ` " session . update ( authenticated=True ) " ` 做數據提供予這个程序,伊會更新 ` session ` 字典以設定一个通過身份驗證的鍵為 True。為著補救這點,所有這个將會予 ` eval ` 咧用的數據著愛予人轉義,抑是講必須愛運行無法度訪問可能有害的函數的環境下。
使用
著 ` eval ` 的調用有當時仔無經驗的程式設計師佇咧所有種類的事物頂懸使用。佇足濟數情形之下,有更加靈活佇咧袂造成解析代碼時速度損失的會當代的方法。
譬論講,` eval ` 有時予人用佇一个簡單的郵件合併設施上,就親像如下 PHP 代碼所示 :
就算講這確實有用,伊可能致使一寡安全的問題 ( 見安全風險 ),而且比其他的解決方案慢誠濟。更加緊更加安全的解決方案會當是改變最後一行為 ` print $ template ; ` 佮徙掉前一行的單引號,抑是使用 ` printf `。
` eval ` 有當時仔需要對數學表達式求值的應用中,若電子試算表。這比寫一个表達式解析器簡單加了,猶毋過發現或者是寫出一个表達式解析器通常是一个閣較好的選擇。除了會當修復的安全風險,使用這款語言的求值特性通常真有可能閣較慢,嘛無遐爾仔懸的彼可定製性。
凡勢 ` eval ` 的最佳使用是佇咧 bootstrapping 一个新的語言的過程當中 ( 就親像 Lisp 彼款的 ),佮作為語言的允准用戶咧受控制的環境下運途𪜶家己的程序的指導程序。
出於表達式求值的目的,eval 相比表達式解析器的主要優勢佇咧講,佇咧 ` eval ` 受支持的絕大多數編程環境下,這个表達式可能是任意的複雜,而且可能包括對使用者所寫的無可能被解析器的創造者所預先知影的函數的調用。這个能力允准你用一个你會使揤需要增強的函數庫有效的增加 eval ( ) ia̋n-jín,毋免繼續維持一个表達式解析器。毋過,若是你無需要遮終極的靈活性,表達式解析器遠遠閣較有效佮輕量。
實施
佇直譯語言內底,` eval ` 差不多總是予正常的代碼使用仝款解析器實現。佇咧編譯語言當中,用佇咧編譯程序的編譯器可能去予人騙入去 ` eval ` 的程序當中;分開的解說器有時也予人使用,就算講這可能會致使重複代碼。
程序語言
JavaScript
佇咧 JavaScript 中,` eval ` 是某一種介於表達式求值器佮語句執行器的混合體。伊轉去最後一个被求值的表達式的值 ( 佇咧 JavaScript 中,所有的語句攏是表達式 ),也允准最後一个分號省略。
如下示例是一个表達式求值器 :
如下示比如講是一个語句執行器。
JavaScript 的 ` eval ` 的一个應用是解破 JSON 文本,凡勢做為 Ajax 框架內底的一部份。毋過,現代的瀏覽器提供 ` JSON . parse ` 作為這个任務的一个更加安全的替代品。
ActionScript
佇咧 ActionScript ( Flash 的程式語言 ) 中,` eval ` 袂當用於計算任意的表達式。根據 Flash 八文檔,伊的使用干焦限制代表「變量名,屬性,對象抑是欲檢索的影片鉸輯。這个參數會當是一个字符串或者是對對象實例的一个直接引用」的表達式。
ActionScript 三無支持 eval。
ActionScript 三 Eval Library 和 D . eval API 是進行的用以佇咧 ActionScript 三中創建 ` eval ` 的遮的價數的開發項目。
Lisp
Lisp 是首先使用 ` eval ` 函數的語言。事實上,著 ` eval ` 函數的定義致使著該語言解說器的頭先的實施。佇咧 ` eval ` 函數予人定義進前,Lisp 函數干焦手動予人編譯做彙編語言語句。毋過,一旦 ` eval ` 函數被手動編譯,伊隨後就予人用過組做頭一个 Lisp 解說器的基礎的 Read–eval–print 循環的一部份。
Lisp ` eval ` 函數的尾仔版本嘛被做編譯器實施。
Lisp 中的 ` eval ` 函數向望一个形式做為一个參數被求值和執行。予定形式的倒轉去值將會是著 ` eval ` 的調用的倒轉值。
這是一个示例 Lisp 代碼 :
Lisp 眾人知的非常的靈活,` eval ` 函數嘛是。比如講,為著對字符捾的內容求值,這字符攕頭先著愛使用 ` read-from-string ` 函數轉化做 Lisp 格式,隨後這个結果的格式將會被傳予 ` eval ` :
主要造成透濫的一點仔是這个問題,即佇佗一个上下文中這个形式中的符號會被求值。咧講示例中,` form 一 ` 包含符號 +。對該符號的求值必然會產生一个用於加法的函數之使應該示例像按呢的工課。因而 Lisp 某一寡方言允准為 ` eval ` 傳入一个額外的參數以指定求值的上下文 ( 類似 Python 的 ` eval ` 函數的可選參數-如下所示 )。一用 Lisp 的 Scheme 方言 ( R 五 RS 佮以後版本 ) 寫出的示例 :
Perl
佇咧 Perl 中,` eval ` 函數是某一種介於表達式求值器佮語句執行器的混合體。伊轉去最後一个被求值的表達式的結果 ( 佇咧 Perl 編程當中,所有的語句攏是表達式按呢 ),而且允准最後一个分號省略。
一个表達式求值器的示例 :
一个語句執行器的示例 :
( 注意字符串的引號。注意單引號佇頂述示例當中被用來引用字符串。你若使用的是雙引號,伊將會佇共這字符合鬥起來 ` eval ` 進前共變量的值插入字符串,破壞去矣 ` eval ` 原本的目的,而且嘛有佇咧期值的狀況之下,有可能引起句法錯誤。)
Perl 嘛有 ` eval ` _ 塊 _,作為伊的異常處理的機制。這佮頂懸講嘿 ` eval ` 傳入字符串的用法無仝,在於 ` eval ` 內的代碼咧編譯的時陣毋是咧運行的時陣解說,所以伊毋是本文中使用的 ` eval ` 的含義。
PHP
佇咧 PHP 中,` eval ` 執行佇咧一字符串中的代碼差不多就像伊予囥入去矣文件內底,毋是著 ` eval ( ) ` 調用仝款。唯一的區別是錯誤予人報導為來自對 ` eval ( ) ` 的一个調用,共回倒轉來語句成做函數的結果。