แมโครถูกขยายเมื่อรวบรวมไฟล์หรือไม่?


13

ฉันมีมาโครที่ต้องขยายในทุก ๆ อินสแตนซ์ของการใช้งานคอมไพล์เวลา มีวิธีที่ฉันสามารถระบุให้เป็นเช่นนั้นโดยไม่ต้องผ่าน codebase และตัดสายแต่ละอย่างด้วยeval-when-compileหรือไม่

คำตอบ:


13

แมโครทั้งหมดที่เข้าถึงได้โดย byte-compiler จะถูกขยายระหว่างการคอมไพล์ "Reachable" หมายถึงไม่มีการอ้างถึง

เนื้อความของdefuns, defmacros, lambdas ทั้งหมดถูกคอมไพล์ด้วยไบต์เมื่อไฟล์ต้นฉบับที่มีอยู่นั้นถูกคอมไพล์ด้วยไบต์ ใช่แล้วแมโครใด ๆ ในตัวพวกมันจะถูกขยายออกไปตราบใดที่มันไม่ได้อยู่ในเครื่องหมายคำพูด ( ') ความผิดพลาดที่พบบ่อยมากคือการห่อlambdaในใบเสนอราคาและในความเป็นจริงที่ว่าทำไมคุณควรไม่เคยพูดของคุณlambda s

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


7

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

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

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

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

นิยมใช้แมโครสำหรับการทำงานปูถนนไปยังนรกพึ่งพา


จุดที่ดีมากที่ต้องคำนึงถึงเมื่อเขียนหรือใช้มาโคร
ฌอน Allred

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

@ Malabarba สนใจที่จะให้รายละเอียด?
Lunaryorn

@ lunaryorn คุณไปแล้ว ปัญหาเล็กน้อยที่น่ารังเกียจ
Malabarba

1
@ lunaryorn ฉันยอมรับว่าแมโครเป็นสิ่งที่อันตราย (ฉันจะแก้ไขคำตอบของฉันเพื่อให้ได้เสียงที่น่าชื่นชมน้อยลง :) แต่ฉันไม่คิดว่าข้อผิดพลาดนั้นเป็นตัวอย่างที่เฉพาะเจาะจงของมัน ข้อผิดพลาดนั้นมีอาการอื่น ๆ (ทำให้รุนแรงน้อยลง) ที่ไม่เกี่ยวข้องกับมาโครเลย มันยังทำให้เกิดปัญหากับการพึ่งพาฟังก์ชั่น
Malabarba
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.