โปรแกรมอัตโนมัติ: เขียนโค้ดที่เขียนรหัส [ปิด]


105

หลังจากอ่านหนังสือThe Pragmatic Programmerหนึ่งในข้อโต้แย้งที่ฉันพบว่าน่าสนใจที่สุดคือ "เขียนโค้ดที่เขียนโค้ด"

ฉันพยายามค้นหาคำอธิบายหรือบทความเกี่ยวกับเรื่องนี้ทางอินเทอร์เน็ตและในขณะที่ฉันพบบทความที่ดีเกี่ยวกับเรื่องนี้ฉันยังไม่พบการติดตั้งโค้ดเฉพาะหรือตัวอย่างที่ดี

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

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


ตัวอย่างโค้ดบางส่วนจะช่วยให้ฉันเข้าใจการใช้งานได้ดีขึ้น


นี่คือหน้า wikiของหัวเรื่องด้วยเทคนิคการเขียนโปรแกรมที่เกี่ยวข้องเช่น Meta Programming, Generative Programming และ Code Generation


32
ฉันไม่ครั้งหนึ่งเคยเขียนโค้ดที่เขียนรหัสที่เขียนรหัส ... :)
Benjol

9
@Benjol: คุณเขียนด้วย Lisp หรือไม่
compman

11
นอกจากนี้ภาษาฝั่งเซิร์ฟเวอร์ทำสิ่งนี้ตลอดเวลาโดยการสร้าง HTML, CSS และ JavaScript คุณสามารถมีสคริปต์ฝั่งเซิร์ฟเวอร์ที่สร้างสคริปต์ฝั่งเซิร์ฟเวอร์ที่สร้าง html ด้วย javascript ที่สร้าง html เพิ่มเติมและไม่มีใครจะจับตามองเกี่ยวกับเรื่องนี้เพราะมันเป็นเรื่องธรรมดา
zzzzBov

8
หากคุณยังไม่ได้ตรวจสอบนี้ไอบีเอ็มชุด developerWorks บทความ: " ศิลปะของ metaprogramming " ส่วนที่ 1 , ส่วนที่ 2และส่วนที่ 3
John Tobler

3
AtomWeaver ( atomweaver.com ) เป็นตัวอย่างที่ดีของการเขียนโปรแกรมอัตโนมัติ: อันดับแรกคุณสร้างโปรแกรมขนาดเล็กที่สามารถใช้ซ้ำได้ใน Lua จากนั้นคุณสร้างแบบจำลองระบบของคุณโดยการนำสินทรัพย์เหล่านี้กลับมาใช้ใหม่ AtomWeaver จะสานโปรแกรม Lua ที่มี "เครื่องกำเนิดไฟฟ้าขนาดเล็ก" ของคุณเพื่อสร้างซอร์สโค้ดสุดท้ายของระบบ จากนั้นคุณสามารถปรับแต่งโมเดลของคุณและสร้างใหม่อีกครั้ง
Rui Curado

คำตอบ:


49

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

สำหรับผลผลิต: ฉันใช้ metaprogramming เป็นเทคนิคที่โดดเด่นในการพัฒนาเกือบทั้งหมดของฉันและมันช่วยได้อย่างมากทั้งการลดขนาดรหัสและเพิ่มความสามารถในการอ่าน กุญแจสำคัญคือการใช้Domain Specific Languagesและ Metaprogramming เป็นหนึ่งในวิธีที่มีประสิทธิภาพที่สุดในการใช้งาน


67

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

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

หนังสือเล่มหนึ่งที่ฉันชอบอ่านในเรื่องนี้คือMetaprogramming Ruby (ถ้าคุณรู้ภาษา Ruby)


แก้ไขหลังจากคำถามต่อไปนี้ในความคิดเห็น:

ทำไมจึงมีประโยชน์ฉันยังต้องใช้รหัสในการสร้าง? ฉันควรเขียนโค้ดที่สามารถสร้างสิ่งต่าง ๆ ได้หรือไม่ขึ้นอยู่กับการป้อนข้อมูลของผู้ใช้เพื่อที่ฉันจะสามารถนำมันกลับมาใช้ซ้ำได้?

ขั้นแรกการสร้างโปรแกรมมิ่งไม่ใช่เป้าหมาย แต่เป็นเครื่องมือ อย่าใช้ metaprogramming เพราะ "เจ๋ง" หรือ "X กล่าวว่านักพัฒนาทุกคนควรใช้"

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

ตามที่กล่าวโดย Jordanกรณีใช้งานทั่วไปหนึ่งกรณีคือการจัดการฐานข้อมูลและ ORM (การทำแผนที่วัตถุสัมพันธ์) อีกครั้งใน Ruby คุณควรดูActiveRecordซึ่งเป็นตัวอย่างที่ดีของ metaprogramming ที่ใช้กับ ORM

เป็นบันทึกสุดท้าย:

อย่าคิดว่า "ฉันต้องการใช้ metaprogramming ฉันจะสมัครได้ที่ไหนในรหัสของฉัน"

