มีคำพูดที่ว่า "เมื่อ"? [ปิด]


12

มีคุณสมบัติภาษาหรือภาษาที่สามารถจัดการกับ "กรณี" เมื่อใด? นั่นคือเมื่อใดก็ตามที่เงื่อนไขบางอย่างกลายเป็นความจริงในขอบเขตหรือบริบทใด ๆ รหัสพิเศษที่สามารถระบุเพื่อดำเนินการได้

โปรดทราบว่านี่จะแตกต่างจากแบบง่ายifซึ่งจะต้องอยู่ในขอบเขตที่เฉพาะเจาะจงและเขียนอย่างชัดเจน ข้อนี้เมื่อเกือบจะเป็นเหมือนifที่ใช้กับทุกกรณีในการดำเนินการของโปรแกรมหลังจากนั้น


1
เซิร์ฟเวอร์ select case table1.col1 when 1 then 'Y' else 'N' end as col1_yn from ...SQL: นอกจากนี้: msdn.microsoft.com/en-us/library/dd233249.aspxโดยทั่วไปฉันจะค้นหา "เมื่อ" โดยใช้การค้นหารหัสของ Google
งาน

5
@ งาน: นั่นเป็นประโยคไม่ใช่คำสั่ง
Ben Voigt

2
คุณหมายถึงชอบใน Verilog หรือไม่?
dan04

2
ต้องการคำอธิบายเพิ่มเติม ... คำถามที่กว้างมาก
WernerCD

2
คำถามกำลังถูกกล่าวถึงที่นี่ในเมตาดาต้า
อดัมเลียร์

คำตอบ:


25

คำถามของคุณไม่ชัดเจน แต่รูปแบบของผู้สังเกตการณ์ดูเหมือนจะเป็นสิ่งที่คุณมองหาhttp://en.wikipedia.org/wiki/Observer_pattern


1
ใช่สิ่งที่ฉันถามดูเหมือนจะเป็นการใช้งานแบบดั้งเดิม ฉันอยากจะชี้ไปที่บทความที่น่าสนใจเกี่ยวกับการเขียนโปรแกรมปฏิกิริยาที่โพสต์ร้อง "คัดค้านรูปแบบผู้สังเกตการณ์" (ไม่มีลิงก์, CTRL + F มัน) ในทางทฤษฎีเมื่อคำสั่งในทางทฤษฎีเรียกใช้บล็อกของรหัสเมื่อใดก็ตามในระหว่างการดำเนินการของโปรแกรมมีเงื่อนไข - โดยไม่คำนึงถึงวิธีการใช้งาน - และจะทำให้งานของฉันอย่างน้อยที่จะต้องดำเนินการ แบบสังเกตการณ์ด้วยตัวเอง
WindScar

15

ไวยากรณ์ฉลาดมีไม่กี่ภาษาที่มีwhenคำหลัก แต่ฉันไม่รู้ภาษาใด ๆ ที่ใช้ในแบบที่คุณอธิบาย

