กลับไปหน้าบทความ

อ่าน 8 นาที

ประเมิน

ในบาง ภาษาโปรแกรม ` value` eval ซึ่งย่อมาจาก `evaluate` เป็น ฟังก์ชัน ที่ประเมินสตริงเสมือนเป็น นิพจน์ ในภาษานั้น และส่งคืน ผลลัพธ์ ในขณะที่บางภาษา `value`...

ประเมิน

ในบางภาษาโปรแกรม ` value` evalซึ่งย่อมาจาก`evaluate`เป็นฟังก์ชันที่ประเมินสตริงเสมือนเป็นนิพจน์ในภาษานั้น และส่งคืนผลลัพธ์ในขณะที่บางภาษา `value` จะประมวลผลโค้ดหลายบรรทัดเสมือนว่าได้รวมโค้ดเหล่านั้นเข้าไปแล้ว แทนที่จะเป็นบรรทัดที่มี `value` evalอินพุตของ `value` evalไม่จำเป็นต้องเป็นสตริงเสมอไป อาจเป็นโครงสร้างของโค้ด เช่นต้นไม้ไวยากรณ์นามธรรม (เช่น ฟอร์มของ Lisp ) หรือชนิดข้อมูลพิเศษ เช่นcode`string` (เช่นใน Python) คำสั่งที่เทียบเท่ากับ ` value`คือ`exec`ซึ่งประมวลผลสตริง (หรือโค้ดในรูปแบบอื่น) เสมือนเป็นคำสั่ง `value` ในบางภาษา เช่น Python ทั้งสองอย่างมีอยู่ ในขณะที่ภาษาอื่นๆ จะมีเพียงอย่างใดอย่างevalหนึ่งexecเท่านั้น

ความเสี่ยงด้านความปลอดภัย

การใช้งานevalข้อมูลจากแหล่งที่ไม่น่าเชื่อถืออาจก่อให้เกิดช่องโหว่ด้านความปลอดภัย ตัวอย่างเช่น หากget_data()ฟังก์ชันดึงข้อมูลจากอินเทอร์เน็ต โค้ด Python นี้ จะไม่ปลอดภัย:

เซสชัน[ "authenticated" ] = False ข้อมูล= get_data () foo = eval ( data )

ผู้โจมตี อาจป้อน สตริงเป็นข้อมูลให้กับโปรแกรม"session.update(authenticated=True)"ซึ่งจะอัปเดตsessionพจนานุกรมเพื่อตั้งค่าคีย์ที่ตรวจสอบสิทธิ์เป็น True เพื่อแก้ไขปัญหานี้ ข้อมูลทั้งหมดที่จะใช้กับโปรแกรมevalจะต้องถูกเข้ารหัส หรือต้องเรียกใช้โปรแกรมโดยไม่สามารถเข้าถึงฟังก์ชันที่อาจเป็นอันตรายได้

การดำเนินการ

ในภาษาที่ใช้การตีความ (interpreted languages ) evalฟังก์ชันนี้มักจะถูกใช้งานโดยตัวตีความ (interpreter) เดียวกันกับโค้ดปกติ ส่วนในภาษาที่ใช้การคอมไพล์ (compiled languages ) คอมไพเลอร์ตัวเดียวกันกับที่ใช้คอมไพล์โปรแกรมอาจถูกฝังอยู่ในโปรแกรมที่ใช้evalฟังก์ชันนี้ บางครั้งอาจใช้ตัวตีความแยกต่างหาก แต่จะทำให้เกิด การทำ ซ้ำ โค้ด

ภาษาโปรแกรม

อีซีเอ็มเอสคริปต์

โค้ด JavaScript

ในJavaScriptนั้นevalเป็นเหมือนลูกผสมระหว่างตัวประเมินนิพจน์และตัวดำเนินการคำสั่ง โดยจะส่งคืนผลลัพธ์ของนิพจน์สุดท้ายที่ถูกประเมิน

ตัวอย่างการใช้เป็นตัวประเมินนิพจน์:

foo = 2 ; alert ( eval ( 'foo + 2' ));

ตัวอย่างการใช้เป็นตัวดำเนินการคำสั่ง:

foo = 2 ; eval ( 'foo = foo + 2;alert(foo);' );

หนึ่งในประโยชน์ของ JavaScript evalคือการแยกวิเคราะห์ ข้อความ JSONซึ่งอาจเป็นส่วนหนึ่งของ เฟรมเวิร์ก Ajaxอย่างไรก็ตาม เบราว์เซอร์สมัยใหม่มีJSON.parseทางเลือกที่ปลอดภัยกว่าสำหรับงานนี้