คิดว่า "ฉันเห็นรูปแบบนี้ที่ทำซ้ำทั่วรหัสของฉันฉันไม่สามารถหาวิธีปรับโครงสร้างโค้ดให้มีขนาดเล็กลงและสามารถนำกลับมาใช้ใหม่ได้อีกบางที metaprogramming อาจช่วยฉันได้ไหม"


3
@Jose: ส่วนใหญ่คุณสร้างรหัสผ่านแม่แบบ ตัวอย่างเช่น apache (N-) speed หรือเทมเพลต visual Studio T4 จากนั้นคุณก็มีโปรแกรมที่ดึงข้อมูลเมตาลงในแม่แบบของคุณและสร้างไฟล์ใหม่จากนั้น มันค่อนข้างง่ายและฉันทำมันตลอดเวลาเพื่อสร้างโครงกระดูก UI, เอนทิตี้และอื่น ๆ
Falcon

2
@Jose Faeti ลองดูมาโคร Lisp อย่างใกล้ชิด (หรือ Clojure หรือ Nemerle ขึ้นอยู่กับการตั้งค่าแพลตฟอร์มของคุณ)
SK-logic

1
ฉันจะเพิ่ม metaprogramming สามารถแทนที่รูปแบบบางอย่างเช่นนโยบายหรือรัฐ แต่ไม่มีค่าใช้จ่ายรันไทม์ สิ่งนี้ไม่เพียง แต่สำหรับปัญหาที่ไม่สามารถทำได้ด้วยการรีแฟคเตอร์ทั่วไป แต่บางครั้งก็เป็นทางเลือกที่ดีกว่า
deadalnix

1
@Jose Faeti: ฉันเห็นว่าคุณรู้จักงูหลามบ้าง นอกจากนี้ยังมีความสามารถในการเขียนโปรแกรมแม้ฉันจะไม่ได้ใช้สิ่งเหล่านั้น ดูPython PDF ขั้นสูง
ชุด

3
@ Falcon: IMO ซึ่งเป็นวิธีที่แย่ที่สุดในการสร้างรหัส มันแย่มากในการทำงานกับภาษาที่ไม่มีระบบการเขียนโปรแกรมเมตาในตัว แทนที่จะสร้าง Java หรือ C # จะเป็นการดีกว่าถ้าจะเขียนโค้ดนั้นในภาษา JVM หรือ. NET ระดับสูงกว่า
วินไคลน์

19

ยิ่งไปกว่านั้นใช้รหัสที่คนอื่นเขียนซึ่งเขียนรหัสให้คุณ

การทำงานอัตโนมัติของรหัสนั้นดีสำหรับ ORM และรหัสการโต้ตอบของฐานข้อมูลอื่น ๆ และแน่นอนว่าสำหรับการสร้างรหัสซ้ำ

แน่นอนถ้าคุณกำลังสร้างคลาสที่มีลักษณะคล้ายกันจำนวนมากบางทีคุณอาจจะทำสิ่งเดียวกันในภาษาไดนามิกได้เร็วกว่านี้ แต่ฉันเชือนแช

สิ่งนี้ได้รับการยอมรับจากหลาย ๆ คนแม้ว่าคุณมักจะพบซอฟต์แวร์ที่ระบุว่าเป็นตัวสร้างรหัส

ดู บริษัท และผลิตภัณฑ์เช่น CodeSmith และ MyGeneration หรือดูบทความ Wikipedia นี้: http://en.wikipedia.org/wiki/Comparison_of_code_generation_tools


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

@ SK-logic: สิ่งที่เกี่ยวกับรหัสสร้าง ORM? มันถูกสร้างขึ้นโดยเครื่องมือ / ไลบรารีอื่นและยังคงตอบสนองความต้องการของโครงการจำนวนมาก
เดวิด

@ David พูดตามตรงฉันไม่ค่อยมั่นใจกับ ORM ทั่วไป ฉันมีปัญหามากมายกับพวกเขาในอดีตมักหันมาใช้ ORM เฉพาะของตัวเองแทน
SK-logic

1
@Jordan เครื่องมือทั้งหมดที่มีความเฉพาะเจาะจงเกินไป (และเลว - ข้อความ - based เช่นด้อยกว่าโดยการออกแบบ) ฉันกำลังพูดถึง metaprogramming ที่เหมาะสมแทน
SK-logic

1
@AtillaOzgur พวกเขาสามารถ "ดีมาก" จริง แต่พวกเขาก็ไม่ได้ดีไปกว่า eDSL การสร้างรหัสแบบสแตนด์อโลนนั้น จำกัด มากขึ้นและมีความยืดหยุ่นน้อยกว่ามาโครการเขียนโปรแกรมแมโคร
SK-logic

16

หนึ่งในตัวอย่างคลาสสิกคือ lex และ yacc วัตถุประสงค์หลักของพวกเขาคือการหลีกเลี่ยงความน่าเบื่อหน่ายในการเขียนโปรแกรมวิเคราะห์คำ พวกเขาทำให้เร็วขึ้นในการสร้างตัวแยกวิเคราะห์ที่ซับซ้อนด้วยกฎและรัฐจำนวนมากและพวกเขายังหลีกเลี่ยงความผิดพลาดทั้งหมดที่ผู้คนทำขึ้นเอง

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

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

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