รูปแบบ 'เมื่อ X เกิดขึ้นทำ Y' เป็นแกนหลักของการเขียนโปรแกรมแบบเชิงกว้าง: แทนที่จะกำหนดโฟลว์เชิงเส้นคุณต้องเชื่อมโยงตัวจัดการเข้ากับเงื่อนไขบางอย่าง (หรือที่เรียกว่า การเขียนโปรแกรมชนิดนี้เป็นที่นิยมในแอปพลิเคชั่น GUI โดยที่รูทีนหลักของโปรแกรมคือตัวเลือกเหตุการณ์

บางภาษามีคุณสมบัติด้านไวยากรณ์ที่กว้างขวางเพื่อจัดเตรียมกลไกดังกล่าวผ่านการสร้างภาษา ตัวอย่างจะเป็น C # พร้อมตัวแทนและกิจกรรม:

// 'when btnOK is clicked, run HandleOKClick'
btnOK.Clicked += this.HandleOKClick;

ภาษาอื่น ๆ ใช้โครงสร้าง OOP (รูปแบบของผู้สังเกตการณ์, ผู้ฟังเหตุการณ์ ฯลฯ ) ตัวอย่างใน Java (Java ของฉันค่อนข้างเก่าสนิมดังนั้นอย่าลังเลที่จะแก้ไข):

Foobar f = this;
btnOK.registerClickHandler(
    new ClickHandler {
        public void handleClick(Event e) {
            f.handleOKClick(e);
        }
    });

อีกวิธีหนึ่งคือใช้การโทรกลับแบบเก่าแบบธรรมดา ตัวอย่างในจาวาสคริปต์:

var btnOK = $('btnOK');
btnOK.click(handleOKClick);

15

ยังไม่มีใครได้กล่าวถึงCOMEFROMของINTERCAL :

COMEFROM ถูกพบครั้งแรกในรายการของคำแนะนำภาษาแอสเซมบลีตลก (เป็น 'CMFRM') มันถูกอธิบายอย่างละเอียดในบทความ Datamation โดย R. Lawrence Clark ในปี 1973 ซึ่งเขียนขึ้นเพื่อตอบจดหมายของ Edsger Dijkstra Go To Statement ถือว่าเป็นอันตราย ในที่สุด COMEFROM ก็ถูกนำไปใช้ในตัวแปร C-INTERCAL ของภาษาการเขียนโปรแกรมลึกลับ INTERCAL พร้อมกับการบดบัง COMEFROM ที่ซับซ้อนยิ่งขึ้น นอกจากนี้ยังมีข้อเสนอ Fortran สำหรับคำว่า 'กำหนดมาจาก' และคำหลัก 'ดอนต์' (เพื่อเติมเต็มลูป 'DO' ที่มีอยู่เดิม)

เมื่อวันที่ 1 เมษายน 2547 Richie Hindle ได้ตีพิมพ์การนำ GOTO และ COMEFROM มาใช้ในการเขียนโปรแกรมภาษา Python แม้จะได้รับการปล่อยตัวในวันเอพริลฟูลส์และไม่ได้มีจุดประสงค์เพื่อการใช้งานที่จริงจัง แต่ไวยากรณ์นั้นใช้ได้และใช้งานได้อย่างสมบูรณ์


7
... และคุณต้องทำให้เสีย! :-)
Stephen C


2
@BenVoigt: คำตอบของคุณในขณะที่ทำการโพสต์ไม่มี "Intercal" หรือ "COMEFROM"
DeadMG

2
@DeadMG: คำตอบของฉันมี " en.wikipedia.org/wiki/COMEFROM " จากรุ่นแรกมาก
Ben Voigt

2
@BenVoigt: นั่นไม่นับ
DeadMG

6

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

แต่ถ้าคุณทำสิ่งนี้คุณควรระวัง ในขณะที่คุณไม่ได้มีปัญหาอย่างเป็นทางการกับ reentrancy (การติดตามถูกปิดใช้งานในช่วงระยะเวลาของการดำเนินการของร่างกาย) ก็ยังเป็นวิธีที่ดีในการเขียนรหัสที่ไม่ชัดเจนและก่อให้เกิดความสับสนมาก นอกจากนี้ยังเป็นความคิดที่น่ากลัวอย่างแท้จริงที่จะใช้กับตัวแปรลูป (นอกเหนือจากการดีบั๊ก) เนื่องจากประสิทธิภาพในการทำงานมีความสำคัญมาก


ตัวอย่าง (อ้างอิงจากรหัสจากหน้าคู่มือที่เชื่อมโยงด้านบน) แสดง

set foo 1
set bar 2
proc doMult args {
    global foo bar foobar
    set foobar [expr {$foo * $bar}]
}
trace add variable foo write doMult
trace add variable bar write doMult
doMult

จากจุดนั้นเป็นต้นไปทุกครั้งที่$fooหรือ$barกลายเป็นจำนวนเต็มใหม่$foobarกลายเป็นผลิตภัณฑ์ของทั้งสอง อัตโนมัติ


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


4

สิ่งที่ต้องการจัดการเหตุการณ์?

แทน func () จัดการกับเหตุการณ์