แอ็กชันสคริปต์

ในActionScript (ภาษาการเขียนโปรแกรมของ Flash) evalไม่สามารถใช้ประเมินนิพจน์ใดๆ ได้ ตามเอกสาร Flash 8 การใช้งานถูกจำกัดไว้เฉพาะนิพจน์ที่แสดงถึง "ชื่อของตัวแปร คุณสมบัติ วัตถุ หรือคลิปภาพยนตร์ที่จะเรียกใช้ พารามิเตอร์นี้สามารถเป็นสตริงหรือการอ้างอิงโดยตรงไปยังอินสแตนซ์ของวัตถุ" [ 1 ]

ActionScript 3 ไม่รองรับคำสั่ง eval

ไลบรารี ActionScript 3 Eval [ 2 ]และ API D.eval [ 3 ]เป็นโครงการพัฒนาเพื่อสร้างสิ่งที่เทียบเท่าevalใน ActionScript 3 ทั้งสองโครงการได้สิ้นสุดลงแล้ว เนื่องจากAdobe Flash Playerหมดอายุการใช้งานแล้ว

ลิสป์

Lispเป็นภาษาแรกที่ใช้evalฟังก์ชันในปี 1958 อันที่จริง การกำหนดevalฟังก์ชันนำไปสู่การใช้งานตัวแปลภาษาเป็นครั้งแรก[ 4 ] ก่อนที่evalจะมีการกำหนดฟังก์ชัน ฟังก์ชันของ Lisp จะถูกคอมไพล์ด้วยตนเองเป็น คำสั่ง ภาษาแอสเซมบลีอย่างไรก็ตาม เมื่อevalฟังก์ชันถูกคอมไพล์ด้วยตนเองแล้ว ก็จะถูกใช้เป็นส่วนหนึ่งของลูปอ่าน-ประเมิน-พิมพ์ แบบง่ายๆ ซึ่งเป็นพื้นฐานของตัวแปลภาษา Lisp ตัวแรก

ฟังก์ชัน Lisp เวอร์ชันต่อมาevalได้ถูกนำไปใช้ในรูปแบบของคอมไพเลอร์ด้วยเช่นกัน

ฟังก์ชันevalในภาษา Lisp คาดหวังให้ประเมินรูปแบบหนึ่งเป็นอาร์กิวเมนต์ ค่าที่ได้จากรูปแบบที่กำหนดจะเป็นค่าที่ส่งคืนจากการเรียกใช้ฟังก์ชันevalนั้น

นี่คือตัวอย่างโค้ด Lisp:

; รูปแบบที่เรียกใช้ฟังก์ชัน + โดยมี 1, 2 และ 3 เป็นอาร์กิวเมนต์; มันจะคืนค่า 6 ( + 1 2 3 ) ; ใน Lisp รูปแบบใดๆ ก็ตามมีไว้สำหรับการประเมินค่า ดังนั้น; การเรียกใช้ฟังก์ชัน + จึงเกิดขึ้น; เราสามารถป้องกันไม่ให้ Lisp ทำการประเมินค่า; ของรูปแบบได้โดยการใส่เครื่องหมาย "" นำหน้า เช่น: ( setq form1 ' ( + 1 2 3 )) ; ตอนนี้ form1 มีรูปแบบที่สามารถใช้โดย eval ได้เช่น: ( eval form1 ) ; eval ประเมินค่า (+ 1 2 3) และคืนค่า 6

ภาษา Lisp เป็นที่รู้จักกันดีว่ามีความยืดหยุ่นสูง และevalฟังก์ชันก็เช่นกัน ตัวอย่างเช่น ในการประเมินเนื้อหาของสตริง สตริงนั้นจะต้องถูกแปลงเป็นรูปแบบ Lisp ก่อนโดยใช้read-from-stringฟังก์ชัน จากนั้นรูปแบบที่ได้จะต้องถูกส่งไปยังeval:

( eval ( read-from-string "(format t \"Hello World!!!~%\")" ))

ประเด็นสำคัญประการหนึ่งที่ทำให้เกิดความสับสนคือคำถามที่ว่า สัญลักษณ์ในรูปแบบนั้นจะถูกประเมินในบริบทใด ในตัวอย่างข้างต้นform1มีสัญลักษณ์+การประเมินสัญลักษณ์นี้จะต้องให้ผลลัพธ์เป็นฟังก์ชันสำหรับการบวกเพื่อให้ตัวอย่างทำงานได้ตามที่ต้องการ ดังนั้น ภาษา Lisp บางสำเนียงจึงอนุญาตให้มีพารามิเตอร์เพิ่มเติมสำหรับevalเพื่อระบุบริบทของการประเมิน (คล้ายกับอาร์กิวเมนต์เสริมของฟังก์ชัน ใน Python eval- ดูด้านล่าง) ตัวอย่างในภาษา Lisp สำเนียง Scheme (R 5 RS และเวอร์ชันที่ใหม่กว่า):

;; กำหนดฟอร์มอย่างง่ายดังตัวอย่างข้างต้น( define form2 ' ( + 5 2 )) ;ค่า: form2;; ประเมินฟอร์มภายในบริบทเริ่มต้น;; บริบทสำหรับการประเมินเรียกว่า "สภาพแวดล้อม" ในภาษา Scheme ( eval form2 user-initial-environment ) ;ค่า: 7;; ทำให้สภาพแวดล้อมเริ่มต้นสับสน เพื่อให้ + กลายเป็นชื่อสำหรับฟังก์ชันการลบ( environment-define user-initial-environment '+ - ) ;ค่า: +;; ประเมินฟอร์มอีกครั้ง;; สังเกตว่าค่าที่ส่งคืนมีการเปลี่ยนแปลง( eval form2 user-initial-environment ) ;ค่า: 3

เพิร์ล

ในภาษา Perl ฟังก์ชัน นี้evalเป็นเหมือนลูกผสมระหว่างตัวประเมินนิพจน์และตัวดำเนินการคำสั่ง มันจะส่งคืนผลลัพธ์ของนิพจน์สุดท้ายที่ถูกประเมิน (คำสั่งทั้งหมดเป็นนิพจน์ในภาษา Perl) และอนุญาตให้ละเว้นเครื่องหมายเซมิโคลอนตัวสุดท้ายได้

ตัวอย่างการใช้เป็นตัวประเมินนิพจน์:

$foo = 2 ; print eval ( '$foo + 2' ), "\n" ;

ตัวอย่างการใช้เป็นตัวดำเนินการคำสั่ง:

$foo = 2 ; eval ( '$foo += 2; print "$foo\n";' );

ภาษา Perlยังมีevalบล็อกซึ่งทำหน้าที่เป็น กลไก การจัดการข้อยกเว้น (ดูไวยากรณ์การจัดการข้อยกเว้น#Perl ) ซึ่งแตกต่างจากการใช้ กับevalสตริงที่กล่าวมาข้างต้นตรงที่โค้ดภายในevalบล็อกจะถูกตีความในขั้นตอนการคอมไพล์ แทนที่จะเป็นขั้นตอนการทำงาน ดังนั้นจึงไม่ใช่ความหมายที่evalใช้ในบทความนี้

พีพี

ในPHP คำสั่ง ` evalexecute` จะประมวลผลโค้ดในสตริงเกือบเหมือนกับว่าโค้ดนั้นถูกเขียนไว้ในไฟล์โดยตรง แทนที่จะเรียกใช้ฟังก์ชัน `function` eval()ข้อแตกต่างเพียงอย่างเดียวคือ ข้อผิดพลาดจะถูกรายงานว่าเกิดจากการเรียกใช้ฟังก์ชัน `function` eval()และคำสั่ง `return` จะกลายเป็นผลลัพธ์ของฟังก์ชันนั้น

แตกต่างจากภาษาโปรแกรมบางภาษา อาร์กิวเมนต์ของฟังก์ชันevalต้องเป็นสตริงของคำสั่งที่สมบูรณ์อย่างน้อยหนึ่งคำสั่ง ไม่ใช่แค่เพียงนิพจน์ อย่างไรก็ตาม เราสามารถสร้างรูปแบบ "นิพจน์" ของฟังก์ชันได้evalโดยการใส่นิพจน์นั้นไว้ในคำสั่ง return ซึ่งจะทำให้evalฟังก์ชันส่งคืนผลลัพธ์ของนิพจน์นั้น

ต่างจากภาษาบางภาษา PHP evalเป็น "โครงสร้างภาษา" มากกว่าจะเป็นฟังก์ชัน[ 5 ]ดังนั้นจึงไม่สามารถใช้ในบางบริบทที่สามารถใช้ฟังก์ชันได้ เช่น ฟังก์ชันลำดับสูง

ตัวอย่างการใช้คำสั่ง echo:

<?php $foo = "Hello, world! \n " ; eval ( 'echo "$foo";' ); ?>

ตัวอย่างการส่งคืนค่า:

<?php $foo = "Goodbye, world! \n " ; //ใช้งานไม่ได้ใน PHP5 echo eval ( 'return $foo;' ); ?>

ลัว

ในLua 5.1 loadstringจะคอมไพล์โค้ด Lua ให้เป็นฟังก์ชัน นิรนาม

ตัวอย่างการใช้เป็นตัวประเมินนิพจน์:

loadstring ( "print('Hello World!')" )()

ตัวอย่างการประเมินผลในสองขั้นตอน:

a = 1 f = loadstring ( "return a + 1" ) -- แปลงนิพจน์เป็นฟังก์ชันนิรนามprint ( f ()) -- เรียกใช้ (และพิมพ์ผลลัพธ์ '2')

Lua 5.2 ยกเลิกloadstringการใช้loadงานฟังก์ชันเดิม และหันมาใช้ฟังก์ชันที่มีอยู่เดิมแทน ซึ่งได้รับการปรับปรุงให้สามารถรับสตริงได้ นอกจากนี้ยังอนุญาตให้ระบุสภาพแวดล้อมของฟังก์ชันได้โดยตรง เนื่องจากสภาพแวดล้อมในปัจจุบันเป็นค่าแบบ upvalueแล้ว

load ( "print('Hello ' .. a)" , "" , "t" , { a = "World!" , print = print })()

โพสต์สคริปต์

ตัวดำเนินการ ของPostScriptexecรับตัวถูกดำเนินการ — ถ้าเป็นค่าคงที่ธรรมดา มันจะผลักค่าคงที่นั้นกลับเข้าไปในสแต็ก แต่ถ้าหากรับสตริงที่มีนิพจน์ PostScript เราสามารถแปลงสตริงนั้นให้เป็นไฟล์ปฏิบัติการได้ จากนั้นตัวแปลภาษาจะสามารถเรียกใช้งานได้ ตัวอย่างเช่น:

((สวัสดีโลก) =) cvx exec

แปลงนิพจน์ PostScript

(สวัสดีโลก) =

ซึ่งจะดึงสตริง "Hello World" ออกจากสแต็กและแสดงผลบนหน้าจอ เพื่อให้ได้ประเภทที่สามารถเรียกใช้งานได้ จากนั้นจึงทำการเรียกใช้งาน

ตัวดำเนินการ ของ PostScript runมีฟังก์ชันการทำงานคล้ายกัน แต่ตัวแปลภาษาจะตีความนิพจน์ PostScript ในไฟล์เอง

(ไฟล์ .ps) รัน

ไพธอน

ในภาษา Pythonฟังก์ชันevalในรูปแบบที่ง่ายที่สุดจะประเมินนิพจน์เพียงนิพจน์เดียว

evalตัวอย่าง (เชลล์แบบโต้ตอบ):

>>> x = 1 >>> eval ( "x + 1" ) 2 >>> eval ( "x" ) 1

ฟังก์ชัน นี้evalรับอาร์กิวเมนต์เสริมสองตัว คือglobalและlocalsซึ่งช่วยให้โปรแกรมเมอร์สามารถกำหนดสภาพแวดล้อมที่จำกัดสำหรับการประเมินนิพจน์ได้

คำexecสั่ง (หรือexecฟังก์ชันใน Python 3.x) จะดำเนินการตามคำสั่งต่อไปนี้:

execตัวอย่าง (เชลล์แบบโต้ตอบ):

>>> x = 1 >>> y = 1 >>> exec "x += 1; y -= 1" >>> x 2 >>> y 0

รูปแบบทั่วไปที่สุดสำหรับการประเมินคำสั่ง/นิพจน์คือการใช้โค้ดออบเจ็กต์ ซึ่งสามารถสร้างได้โดยการเรียกใช้compile()ฟังก์ชันและบอกฟังก์ชันว่าต้องคอมไพล์ด้วยอินพุตประเภทใด: execคำสั่ง " ", evalคำสั่ง " " หรือsingleคำสั่ง " ":

compileตัวอย่าง (เชลล์แบบโต้ตอบ):

>>> x = 1 >>> y = 2 >>> eval ( compile ( "print 'x + y = ', x + y" , "compile-sample.py" , "single" )) x + y = 3

ดี

Dเป็นภาษาที่คอมไพล์แบบสแตติก ดังนั้นจึงไม่มีevalคำสั่ง " " ในความหมายดั้งเดิม แต่มีmixinคำสั่ง " " ที่เกี่ยวข้อง ความแตกต่างคือ ในขณะที่ " eval" ตีความสตริงเป็นโค้ดในขณะรันไทม์ แต่ " mixin" สตริงจะถูกคอมไพล์แบบสแตติกเหมือนโค้ดทั่วไปและต้องทราบค่าในขณะคอมไพล์ ตัวอย่างเช่น:

import std.stdio ;void main () { int num = 0 ; mixin ( "num++;" ); writeln ( num ); // พิมพ์ 1. }

ตัวอย่างข้างต้นจะคอมไพล์เป็นคำสั่งภาษาแอสเซมบลีเหมือนกันทุกประการราวกับว่า " num++;" ถูกเขียนโดยตรงแทนที่จะใช้ mixin อาร์กิวเมนต์ของ mixin ไม่จำเป็นต้องเป็นสตริงตัวอักษรแต่เป็นนิพจน์ใดๆ ก็ได้ที่ให้ค่าเป็นสตริง รวมถึงการเรียกใช้ฟังก์ชัน ซึ่งสามารถประเมินค่าได้ในระหว่างการคอมไพล์

โคลด์ฟิวชั่น

ฟังก์ชัน ของColdFusionevaluateช่วยให้ผู้ใช้สามารถประเมินนิพจน์สตริงได้ในขณะรันไทม์

<cfset x = "int(1+1)" > <cfset y = Evaluate ( x ) >

วิธีนี้มีประโยชน์อย่างยิ่งเมื่อผู้ใช้จำเป็นต้องเลือกตัวแปรที่ต้องการอ่านค่าโดยใช้การเขียนโปรแกรม

<cfset x = Evaluate ( "queryname. #columnname# [rownumber]" ) >

ทับทิม

ตัว แปล ภาษาโปรแกรม Rubyมีevalฟังก์ชันที่คล้ายกับ Python หรือ Perl และยังอนุญาตให้ระบุ ขอบเขตหรือการผูกมัด ได้ด้วย

นอกจากการระบุการผูกฟังก์ชันแล้วevalยังสามารถใช้เพื่อประเมินนิพจน์ภายในการผูกคำจำกัดความคลาสเฉพาะหรือการผูกอินสแตนซ์ของวัตถุ ทำให้สามารถขยายคลาสด้วยเมธอดใหม่ที่ระบุในสตริงได้

a = 1 eval ( 'a + 1' ) # (ประเมินค่าได้ 2)# การประเมินค่าภายในบริบทdef get_binding ( a ) binding end eval ( 'a + 1' , get_binding ( 3 )) # (ประเมินค่าได้ 4 เพราะ 'a' ในบริบทของ get_binding คือ 3)
class Test ; end Test . class_eval ( "def hello; return 'hello';end" ) # เพิ่มเมธอด 'hello' ให้กับคลาสนี้Test . new . hello # ประเมินค่าเป็น "hello"

ไปข้างหน้า

การใช้งาน Forthมาตรฐานส่วนใหญ่จะมีรูปแบบสองแบบคือeval: EVALUATEและINTERPRET.

ตัวอย่างโค้ด Win32FORTH:

S" 2 2 + . " ประเมิน\ ผลลัพธ์ "4"

พื้นฐาน

เรียลเบสิก

ในREALbasicมีคลาสชื่อRBScriptซึ่งสามารถเรียกใช้โค้ด REALbasic ในขณะรันไทม์ได้ RBScript มีขอบเขตการทำงานที่ค่อนข้างจำกัด—มีเพียงฟีเจอร์หลักของภาษาเท่านั้นที่ใช้งานได้ และผู้ใช้ต้องอนุญาตให้เข้าถึงสิ่งต่างๆ ที่ต้องการ พวกเขาสามารถกำหนดอ็อบเจ็กต์ให้กับคุณสมบัติ context ได้ ซึ่งจะทำให้โค้ดใน RBScript สามารถเรียกใช้ฟังก์ชันและใช้คุณสมบัติของอ็อบเจ็กต์ context ได้ อย่างไรก็ตาม มันยังคงจำกัดอยู่เพียงแค่การเข้าใจประเภทข้อมูลพื้นฐานที่สุด ดังนั้นหากมีฟังก์ชันที่ส่งคืนค่าเป็น Dictionary หรือ MySpiffyObject RBScript จะไม่สามารถใช้งานได้ ผู้ใช้ยังสามารถสื่อสารกับ RBScript ผ่านเหตุการณ์ Print และ Input ได้อีกด้วย

วีบีสคริปต์

VBScriptของ Microsoft ซึ่งเป็นภาษาที่ใช้การตีความ มีโครงสร้างสองแบบ แบบแรกEvalคือตัวประเมินฟังก์ชันที่สามารถเรียกใช้ฟังก์ชันที่ผู้ใช้กำหนดเองได้ (ฟังก์ชันเหล่านี้อาจมีผลข้างเคียง เช่น การเปลี่ยนแปลงค่าของตัวแปรส่วนกลาง) และแบบที่สองคือExecuteตัวดำเนินการคำสั่งที่คั่นด้วยเครื่องหมายโคลอนตั้งแต่หนึ่งคำสั่งขึ้นไป ซึ่งสามารถเปลี่ยนแปลงสถานะส่วนกลางได้

ทั้ง VBScript และ JScript evalสามารถใช้งานได้โดยนักพัฒนาแอปพลิเคชัน Windows ที่คอมไพล์แล้ว (เขียนด้วยภาษาที่ไม่รองรับ Eval) ผ่านทางตัวควบคุม ActiveX ที่เรียกว่า Microsoft Script Control ซึ่งสามารถเรียกใช้เมธอด Eval ได้จากโค้ดแอปพลิเคชัน ในการรองรับการเรียกใช้ฟังก์ชันที่ผู้ใช้กำหนดเอง จำเป็นต้องเริ่มต้นตัวควบคุมด้วยเมธอด AddCode ก่อน ซึ่งจะโหลดสตริง (หรือทรัพยากรสตริง) ที่มีไลบรารีของฟังก์ชันที่ผู้ใช้กำหนดเองในภาษาที่เลือก ก่อนที่จะเรียกใช้ Eval

Visual Basic สำหรับแอปพลิเคชัน

Visual Basic for Applications (VBA) ซึ่งเป็นภาษาโปรแกรมของ Microsoft Office เป็นภาษาเครื่องเสมือน (Virtual Machine Language) ที่สภาพแวดล้อมรันไทม์ (Runtime Environment) ทำการคอมไพล์และรันโค้ดp-codeฟังก์ชัน Eval ใน VBA รองรับเฉพาะการประเมินนิพจน์เท่านั้น โดยนิพจน์นั้นอาจรวมถึงฟังก์ชันและออบเจ็กต์ที่ผู้ใช้กำหนดเองได้ (แต่ไม่รวมชื่อตัวแปรที่ผู้ใช้กำหนดเอง) ที่สำคัญคือ ตัวประเมินผล (Evaluator) ใน VBA แตกต่างจากใน VBS และการเรียกใช้ฟังก์ชันที่ผู้ใช้กำหนดเองบางอย่างอาจทำงานแตกต่างกันใน VBA เมื่อเทียบกับโค้ดเดียวกันใน VBScript

การสนทนาเล็กๆ น้อยๆ

เนื่องจาก คลาสคอมไพเลอร์ของ Smalltalkเป็นส่วนหนึ่งของไลบรารีคลาสมาตรฐานและมักมีอยู่ขณะรันไทม์ จึงสามารถใช้คลาสเหล่านี้ในการประเมินสตริงโค้ดได้

คอมไพเลอร์ประเมินผล: '1 + 2'

เนื่องจากการกำหนดคลาสและเมธอดนั้นดำเนินการผ่านการส่งข้อความ (ไปยังอ็อบเจ็กต์ของคลาส) ดังนั้นจึงสามารถเปลี่ยนแปลงโค้ดได้:

คอมไพเลอร์ประเมิน: 'คลาสย่อยของอ็อบเจ็กต์: #Foo'

ทีซีแอล

ภาษา โปรแกรม Tclมีคำสั่งที่เรียกว่า ` evalexecute` ซึ่งใช้สำหรับเรียกใช้โค้ดต้นฉบับที่ให้มาเป็นอาร์กิวเมนต์ Tcl จะแสดงโค้ดต้นฉบับทั้งหมดในรูปแบบสตริง โดยใช้เครื่องหมายวงเล็บปีกกาแทนเครื่องหมายอัญประกาศ เพื่อให้โค้ดที่ส่งมาเป็นอาร์กิวเมนต์evalสามารถมีรูปแบบเดียวกันกับโค้ดต้นฉบับอื่นๆ ได้

กำหนดค่า foo { ในขณะที่{[ เพิ่ม i ] < 10 } { ใส่"$i ยกกำลังสองคือ [expr $i*$i]" } } ประเมินค่า$foo

บีเอส

bsมีevalฟังก์ชันที่รับอาร์กิวเมนต์สตริงหนึ่งตัว ฟังก์ชันนี้เป็นทั้งตัวประเมินนิพจน์และตัวดำเนินการคำสั่ง ในบทบาทหลังนี้ ยังสามารถใช้สำหรับการจัดการข้อผิดพลาดได้อีกด้วย ตัวอย่างและข้อความต่อไปนี้มาจากbsหน้าคู่มือตามที่ปรากฏในคู่มือโปรแกรมเมอร์UNIX System V Release 3.2 [ 6 ]

อาร์กิวเมนต์ที่เป็นสตริงจะถูกประเมินเป็นbsนิพจน์ ฟังก์ชันนี้มีประโยชน์สำหรับการแปลงสตริงตัวเลขให้เป็นรูปแบบตัวเลขภายใน นอกจากนี้evalยังสามารถใช้เป็นรูปแบบการอ้างอิงแบบคร่าวๆ ได้ ดังตัวอย่างต่อไปนี้ (โปรดทราบว่า ในbs( _เครื่องหมายขีดล่าง) คือตัวดำเนินการเชื่อมต่อ):

name = "xyz" eval ( "++" _ name )

ซึ่งจะเพิ่มค่าตัวแปรxyzขึ้น

นอกจากนี้evalเมื่อใช้ตัวดำเนินการสอบถามนำหน้า?จะช่วยให้ผู้ใช้สามารถควบคุมbsเงื่อนไขข้อผิดพลาดได้ ตัวอย่างเช่น:

?eval ( "open(\"X\", \"XXX\", \"r\")" )

ฟังก์ชันนี้จะคืนค่าเป็นศูนย์หากไม่มีไฟล์ชื่อ "XXX" (แทนที่จะหยุดโปรแกรมของผู้ใช้)

คำสั่งต่อไปนี้จะดำเนินการgotoกับป้ายกำกับL(ถ้ามี):

label = "L" ถ้า ! ( ?eval ( "goto " _ label )) puterr = "no label"

ตัวแปลคำสั่งบรรทัดคำสั่ง

เชลล์ยูนิกซ์

คำ สั่ง evalมีอยู่ในเชลล์ Unix ทุกตัว รวมถึง "sh" ดั้งเดิม ( Bourne shell ) ด้วย คำสั่งนี้จะรวมอาร์กิวเมนต์ทั้งหมดเข้าด้วยกันโดยเว้นวรรค จากนั้นจะแยกวิเคราะห์และเรียกใช้ผลลัพธ์เป็นคำสั่งsh(1) –  คู่มือคำสั่งทั่วไปของ FreeBSD

พาวเวอร์เชลล์

ในPowerShell คำสั่ง Cmdlet Invoke-Expressionทำหน้าที่เหมือนกับฟังก์ชัน eval ในภาษาโปรแกรมต่างๆ เช่น JavaScript, PHP และ Python Cmdlet จะรันนิพจน์ PowerShell ใดๆ ที่ระบุเป็นพารามิเตอร์คำสั่งในรูปแบบสตริง และแสดงผลลัพธ์ของนิพจน์นั้น โดยปกติแล้ว ผลลัพธ์ของ Cmdlet จะมีประเภทเดียวกับผลลัพธ์ของการรันนิพจน์นั้น อย่างไรก็ตาม หากผลลัพธ์เป็นอาร์เรย์ว่างเปล่า จะแสดงค่าว่าง (null $null) ในกรณีที่ผลลัพธ์เป็นอาร์เรย์ที่มีองค์ประกอบเดียว จะแสดงองค์ประกอบนั้นออกมา เช่นเดียวกับ JavaScript PowerShell อนุญาตให้ละเว้นเครื่องหมายเซมิโคลอนตัวสุดท้ายได้

ตัวอย่างการใช้เป็นตัวประเมินนิพจน์:

PS > $foo = 2 PS > Invoke-Expression '$foo + 2'

ตัวอย่างการใช้เป็นตัวดำเนินการคำสั่ง:

PS > $foo = 2 PS > Invoke-Expression '$foo += 2; $foo'

ไมโครโค้ด

ในปี พ.ศ. 2509 ระบบการเขียนโปรแกรมแบบสนทนาของ IBM (CPS) ได้แนะนำฟังก์ชันไมโครโปรแกรมเพื่อทำการ "ประเมินการตีความนิพจน์ที่เขียนในรูปแบบ Polish-string ที่แก้ไขแล้ว " บนIBM System/360 รุ่น 50 [ 7 ] การเขียนโค้ดไมโครสำหรับฟังก์ชันนี้เร็วกว่าโปรแกรมที่ตีความคำสั่งการกำหนดค่า "อย่างมาก" มากกว่าห้าเท่า [ 8 ]EVAL

ทฤษฎี

ในวิทยาการคอมพิวเตอร์เชิงทฤษฎีมักมีการแยกแยะความแตกต่างระหว่าง eval และapplyอย่าง ละเอียด evalหมายถึงขั้นตอนการแปลงสตริงที่อยู่ในเครื่องหมายคำพูดให้เป็นฟังก์ชันที่เรียกได้พร้อมอาร์กิวเมนต์ ในขณะที่applyคือการเรียกใช้ฟังก์ชันจริง ๆ ด้วยชุดอาร์กิวเมนต์ที่กำหนด ความแตกต่างนี้เห็นได้ชัดเจนเป็นพิเศษในภาษาโปรแกรมเชิงฟังก์ชันและภาษาที่ใช้แคลคูลัสแลมบ์ดาเช่นLISPและSchemeดังนั้น ตัวอย่างเช่น ใน Scheme ความแตกต่างจึงอยู่ระหว่าง eval และ apply

( eval ' ( f x ) )

โดยที่แบบฟอร์ม (fx) จะต้องได้รับการประเมิน และ

( ใช้f ( รายการx ))

โดยที่ฟังก์ชันfจะถูกเรียกใช้โดยมีอาร์กิวเมนต์เป็น x

Evalและapplyเป็นส่วนประกอบที่พึ่งพาซึ่งกันและกันสองส่วนของวงจร eval-applyซึ่งเป็นสาระสำคัญของการประเมิน Lisp ตามที่อธิบายไว้ในSICP [ 9 ]

ในทฤษฎีหมวดหมู่มอร์ฟิซึม eval ถูก ใช้เพื่อกำหนดหมวดหมู่โมโนอิดัลแบบปิดตัวอย่างเช่นหมวดหมู่ของเซตโดยใช้ฟังก์ชันเป็นมอร์ฟิซึม และผลคูณคาร์ ทีเซียน เป็นผลคูณจะก่อให้เกิดหมวดหมู่คาร์ทีเซียนแบบปิดในที่นี้eval (หรือพูดให้ถูกต้องคือ apply ) พร้อมกับ แอดจ อยต์ด้านขวาcurryingจะก่อให้เกิด แคลคูลัสแลมบ์ดาแบบง่ายซึ่งสามารถตีความได้ว่าเป็นมอร์ฟิซึมของหมวดหมู่คาร์ทีเซียนแบบปิด

ดูเพิ่มเติม

  • เอกสาร ANSI และ GNU Common Lisp: ฟังก์ชัน eval
  • เอกสารอ้างอิงไลบรารี Python: ฟังก์ชัน eval ในตัว
  • โจนาธาน จอห์นสัน กล่าวถึงการเปิดเผยคลาสต่างๆ ให้รู้จักกับ RBScript
  • ตัวอย่างการประเมินผลขณะรันไทม์ในภาษาโปรแกรมต่างๆบนRosetta Code
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Eval&oldid=1357930457 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ประเมิน

ในบาง ภาษาโปรแกรม ` value` eval ซึ่งย่อมาจาก `evaluate` เป็น ฟังก์ชัน ที่ประเมินสตริงเสมือนเป็น นิพจน์ ในภาษานั้น และส่งคืน ผลลัพธ์ ในขณะที่บางภาษา `value`...

ความเสี่ยงด้านความปลอดภัย

การใช้งาน eval ข้อมูลจากแหล่งที่ไม่น่าเชื่อถืออาจก่อให้เกิดช่องโหว่ด้านความปลอดภัย ตัวอย่างเช่น หาก get_data() ฟังก์ชันดึงข้อมูลจากอินเทอร์เน็ต โค้ด Python นี้ จะไม่ปลอดภัย:

การดำเนินการ

ใน ภาษาที่ใช้การตีความ (interpreted languages ) eval ฟังก์ชันนี้มักจะถูกใช้งานโดยตัวตีความ (interpreter) เดียวกันกับโค้ดปกติ ส่วนใน ภาษาที่ใช้การคอมไพล์ (compiled languages ) คอมไพเลอร์ตัวเดียวกันกับที่ใช้คอมไพล์โปรแกรมอาจถูกฝังอยู่ในโปรแกรมที่ใช้ eval...

อีซีเอ็มเอสคริปต์

ใน JavaScript นั้น eval เป็นเหมือนลูกผสมระหว่างตัวประเมินนิพจน์และตัวดำเนินการคำสั่ง โดยจะส่งคืนผลลัพธ์ของนิพจน์สุดท้ายที่ถูกประเมิน