ในความหมายทุกอย่างที่คุณทำเหนือชั้นไบนารีคือการทำงานอัตโนมัติของรหัส


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

1
@Jose Faeti บทความวิกิพีเดียen.wikipedia.org/wiki/Automatic_programmingมีลิงก์ไปยังเครื่องมือต่าง ๆ หากคุณสนใจรายละเอียดเพิ่มเติม ฉันขอแนะนำให้อ่านไฟล์ lex และ yacc ด้วยเนื่องจากมีเอกสารและคำอธิบายเพิ่มเติมอยู่บ้าง
Spencer Rathbun

ในภาษาที่มีประสิทธิภาพเพียงพอ (เช่น C ++ เมื่อเทียบกับ C) เครื่องมือภายนอกเช่น lex และ yacc ไม่จำเป็น
วินไคลน์

YACC ไม่ได้เขียน "parser ใด ๆ " มันเขียนตัวแยกวิเคราะห์ชนิดหนึ่ง (LALR) ชนิดหนึ่งซึ่งยากมากที่จะได้รับสิทธิโดยปราศจากความช่วยเหลือแบบอัตโนมัติ มีตัวแยกวิเคราะห์อีกประเภทหนึ่ง (แบบสืบซ้ำ) ซึ่งง่ายต่อการเขียนและทำให้ถูกต้องมากขึ้นและอ่านและเข้าใจได้ง่ายขึ้นว่าเกิดอะไรขึ้น
Mason Wheeler

@MasonWheeler ตัวแยกวิเคราะห์ชนิดหนึ่งอ้างถึงไวยากรณ์ที่สามารถสร้างขึ้นเพื่อแก้ไขปัญหาได้อย่างกว้างขวางและไม่ตรงตามความเป็นจริง อ่านอีกหนึ่งปีต่อมามันไม่ชัดเจนเท่าที่ฉันจะชอบ ฉันไม่แน่ใจว่าฉันเห็นด้วยกับคุณในการแยกวิเคราะห์ LL (*) ง่ายต่อการเขียนและใช้งาน
Spencer Rathbun

13

metaprogramming

Metaprogramming เป็นเทคนิคการโต้เถียงในร้านค้าหลายแห่ง เหตุผลก็คือเหมือนเครื่องมืออันทรงพลังขนาดของความช่วยเหลือหรือเจ็บมีขนาดใหญ่

ข้อดี

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

จุดด้อย

  • ความซับซ้อนอาจมีความซับซ้อนมากแม้ว่าจะมีรหัสน้อย
  • ความปลอดภัยความปลอดภัยประเภทบางครั้งและการวิเคราะห์แบบคงที่โดยทั่วไปจะเสียสละ
  • ข้อบกพร่องมีผลมากกว่าข้อผิดพลาดเล็กน้อยจะมีผลกระทบมากขึ้น

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

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


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

ฮ่าฮ่าทำให้ฉันจำความผิดพลาดที่ฉันเคยทำกับ GCC เมื่อหลายปีก่อน 162 บรรทัดเพื่อใส่ข้อความแสดงข้อผิดพลาดบนหน้าจอของฉัน Metaprogramming แบบเรียกซ้ำโปรแกรม FTW!
deadalnix

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

2
@ SK-logic: ไม่ใช่ทุกภาษาที่สนับสนุน metaprogramming ดังนั้นบางครั้งสิ่งที่ต้องการความปลอดภัยประเภทจะเสียสละ(เช่น. C) metaprogramming ไม่ได้เป็นเพียง DSL เท่านั้น มันรวมถึงสิ่งต่าง ๆ เช่นการเขียนโปรแกรมรูปแบบการจัดส่งข้อมูลทั่วไปการปิดการตรวจสอบวัตถุแอปพลิเคชันแบบไดนามิกและอื่น ๆ สำหรับความซับซ้อนฉันคิดว่ามันง่ายสำหรับเรา (คนที่มีประสบการณ์ metaprogramming) ฉันได้เห็นการต่อสู้อื่น ๆ ด้วยความเข้าใจในทุกกรณีรหัสจะถูกดำเนินการภายใต้ ส่วนใหญ่ขึ้นอยู่กับประสบการณ์และเทคนิคที่เกี่ยวข้อง
dietbuddha

@dietbuddha คุณช่วยอธิบายได้อย่างละเอียดว่าทำไมพวกเราถึงเสียสละความปลอดภัยของ DSL ของพวกเขาเองไม่ว่ามันจะถูกนำไปใช้อย่างไร? คุณสามารถเขียน ad hoc interpreter ใน pure C ด้วยระบบ strong type (ดู Hugs เช่น) คุณสามารถเขียนตัวสร้างโค้ดที่กำหนดเป้าหมาย C ซึ่งทำหน้าที่ตรวจสอบตัวเองทั้งหมดโดยไม่ต้องพึ่งพาระบบประเภทภาษาเป้าหมาย สำหรับความซับซ้อน: คนส่วนใหญ่ใช้วิธีการที่ซับซ้อนโดยไม่จำเป็นขณะที่วิธีการออกแบบเดียวกันทั้งหมดสามารถนำไปใช้กับการสร้างรหัสได้เช่นเดียวกับในการเขียนโปรแกรม "ปกติ" แทบไม่จำเป็นต้องมีความรู้ใหม่
SK-logic