คุณพูดเมื่อเหตุการณ์ทำ func

หรืออาจจะโทรกลับใน varible เฉพาะหรือไม่


เสียงเหมือนเหตุการณ์แน่นอน
ต้น Plomp

4

ใช่มีคำหลักดังกล่าวใน Perl เป็นตัวแก้ไขคำสั่ง:

say 'Well done!'        when 'A';

มันเป็นส่วนหนึ่งของคำสั่ง switch:

given ($foo) {
    when (/^abc/) { $abc = 1; }
    when (/^def/) { $def = 1; }
    when (/^xyz/) { $xyz = 1; }
    default { $nothing = 1; }
}

5
ฉันไม่รู้ Perl แต่นี่ 'เมื่อ' ดูเหมือนว่า 'ถ้า' สำหรับฉัน ... ฉันคิดว่าคำถามหมายถึง 'เมื่อ <event> <action>' ประเภท 'เมื่อ'
ShdNx

1
กลิ่นเหมือนswitchคำให้ฉัน (ด้วยทองเหลืองลูกบิดกับมัน แต่แล้วอีกครั้งก็เป็น Perl ... )
Donal Fellows

จริงนี้เป็นcaseในswitchคำสั่ง เช่นเดียวกับใน Ada
mouviciel

4

ไม่นี้ ( COMEFROMคำสั่งที่อธิบายในวิกิพีเดีย)นับ?

สรุป:

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


6
ฉันเห็นว่าคุณมาจากไหน
Pubby

6
-1 สำหรับลิงก์ที่ไม่มีการสรุป linkrot สามารถเกิดขึ้นได้
Hugo

5
@Ben - ไม่ว่าคำตอบของคุณจะดีกว่านี้ถ้าคุณใส่ใจที่จะเขียนมากกว่า 3 คำ
BlackJack

3
@BenVoigt: ในกรณีนี้คุณสามารถวางลิงก์ทั้งหมดแทนที่จะซ่อนไว้ข้างหลัง "นี่"
Marjan Venema

1
@BenVoigt: ประเด็นของฉันคือเมื่อคุณวางลิงก์ทั้งหมดแทนที่จะซ่อนไว้ด้านหลัง "นี่" คำที่ค้นหาจะปรากฏทันทีในข้อความที่คุณตอบแทนที่จะเป็นเฉพาะเมื่อคุณวางลิงก์ไว้ที่ ... รวมทั้งฉันเห็นด้วยกับ BlackJack และ Hugo ว่าคำตอบที่เป็นลิงก์อย่างน้อยที่สุดควรให้สรุปสั้น ๆ ของสิ่งที่สามารถพบได้ที่นั่น ช่วยให้มั่นใจว่า StackExchange สามารถยืนได้ด้วยสองเท้าของตัวเองแม้ว่าลิงก์จะเน่าก็ตาม
Marjan Venema

3

คุณกำลังมองหาภาษาที่มีซิงโครนัสหรือแบบอะซิงโครนัสเมื่อมีคำสั่งหรือไม่?

ฟังดูเหมือนรูปแบบกิจกรรม (/ สมัครสมาชิก / โทรกลับ) สำหรับฉัน

เช่น

conditionOwner.Condition += listener.WhenCondition

เมื่อใดก็ตามที่เจ้าของเงื่อนไขแจ้งว่าเงื่อนไขเกิดขึ้นผู้ฟังจะทำ WhenCondition ()

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

