ก่อนอื่นเลย เราไปดูความหมายของ Meta programming จากใน wikipedia กันก่อน
Metaprogramming is a computer programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyse, or transform other programs, and even modify itself, while running.
แปลเองแล้วงง ลองให้ AI แปลดูซิ
Metaprogramming คือ เทคนิคในการเขียนโปรแกรมคอมพิวเตอร์ ซึ่งโปรแกรมสามารถจัดการกับโปรแกรมอื่น ๆ เหมือนข้อมูลของตัวเองได้ นั่นหมายถึงโปรแกรมสามารถออกแบบให้สามารถอ่าน สร้าง วิเคราะห์ หรือแปลงโปรแกรมอื่น ๆ และ ในบางกรณี สามารถปรับเปลี่ยนตัวเองขณะที่กำลังทำงานได้
ไม่ได้ช่วยเท่าไหร่เลย ผมลองอธิบายแบบบ้านๆดีกว่า
อย่างเวลาเราเขียนโปรแกรม เราก็จะประกาศตัวแปร หรือ function หรือ class ขึ้นมาเพื่อแก้ปัญหาอะไรสักอย่าง ในภาษาอย่าง Java หรือ Typescript ก็ถือเป็น object ประเภทหนึ่ง เราสามารถเข้าถึงข้อมูลบางอย่างได้ เช่น ชื่อ หรือถ้าฟังก์ชั่นก็จะดู input arguments ได้ เป็นต้น ซึ่งการเข้าถึงข้อมูลพวกนี้เรียกว่า metadata ก็เลยเป็นที่มาของ meta programming นี่แหละครับ
ยกตัวอย่างที่เราพอได้ใช้กันอยู่บ้าง เช่นการใช้ Object.hasOwnProperty()
เราสามารถที่จะเรียกดูรายชื่อ proterty ใน object ได้ด้วยการใช้ Object.keys
เข้าถึง property descriptor ด้วย Object.getOwnPerpertyDescriptor()
แก้ไขข้อกำหนดบางอย่างของตัว property ด้วย Object.defineProperty() อย่างเช่น ไม่อนุญาตให้แก้ไข
ลองเล่นกับ Decorator
ปกติแล้ว เราจะเป็นผู้ใช้งาน decorator กันซะมากกว่า ในหลายๆ framework เช่น Angular (แล้วเราก็เรียกมันว่า magic 😂)
ซึ่ง magic ที่ว่านี่ก็คือการใช้ประโยชน์จากการเข้าถึง meta data ได้นั่นแหละ
ลองมาดูหน้าตาของ decorator ใน TypeScript กัน ก่อนอื่นต้องรู้ก่อนว่าจะเอา decorator ไปวางไว้ที่ไหน เช่น class หรือ method
เอาง่ายๆก็ method ก่อน สมมติว่าเราจะสร้าง decorator ชื่อ log
วิธีใช้งานก็เอาไปวางบนหัว method แบบนี้
แน่นอนว่าตัว decorator ยังไม่ได้ทำอะไรเลย ดังนั้นเรามาดูกันต่อว่าทำอะไรกับมันได้บ้าง
สมมติว่า เราอยากจะทำการ log ทุกครั้งที่มีการเรียก method เราก็จะต้องทำการ decorate ก่อน ที่จะเรียก method จริงๆ
ที่นี้จะทำได้ยังไง ก็ผ่านตัว descriptor นั่นแหละ หน้าตามันก็คล้ายๆกับที่เล่าไปในตอนแรก
ใน descriptor มันจะมี property ตัวนึงชื่อ value ให้เราสามารถย่ำยีได้ตามใจชอบ ดังนั้น เราก็จะสร้าง function มาครอบของเดิม เพื่อให้มัน log ก่อน แล้วค่อยไปเรียกตัว method จริงๆ
ลองใช้งานดู ก็จะพบว่า จะมีการ log ทุกครั้งที่เรียกฟังก์ชั่น
แน่นอนว่า เราสามารถ เข้าถึงได้มากกว่าชื่อ functtion จะ log input arguments ก็ทำได้เช่นกัน
ที่นี้ก้ไม่ต้องคอยใส่ log เข้าไปทุก method แล้ว
อันนี้ก็ตัวอย่างที่เราเอาไปใช้ได้นะครับ เรื่อง metaprogramming ยังมีให้ศึกษาอีกเยอะมากเลย เป็นเครื่องมืออีกอันที่หยิบมาใช้ทำให้ชีวิตดีขึ้นได้ครับ ทำให้เข้าใจมากขึ้นเวลาไปใช้ framework ต่างๆด้วย ว่า magic แต่ละอันมันมาได้ยังไงด้วย 😎
จบไว้ประมาณนี้ก่อนะครับ ถ้ามีโอกาสจะมาเล่าเคสที่ซับซ้อนมากขึ้นอีกนิด
Top comments (0)