9

รหัสส่วนใหญ่เขียนรหัส ตัวอย่างเช่นโค้ด php ช่วยในการเขียน html php pdo library ช่วยเขียนการเรียก SQL ฟังก์ชัน I / O ไฟล์เขียนโค้ดเพื่อสื่อสารกับระบบปฏิบัติการ แม้แต่การเรียกใช้ฟังก์ชั่นปกติก็คือการอ้างอิงไปยังบล็อคของรหัสอื่นซึ่งถูกเรียกใช้งาน ดังนั้นการเรียกฟังก์ชั่นของคุณคือการเขียนรหัส

ในแง่กว้างเราสามารถคิดว่าการคำนวณเป็นรหัสการเขียนที่เขียนรหัสซ้ำสแต็คที่สิ้นสุดเมื่อมันทำงานกับความเป็นจริงทางกายภาพของรหัสสายในฮาร์ดแวร์


3
ฉันจะไม่เรียก html เป็นภาษาโปรแกรม มันเป็นไวยากรณ์สำหรับเอกสาร
Simon Bergot

3
@Simon มันเป็นจุดที่น่าสนใจ มีพลังการแสดงออกที่หลากหลายสำหรับรหัสที่แตกต่างกันที่เราใช้ รหัสสามารถเขียนเป็นภาษาที่อ่อนแอกว่าภาษาที่แข็งแกร่งกว่าหรือภาษาของมันเอง
Ben Haley

5

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

โครงการสุดท้ายของฉันเกี่ยวกับเรื่องนี้คือหน้าจอ ASP.NET CRUD พื้นฐานบางอย่าง (การสร้างรหัสนั้นดีสำหรับสิ่งนี้) กระบวนการได้กำหนดเอนทิตีเป็นเมทาดาทาในไฟล์ xml เขียนเทมเพลตเพื่อครอบคลุมสิ่งประดิษฐ์ต่าง ๆ ที่ต้องการ (คลาสเอนทิตี้, ที่เก็บ, คลาสเซอร์วิส, การควบคุม asp.net, หน้า asp.net เป็นต้น) เรียกใช้กระบวนการสร้างและจัดรูปแบบผลลัพธ์

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

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


5

ที่ บริษัท ของเราเราใช้เครื่องมือบางอย่างที่สร้างคลาส C ++ หรือ C # จริงด้วยข้อมูลที่ดาวน์โหลดจากอินเทอร์เน็ต คลาสเหล่านี้เป็นที่เก็บข้อมูลและมีวัตถุจำนวนมากในรายการ


เช่นโค้ดตัวอย่างที่พบใน IDE บางตัวเช่น Visual Studio เป็นต้น
Jose Faeti

@Jose เครื่องมือของเราเป็นเพียงแอปพลิเคชั่นสำหรับแปลง HTML เป็นคลาส ดังนั้นแทนที่จะดาวน์โหลดข้อมูลทุกครั้งที่แอปพลิเคชั่นเริ่มต้นขึ้นเราจะดาวน์โหลดหนึ่งครั้งและสร้างคลาสขึ้นมา
Holli

5

Metaprogramming เป็นส่วนหนึ่งของการเขียนโปรแกรมมาเป็นเวลานาน พิจารณาไม่ใช่แค่เครื่องมืออย่าง SWIG หรือ WYSIWYG ซึ่งสร้างรหัส แต่ยังเป็นเครื่องมือในภาษาเช่นตัวประมวลผลล่วงหน้าของ C หรือแม้แต่แม่แบบของ C ++ และแม่แบบของ C ++ และ generics ของ C # / Java ไม่ต้องพูดถึง Reflection

ในความเป็นจริงคุณสามารถยืนยันว่าคอมไพเลอร์ทุกตัวเป็นเพียง metaprogram อื่นที่พวกเขาใช้ในโปรแกรมข้อความและเครื่องส่งออกหรือรหัส VM และชีวิตที่ไม่มีคอมไพเลอร์? Owch


ถูกต้องแล้ว แต่คุณจะใช้งานจริงในภาษาโปรแกรมของคุณเองอย่างไรเพื่อเพิ่มประสิทธิภาพของคุณ? นั่นคือสิ่งที่ฉันขาดหายไป
Jose Faeti

5

นี่เป็นตัวอย่างที่ชัดเจนจากอดีตของฉัน

ฉันทำงานที่ไซต์ที่มีซอร์สโค้ด Delphi ประมาณ 50MB โดยใช้ BDE สำหรับการเข้าถึงข้อมูล พวกเขาต้องการเปลี่ยนไปใช้ Direct Oracle Access เพื่ออนุญาตให้อัพเกรด Oracle รุ่นที่ผ่านมาซึ่งรองรับโดย BDE (8i ถ้าฉันจำได้ถูกต้อง)