สำหรับภาษาเช่น. NET (เช่น C #) มีการสมัครสมาชิกแบบซิงโครนัส (เหตุการณ์) และ Reactive Extensions (RX) เพิ่มการสมัครแบบอะซิงโครนัส


3

คำอธิบายเสียงเหมือนฐานข้อมูลทริกเกอร์ซึ่งออกแบบมาเพื่อรอสถานการณ์ที่แน่นอนแล้วดำเนินการ

จากวิกิพีเดีย:

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

http://en.wikipedia.org/wiki/Database_trigger


3

สิ่งที่คุณกำลังพูดถึงน้อยไวยากรณ์กว่าโครงสร้าง คุณสามารถมีwhenคำสั่งแบบนั้นได้ในระบบที่ใช้ตรรกะจำนวน จำกัด จากนั้นจึงเรียกใช้whenคำสั่งจากนั้นวนรอบและดำเนินการตรรกะอีกครั้งโดยดำเนินการต่อในวงวนไม่สิ้นสุด

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

ตัวอย่างเช่นหากคุณใช้เหตุการณ์ใน C # คุณสามารถทำได้โดยไม่มีการวนรอบข้อความ แต่ข้อ จำกัด คือคุณต้องประกาศเหตุการณ์ล่วงหน้าดังนั้นคุณจึงไม่สามารถเขียนwhenคำสั่งคลังข้อมูลที่เฝ้าดูประเภทใดก็ได้ สถานะ. คุณต้องรอเหตุการณ์เฉพาะ

ในการรับพฤติกรรมนี้ในสถาปัตยกรรม Von Neumann คุณต้องเรียกใช้การวนซ้ำแบบไม่สิ้นสุดที่ตรวจสอบเงื่อนไขทั้งหมดทุกครั้งผ่านการวนซ้ำที่เรียกใช้รหัสที่เหมาะสมหากเหมาะสม ภายในคุณจะได้รับรายการif/ thenหรือswitchข้อความสั่งจำนวนมาก เดสก์ท็อปแอปพลิเคชันและโปรแกรมเมอร์เว็บส่วนใหญ่จะอาเจียนถ้าพวกเขาเห็นโครงสร้างดังกล่าวดังนั้นจึงเป็นเรื่องที่น่าพึงพอใจจริงๆถ้าคุณห่อมันด้วยน้ำตาล syntactic บางชนิดเช่นรูปแบบเหตุการณ์ของ Windows (แม้ว่าจะเป็นสิ่งที่เกิดขึ้น)

ในทางกลับกันถ้าคุณดูที่การพัฒนาเฟิร์มแวร์แบบฝังตัวผู้บริหารแบบเรียลไทม์หรือผู้ควบคุมอุตสาหกรรมโปรแกรมแบบนี้เป็นเรื่องธรรมดามาก ตัวอย่างเช่นหากคุณมีโปรแกรมเรียลไทม์คุณอาจต้องการแสดง:

outputA = input1 && input2

รหัสตรงไปตรงมาเพื่อทำความเข้าใจ (เพราะมันเป็นการประกาศ) อย่างไรก็ตามเพื่อให้มันใช้งานได้คุณจะต้องรันมันเป็นวงแคบ คุณประเมินoutputAทุกครั้งผ่านลูป ผู้เขียนโปรแกรมบนเดสก์ท็อปหรือเว็บจำนวนมากไม่ชอบสิ่งนี้เพราะมันไม่มีประสิทธิภาพ สำหรับพวกเขาเวลาเดียวที่คุณควรประเมินใหม่outputAคือเมื่อใดinput1หรือinput2การเปลี่ยนแปลง พวกเขาค่อนข้างจะเห็นอะไรมากกว่านี้เช่นคุณกำลังอธิบาย:

when input1 changes
    evaluateOutputA()

when input2 changes
    evaluateOutputA()

evaluateOutputA()
    outputA = input1 && input2

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

ในทางกลับกันถ้างานที่คุณต้องทำเมื่อinput1การเปลี่ยนแปลงมีความสำคัญwhenประโยคของคุณอาจสมเหตุสมผล ใน PLC คำสั่งประเภทนี้เรียกว่า "การตรวจจับขอบที่เพิ่มขึ้น" มันช่วยประหยัดสถานะของinput1ในครั้งล่าสุดผ่านลูปเปรียบเทียบกับค่าในเวลานี้และดำเนินการตรรกะถ้าสถานะสุดท้ายเป็นเท็จและรัฐนี้เป็นจริง

หากคุณไม่มีสถาปัตยกรรม Von Neumann เกมจะเปลี่ยนไป ตัวอย่างเช่นหากคุณกำลังเขียนโปรแกรม FPGA ในVHDLจากนั้นเมื่อคุณเขียน:

outputA = input1 && input2

( ... หรืออะไรก็ตามไวยากรณ์ VHDL ที่เหมาะสมจะเป็น) แล้ว FPGA จริงได้รับสายขึ้นดังกล่าวว่าinput1และจะมีสายการป้อนข้อมูลของและประตูเมืองและการส่งออกของและประตูจะสายไปinput2 outputAดังนั้นไม่เพียง แต่เป็นรหัสที่เข้าใจง่ายเท่านั้นมันยังทำงานควบคู่ไปกับตรรกะอื่น ๆ ทั้งหมดและมีประสิทธิภาพ

เมื่อคุณกำลังพูดถึงคอนโทรลเลอร์อุตสาหกรรมเช่น PLC หรือ PAC ซึ่งตั้งโปรแกรมในหนึ่งในห้าภาษา IEC-61131-3 กรณีทั่วไปคือการจัดการประเภทนี้:

  1. อ่านอินพุตและเก็บไว้ในหน่วยความจำ
  2. รันโปรแกรมหลัก
  3. เขียนเอาต์พุตจากหน่วยความจำไปยังเอาต์พุตจริง
  4. ไปที่ขั้นตอนที่ 1

สิ่งนี้สร้างขึ้นในสถาปัตยกรรมของระบบดังนั้นจึงคาดว่าคุณจะเขียน:

outputA = input1 && input2

... และมันจะถูกดำเนินการในการวนซ้ำอย่างต่อเนื่อง

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

ดังนั้นในภาษาดั้งเดิม (ที่ไม่มีการวนซ้ำที่ไม่ จำกัด ) คุณต้องถามคำถามว่า "เมื่อใดที่โค้ดการประเมินทำงาน"

ถ้าคุณเขียน:

when A do
    launchNukes()

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

when systemTime > actionTime do
    launchNukes()

สังเกตว่าsystemTimeมีการเปลี่ยนแปลงอยู่เสมอ (ทุกครั้งที่คุณอ่านคุณจะได้รับหมายเลขที่แตกต่างกัน) ซึ่งหมายความว่าส่วนที่มีเงื่อนไขของwhenคำสั่งทั้งหมดของคุณจะต้องได้รับการประเมินใหม่อย่างต่อเนื่อง เกือบจะเป็นไปไม่ได้ (และลองพิจารณาสักครู่ว่าจะเกิดอะไรขึ้นถ้านิพจน์เงื่อนไขของคุณมีผลข้างเคียง!

ข้อสรุป

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


3

ภาษา AspectJมีเข้าร่วม-Point รุ่นซึ่งเป็นหนึ่งในวิธีการแก้ปัญหาการจัดการตรงชนิดของสถานการณ์นี้

จุดเชื่อมต่อใน AspectJ เป็นเหตุการณ์แบบไดนามิกในโปรแกรม Java ที่เกิดขึ้นเมื่อโปรแกรมกำลังทำงาน ตัวอย่างจุดเชื่อมต่อคือ: (1) วิธีการถูกเรียก; (2) วิธีการจะดำเนินการ; (3) เรียกตัวสร้าง (4) ตัวสร้างถูกดำเนินการ; (5) ตั้งค่าฟิลด์ หรือ (6) มีการเข้าถึงฟิลด์

จากนั้นคุณสามารถสร้างชุดของจุดเชื่อมต่อเหล่านี้เรียกว่าจุดทางลัด Pointcuts สามารถเข้าร่วมเสริมและตัดกันในทางทฤษฎีชุดปกติ การตัดจุดอื่น ๆ สามารถปรับเงื่อนไขในค่า / ประเภทของตัวแปร (เช่น "เฉพาะเมื่อ x เป็นบวก", "เฉพาะเมื่อค่าที่ตั้งไว้เป็น subclass ของประเภทนี้") และขึ้นอยู่กับสถานะของโปรแกรม ("เมื่อ วิธีการนี้เรียกว่า แต่เมื่อวิธีอื่นนี้อยู่ในสแต็กของเธรดนี้ [หมายความว่าวิธีนั้นเรียกว่าอ้อม] ")

เมื่อคุณมี pointcut เหล่านี้ทั้งหมดอธิบายเหตุการณ์ในโปรแกรมคุณสามารถใช้ AspectJ เพื่อแนะนำเหตุการณ์เหล่านี้ คุณสามารถเลือกที่จะทำอะไรบางอย่างก่อนที่เหตุการณ์จะเกิดขึ้น ( beforeคำแนะนำ) หลังจากเหตุการณ์เกิดขึ้น ( afterคำแนะนำ) หรือแทนที่จะเป็นเหตุการณ์ที่เกิดขึ้น ( aroundคำแนะนำ)

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

หลายคนที่อยู่นอกการเขียนโปรแกรมแบบเชิงกว้างเชื่อว่า AOP ส่วนใหญ่เกี่ยวกับ "การบันทึก" คุณสามารถใช้ AspectJ เพื่อจัดการการบันทึกและทำได้ค่อนข้างดี ("บันทึกในไฟล์บันทึกนี้เมื่อมีการเรียกใช้เมธอดสาธารณะทั้งหมดในแพ็คเกจนี้และผลลัพธ์ของผลลัพธ์ / ผลลัพธ์ข้อผิดพลาด") แต่มีอีกมากมายที่ AspectJ รวมถึงเคล็ดลับที่ชาญฉลาดในการจำลองขอบเขตแบบไดนามิกที่เรียกว่าWorm Hole Pattern [ดูสไลด์ 23 และถัดไป]

นอกเหนือจาก AOP คุณกำลังพูดถึงการเขียนโปรแกรมตามเหตุการณ์ซึ่งรวมถึง [ตามที่คนอื่น ๆ ได้บันทึกไว้] รูปแบบการสังเกตการณ์ ความแตกต่างระหว่างการแก้ปัญหาคือ: (1) วิธีตรวจจับเงื่อนไข; (2) เมื่อมีการแสดงเงื่อนไข และ (3) วิธีผูกรหัสเพื่อดำเนินการกับเหตุการณ์


2

วิธีใช้ Notify / Waitดูเหมือนจะใกล้เคียงกับสิ่งนี้:

เราได้กล่าวถึงกลไกการรอ / แจ้งเตือนของ Java เป็นวิธีการสื่อสารระหว่างเธรดเป็นหลัก สรุปความคิดมีดังนี้:

  • หนึ่งเธรดขึ้นไปกำลังรอสัญญาณ
  • อีกเธรดหนึ่งจะมาพร้อมกันและแจ้งให้ทราบถึงเธรดที่รออยู่ (เช่น "ปลุก / ปลุกพวกเขา" พร้อมกับสัญญาณ)

ขึ้นอยู่กับบริบทมีโครงสร้างบางอย่างที่สามารถอยู่ใกล้กับสิ่งนี้ แต่คุณต้องชี้แจงคำถามของคุณ

นอกจากนี้ยังมีคำสั่ง "เมื่อ" ใน XSLT :

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


XSLT "เมื่อ" เป็นคำสั่งแบบมีเงื่อนไขเหมือนสวิตช์มากกว่าถ้า อย่างไรก็ตามบริบทของสิ่งที่มีความหมายโดย "เมื่อ" ในคำถามแรกไม่ชัดเจน

ฉันใช้ XSLT ค่อนข้างบ่อยใน Sitecore CMS ที่ฉันทำงานเพื่อนำเสนอเนื้อหาเพื่อให้สามารถใช้ในสภาพแวดล้อม GUI ในบางกรณี


XSLT เมื่อฟังดูเป็นมากกว่าifแม้ว่าจะไม่ใช่ประเภทของขั้นตอนที่ifคุณจะพบในภาษาการเขียนโปรแกรม (ฉันมองว่า XSLT เป็นภาษาการประมวลผลข้อมูลเฉพาะมากกว่าภาษาโปรแกรมทั่วไป - ฉันไม่เห็นคุณสร้าง GUI เดสก์ท็อปโดยใช้ XSLT)
Marjan Venema

2

สิ่งที่คุณจะขอเรียกว่าการเขียนโปรแกรมปฏิกิริยา

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

โดยปกติพฤติกรรมการตอบสนองนี้จะเกิดขึ้นได้ด้วยการใช้รูปแบบการสังเกตอย่างชาญฉลาดซึ่งค่ารีแอกทีฟจะลงทะเบียนตัวเองเป็นผู้ฟังในชุดของเหตุการณ์ที่กระตุ้นให้เกิดการประเมินค่าอีกครั้ง

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

ส่วนใหญ่ของการผูกข้อมูลกรอบสามารถพิจารณาการใช้งานของการเขียนโปรแกรมปฏิกิริยา

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


หนึ่งในคำตอบที่ดีที่สุดสำหรับคำถามของฉัน กระดาษที่ดี
WindScar

1
อย่าลังเลที่จะทำเครื่องหมายว่า "ยอมรับ" (ขยิบตาขยิบพยักหน้า)
Roland Tepp

ฉันกำลังจะโพสต์สิ่งนี้ แต่อย่างมีความสุขคุณเอาชนะฉันไปที่มันและเขียนคำตอบที่ดีกว่าฉันจะมี การเขียนโปรแกรมเชิงโต้ตอบนั้นยอดเยี่ยม (และเป็นวิธีที่ยอดเยี่ยมในการสร้าง UIs ในภาษาที่ใช้งานได้) แต่มีความลับเล็กน้อย
Tikhon Jelvis

1
@RolandTepp การส่งเสริมตนเองที่ไร้ยางอายใช่มั้ย? ฉันชื่นชมที่เกี่ยวกับคุณ +1
นีล

0

เสียงกระเพื่อม (และแป้นหมุนหมายเลขจำนวนมากรวมถึง Scheme) มี:

(when (> 2 1) 'do-something)

ประเมินdo-somethingและ:

(when nil 'other-thing)

ประเมินnilหรือเทียบเท่า


2
เสียงกระเพื่อมwhenเป็นเหมือนถ้าไม่ใช่รูปแบบผู้สังเกตการณ์โดยไม่ได้ตั้งใจอธิบายโดย OP
ocodo

0

ฉันรู้ว่าข้อความดังกล่าวเป็นเพียงข้อผิดพลาดเท่านั้น ตัวอย่างเช่น BASIC ON ERROR ...หรือ SQL * PLUSWHENEVER SQLERROR ...

สำหรับเงื่อนไขการอนุญาโตตุลาการมันจะต้องมีคอมไพเลอร์ที่ฉลาดมากหรือกำลังดุร้ายที่ค่อนข้างแพง (ตรวจสอบทุกคำสั่ง) เพื่อจับช่วงเวลาที่แน่นอนเมื่อเงื่อนไขเป็นจริง


0

มันเป็นคุณสมบัติของภาษา dataflow เช่นภาษาคำอธิบายฮาร์ดแวร์ (Verilog และ VHDL)

นอกเหนือจากนั้นฉันสามารถนึกถึง Ada และกลไกการจัดการข้อยกเว้น: ตัวจัดการข้อยกเว้นถูกทริกเกอร์whenข้อยกเว้นบางอย่าง


0

ดูเหมือนว่าคุณกำลังมองหาตัวแปรเงื่อนไขสิ่งที่อนุญาตให้เธรดนอนหลับจนกว่าเพรดิเคตบางรายการจะกลายเป็นจริง

เพิ่มการดำเนินการกับพวกเขาสำหรับ C ++ ที่Apache พกพา Runtimeดำเนินการพวกเขาสำหรับเซลเซียสใน Common เสียงกระเพื่อมคุณต้องการใช้'sbordeaux-threadmake-condition-variable


คุณสามารถตั้งชื่อส่วนหนึ่งของห้องสมุดเพิ่มที่รับผิดชอบการดำเนินการนี้ได้หรือไม่?
WindScar

0

หากคุณพิจารณาภาษา Drools แล้วใช่

ตัวอย่าง:

rule "Rule 08 - Debit"
when
    AccountingPeriod( $start : start, $end : end )
    $cashflow : AllocatedCashflow( $account : account, $date : date <= $end, $amount : amount, type==TypedCashflow.DEBIT )
    not AccountingPeriod( start < $start)
then 
    $account.setBalance($account.getBalance()-$amount);
    retract($cashflow);
end

0

Perl 6 สามารถจัดการสัญญาณได้โดยตรงโดยใช้tap:

signal(SIGINT).tap: {
    note "Took { now - INIT now } seconds.";
    exit;
}

for 0, 1, *+* ... * {
    sleep 0.5;
    .say;
}

ในขณะที่ Powershell สามารถจัดการกับมันได้โดยใช้ลูปรันด้วยการลอง / ในที่สุดบล็อก:

$Start_Time = (Get-date).second
Write-Host "Type CTRL-C to Terminate..."
$n = 1
Try
{
    While($true)
    {
        Write-Host $n
        $n ++
        Start-Sleep -m 500
    }
}
Finally
{
    $End_Time = (Get-date).second
    $Time_Diff = $End_Time - $Start_Time
    Write-Host "Total time in seconds"$Time_Diff
}

ตามที่คาดหวังโดยใช้trap:

package require Expect

proc sigint_handler {} {
    puts "elapsed time: [expr {[clock seconds] - $::start_time}] seconds"
    set ::looping false
}

trap sigint_handler SIGINT

set start_time [clock seconds]
set n 0
set looping true
while {$looping} {
    puts [incr n]
    after 500
}

อ้างอิง


0

เป็นเวลานานแล้วที่ฉันได้ดูสิ่งเหล่านี้ดังนั้นฉันจึงเข้าใจผิดได้ดี

ในขณะที่ฉันจำได้ว่า PL / I และ BASIC ทั้งคู่มีคำสั่ง "ON" ใน PL / I แนวคิดคือ "ON DO" ในพื้นฐานมันคือ "เปิด" โดยที่คำสั่งมักเป็น GOSUB ในทั้งสองภาษาเมื่อใดก็ตามที่เงื่อนไขที่ระบุเป็นจริงงบที่เกี่ยวข้องจะถูกดำเนินการ

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


0

คุณอาจดูภาษาOPS5 โปรแกรมมันถูกเขียนเป็นชุดของเงื่อนไข เมื่อตรงตามเงื่อนไขจะมีการดำเนินการที่เกี่ยวข้อง การดำเนินการสามารถแก้ไขสถานะซึ่งอาจทำให้เงื่อนไขอื่น ๆ เป็นไปตาม แม้ว่าจะไม่ได้ใช้whenคำหลัก แต่จะทำงานเป็นหลักโดยดำเนินการ "เมื่อ" เป็นไปตามเงื่อนไข จากที่นี่ :

โปรแกรม OPS5 ประกอบด้วยส่วนประกาศที่สร้างข้อมูลพื้นฐานตามด้วยส่วนการผลิตที่มีกฎสำหรับการจัดการข้อมูล

โปรแกรม OPS5 ดำเนินการโดยการจับคู่องค์ประกอบหน่วยความจำในการทำงานกับกฎในหน่วยความจำที่ใช้งานจริงและการยิง (ดำเนินการ) กฎที่โดดเด่นที่สุดซึ่งจับคู่ไว้ รอบการจับคู่เลือกดำเนินการต่อไปจนกว่าโปรแกรมจะหยุดอย่างชัดเจนหรือจนกว่าจะไม่มีกฎใดที่สามารถจับคู่กับหน่วยความจำที่ใช้งานได้

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



-1

ในภาษา OOP ส่วนใหญ่มันจะเป็นไปได้ที่จะวางไข่เธรดพิเศษให้ใช้สิ่งนี้เป็นบริบท:

    while (!value)
{
}

//Execute code

-1

ทีนี้, คุณสามารถเขียนกลุ่มของเธรดแบบขนาน, ซึ่งแต่ละโพลจะโพลตามเงื่อนไขของมัน ฉันคิดว่ามันจะเป็นแอพพลิเคชั่นที่มีประสิทธิภาพต่ำ แต่ก็เป็นไปได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.