ดังนั้นแทนที่จะให้ทีมงานผู้เขียนโค้ดทำงานผ่านทุกรูปแบบและโมดูลข้อมูลเปลี่ยนทุกองค์ประกอบด้วยตนเองฉันเขียนสคริปต์ PERL ที่: -

  1. แยกวิเคราะห์ DFM (ไฟล์ฟอร์ม) และระบุ TQuery, TTable, TStoredProcedure & TDatabase ทั้งหมด - จัดเก็บรายการในรายการ

  2. แยกวิเคราะห์ PAS (รหัส) และระบุการใช้งานของวัตถุ - TQueries กำลังทำการปรับปรุงหรือเลือกอยู่หรือไม่? นอกจากนี้ยังระบุวัตถุใด ๆ ที่สร้างขึ้นในรหัสแทนที่จะวางลงบนแบบฟอร์มใน IDE

  3. เขียน DFM & PAS ใหม่ให้เปลี่ยนประเภทวัตถุอย่างเหมาะสม (เช่น TTable -> TOracleDataSet ด้วยคุณสมบัติ SQL set เป็น "select * from" etc) และการเรียกเมธอด นอกจากนี้ยังมีการเพิ่มการเรียกเมธอดพิเศษหากเหมาะสมเพื่อปิดเปิดและตั้งค่าพารามิเตอร์

ในระยะสั้น 3 สัปดาห์ทำงาน tweaking สคริปต์เพื่อทำงานกับแอปพลิเคชันต่าง ๆ ที่เขียนโดยทีมต่าง ๆ ที่มีรูปแบบการเข้ารหัสที่แตกต่างกันแทนการประเมินดั้งเดิมของนักพัฒนา 5+ ที่ทำงานเป็นเวลา 6 เดือน

และเหตุผลที่ฉันคิดว่าใช้วิธีการนั้นก็คือการอ่านThe Pragmatic Programmer


เยี่ยมมากตอนนี้ฉันเข้าสู่ Perl ตั้งแต่สองสามวันและฉันได้สร้างเครื่องมือเพิ่มประสิทธิภาพเพื่อสร้างพื้นที่ทำงานพื้นฐานสำหรับการพัฒนาเว็บพร้อมไดเรกทอรีไฟล์และอื่น ๆ ทั้งหมดเพียงแค่พิมพ์ "สร้างพื้นที่ทำงาน"! :)
Jose Faeti

1
@Jose นั่นคือความคิด ใช้ภาษาสคริปต์เพื่อทำให้ข้อมูลซ้ำ ๆ โดยอัตโนมัติ อาจเป็นเพียงครั้งเดียวที่คุณได้รับการเพิ่มประสิทธิภาพการผลิต 8x หรือในกรณีของคุณสิ่งที่ใช้เวลานานที่คุณจะทำอีกครั้ง & อีกครั้ง
mcottle

4

คุณขอตัวอย่าง ...

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

ตัวอย่างเช่นก่อนที่ DATE ชนิดข้อมูลจะถูกนำไปใช้กับเซิร์ฟเวอร์ MS SQl ทางเลือกเดียวสำหรับคอลัมน์วันที่คือ DATETIME ซึ่งมีส่วนเวลา - ส่วนเวลาที่ทำให้การจัดการกับข้อมูลนั้นยากขึ้นเล็กน้อย เมื่ออัปเกรดเป็นรุ่นที่มีชนิดข้อมูลวันที่คุณอาจต้องการอัปเดตคอลัมน์ที่มีเวลา 00:00 เสมอ ในฐานข้อมูลที่มีคอลัมน์ DateTime หลายสิบหรือหลายร้อยคอลัมน์สิ่งนี้จะใช้เวลาค่อนข้างนาน แต่มันง่ายในการเขียนสคริปต์ที่สืบค้นทุกตารางตรวจสอบทุกคอลัมน์ด้วยชนิดข้อมูลของ DATETIME เพื่อดูว่าเป็นเวลาใดก็ได้ยกเว้น 00:00 น. และถ้าไม่สร้างคำสั่ง ALTER เพื่อเปลี่ยนตาราง / คอลัมน์ ประเภทข้อมูลถึง DATE โอมเพี้ยงรหัสที่เขียนรหัส


3

ลองดูที่มาโคร CL (Common Lips) ในความคิดของฉันนั่นคือสิ่งที่คุณต้องการ ริมฝีปากสมบูรณ์แบบในการเขียนโปรแกรม

นอกจากนี้ฉันขอแนะนำNemerleถ้าคุณต้องการมีอำนาจ. NET ด้วยการสนับสนุน Metaprogramming ที่สมบูรณ์แบบ (รวมถึงมาโคร)

แต่ถ้าคุณต้องการเอ็นจิ้นการสร้างรหัสที่แท้จริงลองดูApache ความเจริญรุ่งเรือง


3

ฉันแค่ทำงานกับเครื่องมือดังกล่าว ในกรณีของเราโดยเฉพาะเราสร้างรหัส VB.NET ตามชั้นข้อมูลบนลายเซ็นของฟังก์ชันในฐานข้อมูล

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

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

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

หวังว่าจะช่วย
IPP


ขอบคุณสำหรับคำตอบ! กฎในตัวอย่างของคุณมีการนำไปใช้จริงอย่างไร
Jose Faeti

1
ฉันไม่สามารถบอกกฎทั้งหมดให้คุณได้ แต่ฉันสามารถยกตัวอย่างให้คุณได้ เราวิเคราะห์ส่วนต่อประสานที่เปิดเผยโดยฐานข้อมูล oracle และเราคำนึงถึงลายเซ็นของฟังก์ชั่นในส่วนต่อประสาน oracle ขึ้นอยู่กับลายเซ็นที่เราสร้างชื่อของฟังก์ชั่นชั้นข้อมูล เรารู้ว่าเรามักจะได้รับจาก db ฐานข้อมูล oracle จากผลลัพธ์ที่เราวิเคราะห์และบันทึกลงในอาร์เรย์ของประเภทวัตถุพิเศษที่เราใช้เพื่อเก็บข้อมูลของเรา นอกจากนี้ยังขึ้นอยู่กับพารามิเตอร์อินพุต / เอาต์พุตของลายเซ็นของฟังก์ชั่นฐานข้อมูลที่สอดคล้องกันเราเพิ่ม input และ output พารามิเตอร์ให้กับฟังก์ชั่นที่เราสร้างและอื่น ๆ ..
อีวอนพอล Pirau

3

ฉันมีโมดูล PHP ซึ่งแสดงผลหน้าเว็บที่มีรหัส JavaScript ซึ่งสร้าง HTML นั่นคือสามชั้นตรงนั้น เด็กชายอ่านยากมาก!

ในคลาสการเขียนโปรแกรมเราต้องเขียนโปรแกรมที่จะใช้สตริงสูตรจากผู้ใช้แล้วแยกวิเคราะห์และแสดงค่า ตัวแก้ปัญหาที่น่าประทับใจที่สุดเพียงนำอินพุตผู้ใช้มารวมไว้ในmain () {printf ("% d", ... );}และเรียกใช้สคริปต์เพื่อคอมไพล์ลิงก์และรัน เขาไม่ได้เขียนโปรแกรมแยกวิเคราะห์! วันนี้คุณสามารถทำได้ในคำสั่ง SQL SELECT

มันเป็นเครื่องมือที่คุณควรเล่นด้วยจากนั้นเก็บมันไว้ในวันข้างหน้าเมื่อมันจะมีประโยชน์


นั่นคือสิ่งเดียวกันกับที่ฉันพยายามนำไปใช้! :) แต่ฉันก็ตัดสินใจที่จะเขียนมันด้วย Perl แบบออฟไลน์และมันใช้งานได้ดี ฉันมีฟีเจอร์มากมายที่ฉันคิดจะเพิ่ม!
Jose Faeti

ฉันกำลังเขียนโค้ดที่มีภาษามากถึง 20 เลเยอร์เพื่อการแปลงภาษาโดยไม่มีปัญหาเลย ไม่ซับซ้อนกว่าการมี call call ที่มีความลึก 20 ชั้น ดังนั้นฉันจึงไม่เห็นด้วยอย่างยิ่งว่ามันเป็นเครื่องมือในการ " เก็บมันไว้ในวันข้างหน้าเมื่อมันจะมีประโยชน์ " - การสร้างโค้ดนั้นมีประโยชน์เสมอ
SK-logic

3

ผมได้พัฒนาเรียบร้อยmeta-การเขียนโปรแกรมการแก้ปัญหาด้วยการเปิดฉาก โดยที่แอปพลิเคชันหลัก (ใน C ++ บอกว่า) แปลคำจำกัดความที่เป็นนามธรรมของปัญหาให้เป็นแอปพลิเคชัน Prolog ที่รันไทม์ซึ่งจะมอบหมายให้ บ่อยครั้งที่การเขียนฟังก์ชันการทำงานที่เทียบเท่าใน C ++ จะใช้เวลาตลอดไป

ฉันคิดว่าสถานการณ์นี้เป็นกรณีที่ยอดเยี่ยมในการโต้แย้งการเขียนโค้ด


3

คุณคิดยังไงกับเรื่องนี้?

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

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

ในเว็บไซต์การโต้ตอบส่วนใหญ่หมุนรอบสี่การกระทำหลัก:

  • สร้างองค์ประกอบ
  • ดึงชุดขององค์ประกอบ (ที่มีตัวกรองที่เป็นไปได้)
  • อัปเดตองค์ประกอบด้วยแอตทริบิวต์ใหม่
  • ลบชุดองค์ประกอบ

อย่างน้อยทุกอย่างที่หมุนรอบการกระทำหลัก 4 อย่างนี้และ IMHO ควรทำได้โดยใช้เครื่องมือการสร้างรหัสเพื่อให้ได้ผลผลิตสูงสุด

ใน บริษัท ของฉันเราใช้ symfony และผู้ดูแลระบบตัวสร้างเป็นเครื่องมือที่ยอดเยี่ยมที่แม้แต่สร้างรหัสในเวลาทำงาน (และแคช) ซึ่งหมายความว่าเราไม่จำเป็นต้องใช้งานหรือเครื่องมือภายนอกใด ๆ สร้างรหัสใหม่เราแค่ต้องล้างแคชของเรา ฉันแนะนำให้ใช้เครื่องมือชนิดนี้สำหรับการดำเนินงาน CRUD อย่างจริงจัง

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

เป็นสิ่งที่จะเพิ่มประสิทธิภาพการทำงานของคุณหรือไม่

ฉันเชื่อว่า metaprogramming มีความสำคัญมากในระดับต่ำกว่าของงาน (กรอบ, แคช, คอมไพเลอร์, ฯลฯ ) แต่สิ่งที่เราต้องเข้าหาด้วยความระมัดระวังมากถ้าเราทำสิ่งต่าง ๆ ในชั้นธุรกิจ

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

มีแหล่งข้อมูลที่ดีในเรื่องอะไรบ้างในหนังสือบล็อกบล๊อคสไลด์ ฯลฯ

ทรัพยากรที่ดีที่สุดที่จะเข้าใจการเขียนโปรแกรมมักจะเป็นซอร์สโค้ดที่ดีและมีความคิดเห็นดี ฉันจะบอกว่าการมองหาเครื่องกำเนิดไฟฟ้าRubyOnRailsและSymfonyเป็นความคิดที่ดี


3

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

คอมไพเลอร์ใด ๆ (หรือ meta-program, ตัวสร้างโค้ด, นักแปล, ระบบมาโคร, ... ) ทำงานร่วมกับการแปลงสร้างเอาต์พุตจากอินพุตโดยดำเนินการอัลกอริธึมคงที่ของการเปลี่ยนแปลง แต่คอมไพเลอร์แบบดั้งเดิมหรือโปรแกรมเมตาไม่ได้ให้คำนิยามคำอธิบายหรือตัวอย่างของสิ่งที่เรียงลำดับรายการคือ (เช่น [5, 3, 9] => [3,5,9] สร้างอัลกอริทึมการเรียงลำดับ ปัญหาดังกล่าวซึ่งเป็นที่สนใจของช่อง "การเขียนโปรแกรมอัตโนมัติ" นี้

[1] - รายงานความคืบหน้าเกี่ยวกับระบบการทำความเข้าใจกับโปรแกรม ftp://db.stanford.edu/pub/cstr/reports/cs/.../CS-TR-74-444.pdfShare


2

การเขียนโปรแกรม Meta สามารถทำได้ยากมาก ตอนแรกมันดูดี แต่เมื่อคุณเริ่มทำงานในกรณีมุม, ข้อผิดพลาดจะถูกสาย (ในรหัสที่สร้างขึ้น) และสิ่งทั้งหมดกลายเป็นฝันร้ายที่จะใช้ / debug

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


รหัสใด ๆสามารถรักษาได้ยากมาก และอาจเป็นเรื่องง่ายหากทำในสิ่งที่ถูกต้อง Metaprogramming สามารถเพิ่มความสามารถในการบำรุงรักษาตามลำดับความสำคัญในความเป็นจริง ดูเหมือนว่าประสบการณ์ของงูหลามจะไม่เกี่ยวข้องกับการเขียนโปรแกรมจริงเนื่องจาก Python ไม่เหมาะกับวิธีคิดเช่นนี้ด้วย AST ที่ลึกเกินไป แต่ถึงแม้จะใช้ Python ฉันก็ใช้ห้องสมุด Tempita ที่มีประสิทธิภาพสูงและไม่เคยมีปัญหาการบำรุงรักษาแม้แต่กับทีมที่ไม่มีประสบการณ์ Python มาก่อน
SK-logic

ฉันสนใจประเด็นของคุณเกี่ยวกับ python AST คุณใช้ tempita เพื่อวัตถุประสงค์ในการเขียนโปรแกรมเมตา
Simon Bergot

นี้ ( docs.python.org/library/ast.html ) ค่อนข้างเป็น ad hoc AST และ parser จะให้ต้นไม้ที่ไม่ได้ถูกทำให้ยุ่งเหยิงเกินไปซึ่งทำให้การวิเคราะห์มีปัญหา (โดยเฉพาะอย่างยิ่งเมื่อขาดการจับคู่รูปแบบที่เหมาะสมใน Python) การสร้าง AST นั้นไม่สะดวกเช่นกัน ฉันใช้ tempita สำหรับการผลิตทั้งรหัส Python และ C (เช่น metaprogramming แบบข้อความล้วน) มันทำงานได้ดีสำหรับงานเฉพาะนั้น (การสร้างรหัสสำเร็จรูป) ฉันมักจะใช้ Python เพื่อสร้างรหัส C จากคำอธิบายระดับสูง XML บางคำ
SK-logic

2

OP ขอทรัพยากร

คุณอาจพบว่าDMS Software Reengineering Toolkitน่าสนใจ เป็นเครื่องมือ metaprogramming ที่บริสุทธิ์โดยมีจุดประสงค์เพื่อให้ผู้ใช้สามารถสร้างการวิเคราะห์โปรแกรมและเครื่องมือการแปลงแบบกำหนดเองได้

[ในการติดตามความคิดเห็นต่อคำถามของ OP เมื่อใช้เพื่อสร้างเครื่องมือการแปลงเฉพาะ DMS คือสายผลิตภัณฑ์ที่เขียนโค้ดซึ่งเขียนโค้ด:]

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

และเช่นเดียวกับระบบปฏิบัติการ DMS ได้รับการออกแบบมาให้มีความคิดเห็นหรือข้อ จำกัด น้อยมากเกี่ยวกับโปรแกรม (meta) ที่คุณต้องการเขียนซึ่งหมายความว่ามันสามารถใช้สำหรับวัตถุประสงค์ที่หลากหลาย: การแยกตัวชี้วัดการค้นหารหัสที่ตายแล้ว langauges, สร้างรหัสจาก DSL, สร้างแอปพลิเคชันขนาดใหญ่ใหม่ (DMS ถูกใช้ไปแล้วสำหรับงานเหล่านี้ทั้งหมด)

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


2

ดูที่ปัญหาของ Philip Greenspun ชุดที่ 4 จากหลักสูตร MIT 6.916: วิศวกรรมซอฟต์แวร์ของนวัตกรรมการบริการบนเว็บ ( http://philip.greenspun.com/teaching/psets/ps4/ps4.adp )

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

นี่เป็นหนึ่งในปัญหาที่กำหนดให้มีการชักชวน ArsDigita ( http://en.wikipedia.org/wiki/ArsDigita ) ที่มีศักยภาพจำเป็นต้องแก้ปัญหาในช่วงฟองแรก

หนังสือ "SQL for Web Nerds" อ้างอิง Philip ใน pset ถูกย้ายไปที่ ( http://philip.greenspun.com/sql/ )


2

ในหรือราวปี 2544 ฉันเริ่มทำงานในโครงการที่ใช้งานวัตถุธุรกิจและวัตถุข้อมูลอย่างกว้างขวาง ฉันจะสร้างเว็บไซต์ Front-end แต่ถูกวางสายสองนิ้วหัวแม่มือของฉันเพราะชั้นธุรกิจและชั้นการเข้าถึงข้อมูลไม่ได้รับการพัฒนาอย่างเต็มที่ หลังจากสองสามสัปดาห์ที่ผ่านมาฉันเริ่มที่จะดูอย่างหนักว่าเลเยอร์เหล่านั้นกำลังทำอะไรอยู่ โดยพื้นฐานแล้วพวกเขากำลังเปิดเผยข้อมูลที่ส่งคืนจากกระบวนงานที่เก็บไว้เป็นชุดของวัตถุที่มีคุณสมบัติที่สอดคล้องกับเขตข้อมูลในข้อมูลหรือกำลังรับพารามิเตอร์ป้อนเข้าและส่งไปยังกระบวนงานที่เก็บไว้เพื่อบันทึกไว้ในตารางฐานข้อมูล serialization / deserialization เกิดขึ้นระหว่างสองเลเยอร์มี Microsoft Transaction Server ที่เกี่ยวข้องไลบรารีไลบรารี่ IDL / ODL ... แต่มันพอดีกับแพทเทิร์น

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

เครื่องมือสร้างโค้ด (เครื่องมือระดับล่าง) ติดตามฉันผ่านการวนซ้ำหลายครั้งเป็นเวลาประมาณ 8 ถึง 10 ปีเพราะหลักการเรียบง่ายมาก: คุณกำลังทำสิ่งที่ต้องทำเมื่อพูดคุยกับฐานข้อมูลมันค่อนข้างดี การเขียนโค้ดซ้ำ ๆ มากและเมื่อคุณได้รับสิทธิคุณไม่ต้องกังวลกับมันอีกต่อไป

ดังนั้นใช่: ใช้ตัวสร้างโค้ดโดยเฉพาะอย่างยิ่งเมื่อการเข้ารหัสซ้ำและเหมาะกับรูปแบบที่กำหนดไว้อย่างดี

ฉันรู้จักคนใช้แมโคร RegX เพื่อทำสิ่งที่คล้ายกันหรือใช้สูตร Excel เพื่อทำสิ่งที่คล้ายกัน (ฉันทำสิ่งนี้ด้วย)


2

ตัวอย่าง metaprogramming

ฉันมีไลบรารี่การอนุญาต Ruby ชื่อว่าAuthority มันช่วยให้นักพัฒนาถามคำถามใน app ของพวกเขาด้วยวิธีการเช่นและcurrent_user.can_read?(@post) @post.readable_by?(current_user)คำถามเหล่านี้ได้รับคำตอบจากคลาสผู้อนุมัติส่วนกลาง

นี้เป็นส่วนที่สำคัญ: ผู้มีอำนาจไม่ทราบว่าวิธีการที่จะกำหนดจนกว่าจะเห็นการตั้งค่าของผู้ใช้ การกำหนดค่าผู้ใช้อาจมี:

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}

current_user.can_microwave?(@post)ในกรณีที่จำเป็นต้องมีวิธีการเช่น

Metaprogramming ทำให้เป็นไปได้: หลังจากอ่านการกำหนดค่าฉันรู้วิธีการกำหนด :

Authority.verbs.each do |verb|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1 # allows for a nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  RUBY
end
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.