เกริ่นนำ
Mumps แปลว่า โรคคางทูม เป็นโรคติดต่อทางระบบทางเดินหายใจ เกิดจากการติดเชื้อไวรัส มักพบในเด็กและวัยรุ่น แฮร่! คนละมัมส์
คำว่า MUMPS (มัมส์) อ่านว่า ม้ำ ในที่นี้คือ Massachusetts General Hospital Utility Multi-Programming System เป็นระบบและสภาพแวดล้อมที่มีภาษาโปรแกรมและฐานข้อมูลเป็นของตัวเอง ซึ่งตัวฐานข้อมูลจะเป็น NoSQL แบบ key-value Pair ที่สามารถเก็บค่าใน Value เป็น Key-Value Pair ซ้อนเข้าไปอีกได้ เป็น Hierarchical Structure และภาษาหลัก ๆ ที่ใช้จะเรียกว่าภาษา M
MUMPS เป็นระบบเฉพาะทางสำหรับใช้ในวงการวิทยาศาสตร์การแพทย์ และต่อมานำมาใช้กับระบบธนาคารด้วย เช่น ฐานข้อมูลของธนาคารออมสิน ใครที่เคยใช้แอป mymo จะสังเกตว่าระบบล่มน้อยครั้งมากกกกกกเมื่อเทียบกับแอป Mobile Banking ของธนาคารอื่น ก็เพราะความแข็งแกร่งของเจ้า YottaDB ที่ใช้ภาษา M ในการจัดการฐานข้อมูล เนื่องจาก YottaDB มีระบบการทำ Indexing ที่ดีเยี่ยม ทำให้ Query ข้อมูลมหาศาลได้อย่างรวดเร็ว และรองรับการทำ DB Transaction แบบ Real-Time ได้ แม้ในกรณีที่มีลูกค้าแย่งกันใช้จน Load สูงมาก Server ก็ยังรับไหว
ว้าว! ชักอยากรู้รายละเอียดเพิ่มเติมแล้วสิว่า นอกจาก M/MUMPS จะเป็นรากฐานของการพัฒนาระบบของ YottaDB แล้วมันสามารถเอาไปต่อยอดอะไรได้บ้าง และจะใช้ภาษา M กับ YottaDB ได้ยังไงบ้าง ไปอ่านกันเลย!
ขอบคุณภาพประกอบจาก https://www.medpagetoday.com/special-reports/exclusives/97350
ประวัติคร่าว ๆ ของ M/MUMPS
MUMPS หรือ M พัฒนาขึ้นในปีค.ศ. 1966 โดย Neil Pappalardo และคณะที่แล็บของ Octo Barnett ในรพ. Massachusetts General Hospital (MGH) ในยุคแรกมีสถาปัตยกรรม PDP-7 รูปแบบเดียวกับ Unix และมีการพัฒนาอย่างต่อเนื่องมาโดยตลอดจนใช้งานได้บนหลากหลายสถาปัตยกรรม และกลายมาเป็นรากฐานของแอปพลิเคชันด้านวิทยาศาสตร์สุขภาพที่ใช้งานบนคอมพิวเตอร์
ข้อดีของ MUMPS
- สามารถทำงานกับ Big Data ได้อย่างมีประสิทธิภาพสูงกว่า RDBMS หลายเจ้า ทั้งด้าน Performance และ Throughputs
- เป็นฐานข้อมูล NoSQL แบบ Key-Value Pair และมี คุณสมบัติ ACID (Atomic, Consistent, Isolated, Durable)
- สามารถประมวล String ที่ซับซ้อนได้ และรองรับการทำ Pattern Matching
- ค่าใช้จ่ายต่ำ เพราะสามารถ Scale ได้ง่ายตามการใช้งาน
การนำ MUMPS ไปใช้
- YottaDB: ฐานข้อมูลแบบ NoSQL key-value pair ด้วยความสามารถในการรองรับ Load ที่สูง รองรับการทำงานแบบ Real-Time และมีความปลอดภัยสูง จึงเหมาะสำหรับธนาคารและโรงพยาบาล
- FIS GT.M: เป็นฐานข้อมูล Key-Value Pair ที่ปรับปรุงมาให้รองรับภาคอุตสาหกรรมและภาคธุรกิจ รองรับการประมวลผลการทำธุรกรรมจำนวนมากได้อย่างต่อเนื่องและมีประสิทธิภาพ
- Reference Standard M (RSM): เป็นฟรีซอฟต์แวร์ที่นำภาษา M และฐานข้อมูลไปปรับปรุงโดย Raymond Doudlas Newman ใน Version แรก เพื่อให้สอดคล้องตามมาตรฐานที่ M Development Committee (MDC) เผยแพร่ออกมา ปัจจุบันคือมาตรฐาน ANSI/MDC X11.1-1995 (ISO/IEC11756:1999)
- FreeM: เป็นการปรับปรุงความสามารถของภาษา M ให้มีขนาดเล็กลง เข้าใจง่ายขึ้น และรองรับระบบปฏิบัติการหลากหลายขึ้นจากเดิมได้แค่ UNIX และสามาถใช้งานร่วมกับภาษา C ได้
- MiniM: เป็นฐานข้อมูลที่พัฒนาจาก MUMPS เป็นระบบจัดการฐานข้อมูลแบบ Client/Server ภายใต้มาตรฐาน ANSI-1995 X.11 รองรับการทำงานการภาษาโปรแกรมฝั่ง Client ที่หลากหลาย เช่น C++, Java, C#
- M21: เป็นบริษัทที่พัฒนาภาษา M และฐานข้อมูลเพื่อใช้งานในศตวรรษที่ 21 สามารถใช้งานกับภาษา PHP และ XML ได้ด้วย
- GPL Mumps: เป็น Packages Source Code สำหรับ Linux และ Cygwin (สำหรับ Microsoft Windows) ภายใต้ GPL V2 license ประกอบด้วย Mumps Interpreter, Compiler, รวมทั้ง Library สำหรับภาษา C++ นอกจากนี้ยังรองรับการทำงานร่วมกับ MySQL และ PostgreSQL อีกด้วย
ทำความรู้จักภาษา M กันเถอะ
ภาษา M ก็คืออีกชื่อหนึ่งของ MUMPS แค่เรียกให้สั้นลงเฉย ๆ ในที่นี้คนละภาษากับภาษา M สำหรับ Power Query นะ !!! แค่บังเอิญย่อว่า M เหมือนกัน
มาเริ่มกันที่ลักษณะของภาษา M กัน
- เป็นภาษาที่จำเป็นไม่ต้องประกาศตัวแปรก่อนใช้ จะใช้เมื่อไหร่ค่อยประกาศ
- เป็นภาษาที่มีข้อมูลชนิดเดียวคือ String แต่สามารถปรับเปลี่ยนรูปแบบการดำเนินการได้ตามบริบท กล่าวคือ
- คำนวณตัวเลขได้ทั้งจำนวนเต็มและเลขติดทศนิยม
- ค่าความจริงจะใช้ 1 แทนจริงและ 0 แทนเท็จ
- สามารถตั้งชื่อตัวแปรได้
- ตัวแปรเป็น Dynamic Type สามารถเปลี่ยนชนิดค่าที่เก็บได้
- ตัวแปรสามารถแปลงค่า (Type Casting) ได้
- มีตัวแปรทั้ง Local Variable และ Global Variable แต่มีข้อแตกต่างจากภาษาอื่น ตรงที่
- Local Variable จะสร้างตัวแปรมาเก็บไว้บน Stack Memory และจะหายไปเมื่อ Quit Process
- Global Variable จะบันทึกข้อมูลลงบน disk จึงคงอยู่ตลอดไป ไม่หายไปแม้ Quit Process ไปแล้ว ใช้ในการทำตารางในฐานข้อมูลได้
- ข้อมูลที่เก็บด้ใน 1 ตัวแปรเป็น Array ก็ได้เช่นกัน
- นอกจากจะสามารถ Assign ค่าให้ตัวแปรได้แล้วยังสามารถ
- Print ค่าออกมาดู
- กำหนดเงื่อนไข if else
- การทำซ้ำแบบ for loop, while loop
- สร้างฟังก์ชัน
- และอื่น ๆ อีกมากมาย
- อย่าเว้นวรรค Indent หรือ Enter มั่วซั่ว เพราะจะทำให้ Code Error ได้ การเว้นวรรคแต่ละครั้งมีผลกับลำดับการทำงานและ Block Scope ด้วย
- เป็นภาษาที่ Case-Sensitive ระมัดระวังการใช้งานด้วยนะ
- ภาษา M เป็นภาษาที่เขียน 1 บรรทัดแล้ว Enter คือทำงานเลย ถ้าอยากเขียนฟังก์ชันหรือเขียนคำสั่งหลาย ๆ บรรทัดค่อยทำงานทีเดียว ให้สร้างไฟล์นามสกุล .m ต่างหากแล้วค่อย Run File นั้น
- ไม่มีการทำ Error Handling แต่มี Best Practice ในการเขียนโปรแกรมเพื่อป้องกันไม่ให้เกิด error
27 เรื่องที่ควรรู้และตัวอย่างการใช้งานภาษา M ใน YottaDB
1. การประกาศตัวแปรแบบไม่กำหนดค่าเริ่มต้น
N X
N ย่อมาจาก New ใช้ในการประกาศตัวแปรทางขวาคือ X โดยระหว่าง N กับ X คั่นด้วยเว้นวรรค 1 ครั้ง
2. การ assign ค่าให้ตัวแปร Local Variable
S X=1
- S ย่อมาจาก Set คือการกำหนดค่าให้กับตัวแปรทางขวามือที่คั่นด้วยเว้นวรรค 1 ครั้ง
- X คือชื่อตัวแปรที่เราสร้างขึ้น เป็น Local Variable
- = คือเครื่องหมายที่ใช้ในการ Assign ค่าทางขวาให้กับตัวแปรทางซ้าย ห้ามใส่เว้นวรรคหน้าและหลังของเครื่องหมายเท่ากับ
- 1 คือค่าที่เรากำหนดให้ตัวแปร X จะเห็นว่าเราสามารถกำหนดข้อมูลชนิดตัวเลขให้กับตัวแปรในภาษา M ได้
3. การ print ค่าใน local variable
W X
Ouput: 1
- W ย่อมาจาก Write คือการเขียนค่าของตัวแปรทางขวามือที่คั่นด้วยเว้นวรรค 1 ครั้งออกมาทางหน้าจอ
- W ไม่ได้ใช้แค่เขียนค่าของตัวแปรเท่านั้น เราสามารถใส่ตัวเลขหรือข้อความที่ต้องการแสดงลงไปหลัง W ได้เช่นกัน
- X คือตัวแปรที่ต้องการดูค่า
4. การดูตัวแปรทั้งหมดใน Session ใช้คำสั่ง zwr
zwr
Output: X=1
เราสามารถใช้ zwr ในการดูค่าทั้งหมดใน Array หรือ Tree Of Key-Value Pair ได้เช่นกัน (ขอเรียกย่อ ๆ ว่า Tree)
5. การแจ้ง Error ในภาษา M
W Y
Output: %YDB-E-LVUNDEF, Undefined local variable: Y
ในที่นี้ เราลอง Print ค่าของ Y ทั้ง ๆ ที่ยังไม่เคยประกาศหรือ Assign ค่าให้ตัวแปร Y ตัวโปรแกรมก็จะแจ้ง Error แบบมีสัญลักษณ์เปอร์เซ็นต์นำหน้า แจ้งว่าตัวแปร Y ยังไม่ถูกประกาศเลย
6. การ Assign ค่าใหม่ ชนิดใหม่ทับตัวแปรเดิม
S X=1
W X
Output: 1
X=“Hello”
W X
Output: Hello
- ตอนแรก X เก็บค่า 1 ชนิดเป็นตัวเลข
- เมื่อ print ค่า X ออกมาก็ได้ 1
- ต่อมากำหนดให้ X เก็บค่า “Hello” ชนิดเป็น String แทน
- เมื่อ Print ค่า X ออกมาอีกครั้ง คราวนี้เป็นค่า Hello แล้ว
7. การแปลงชนิดข้อมูล (Type Casting)
S X=“Hello”
W +X
Output: 0
S X=“123Hello”
W +X
Output: 123
- กำหนดให้ X เก็บค่า “Hello” ชนิดเป็น String
- เราสามารถแปลงชนิดข้อมูลจาก String เป็น Int ได้โดยใส่เครื่องหมายบวกหน้าตัวแปรนั้น
- จะเห็นว่าเมื่อใช้ +X โดยที่ X เก็บค่าที่ไม่สามารถแปลงเป็นตัวเลขได้จะได้ผลลัพธ์เป็น 0
- แต่เมื่อกำหนดค่าใหม่ให้ X เป็น String “123Hello” เมื่อใช้ +X ในการแปลงชนิดข้อมูลจะมีแค่ “123” เท่านั้นที่แปลงเป็นตัวเลขได้ คำว่า “Hello” จะถูกตัดทิ้งไป
8. การล้างหน้าจอ เหมือนคำสั่ง cls หรือ clear ใน Windows cmd ที่แค่ clear จอให้โล่ง แต่ค่าในตัวแปรยังอยู่ครบ ใช้คำสั่ง w #
w #
9. การเข้าและออกจากโปรแกรม YDB CLI
ydb
ใช้คำสั่ง ydb ในการเปิดโปรแกรม ydb
h
ใช้คำสั่ง h ที่ย่อมาจาก halt ในการออกจากโปรแกรม
10. การใช้ global variable
S ^ZXX=“Test”
- ตัวแปรที่ต้องการให้เป็น Global Variable ให้ใส่ Arrow Head ไว้หน้าชื่อตัวแปรนั้น ๆ
- วิธีการกำหนดค่าให้ตัวแปร Global Variable ก็เหมือนกับการกำหนดให้ Local Variable คือใช้ S เช่นกัน
11. การ Print ค่าใน Global Variable ออกมา
S ^ZXX=“Test”
h
ydb
w ^ZXX
Output: Test
- การ Print ค่า ใช้ w ตัวพิมพ์เล็ก คล้ายกับตอน Print ค่าของ Local Variable ที่ใช้ W พิมพ์ใหญ่
- จะเห็นว่า เรากำหนดค่า “Test” ให้ตัวแปร ^ZXX แล้วออกจากโปรแกรมไปแล้ว แต่เมื่อกลับเข้าโปรแกรมอีกครั้งแล้วลอง Print ค่าของตัวแปร ^ZXX ออกมา จะพบว่าตัวแปรนั้นยังคงอยู่ ไม่หายไป
- ในการตั้งชื่อ Global นิยมขึ้นต้นด้วย Z แต่ไม่ได้เป็นข้อบังคับ
12. การลบค่าใน Global Variable
k ^ZXX
ใช้ k ย่อมาจาก kill ในการลบตัวแปรและค่าในตัวแปรนั้นออกจากฐานข้อมูล
13. Array
S X(1)=1
S X(2)=1
- ใส่ Key หรือ Index ของ Array ลงไปในวงเล็บด้านหลังตัวแปรที่ต้องการให้เป็น Array และกำหนด Value ที่ต้องการให้ Key นั้นหลังเครื่องหมายเท่ากับ
- ในที่นี้ มองได้ว่า Array X ที่ Index 1 เก็บค่า 1 และ ที่ Index 2 เก็บค่า 1
14. การเพิ่ม Key ใหม่เข้าไปใน Array เดิม จะเป็น Int หรือ String ก็ได้
S X(1)=1
S X(2)=1
S X(“New”)=1
ตอนแรก X มีแต่ key ที่เป็น int คือ 1 กับ 2 กับสามารถเพิ่ม key ใหม่คือ “New” ที่มีชนิด string ได้
15. การเพิ่มชั้นของ key (compound keys) เพื่อสร้าง tree of key-value pair
S X(1)=1
S X(2)=1
S X(“New”)=1
S X(2,1)=1
ตอนแรก X มี Key แค่ชั้นเดียวก็สามารถเพิ่มเป็น 2 ชั้น เหมือนเป็น Array 2 มิติได้
16. การ Print ค่าทั้งหมดใน Array ออกมา ใช้ zwr
S X(1)=1
S X(2)=1
S X(“New”)=1
S X(2,1)=1
S X(1,1)=1
S X(1,4)=1
zwr X
Output:
X(1)=1
X(1,1)=1
X(1,4)=1
X(2)=1
X(2,1)=1
X("New")=1
ไม่ว่าเราจะเพิ่มค่าให้ Key ไหนก่อนหลัง เวลา Print ค่าทั้งหมดใน Array ออกมาจะเรียง Key ให้เสมอตามตัวอักษร จากชั้นน้อยไปชั้นมาก โดย Key ที่เป็นตัวเลขจะมาก่อน String
17. การใส่ค่าหลาย Field ต่อ 1 Key นิยมคั่นด้วยเครื่องหมาย Pipe |
S ^ZNEW(1,1)=“field1|field2|field3”
zwr ^ZNEW
Output: ^ZNEW(1,1)="field1|field2|field3"
18. การดูข้อมูลแค่บาง field ใช้คำสั่ง $P
S ^ZNEW(1,1)=“field1|field2|field3”
w $P(^ZNEW(1,1),”|”,3)
Output: field3
- $P คือ Piece เอาแค่ส่วนหนึ่งของค่านั้น
- จากคำสั่งบรรทัดที่ 2 จะได้ว่าในที่นี้ เรา Write Piece ของตัวแปร ^ZNEW ที่ key (1,1) คั่นด้วย | คือ Pipe เอา Field ที่ 3 จะได้ค่านั้น คือ “field3” ออกมา
19. การขึ้นบรรทัดใหม่ตอน Write ค่า ใช้เครื่องหมายตกใจ ส่วนการ Write หลายค่า ใช้เครื่องหมาย Comma คั่น
w 1,!,2
Output:
1
2
20. การต่อ String (Concatenate) ใช้ เครื่องหมาย Underscore
w “Hello”_“:”_“World”
Output: Hello:World
21. การรับค่าทาง Keyboard ใช้คำสั่ง R
W “Input Name: ” R X
Output: Input Name: 2
- print คำว่า “Input Name: ” แล้วรอรับค่าทาง Keyboard มาเก็บในตัวแปร X แล้วอ่านค่าจากตัวแปร X มารอ
- 2 คือค่าที่รับจาก Keyboard
22. If Else
กรณีที่1 กำหนดให้ X=2 เรากำหนดเงื่อนไขว่า ถ้า X=1 จึงจะเขียนค่า 2 ออกมาจึงไม่มีอะไรเกิดขึ้น
S X=2
I X=1 W 2
กรณีที่ 2 กำหนดให้ X=1 เรากำหนดเงื่อนไขว่า ถ้า X=1 จึงจะเขียนค่า 2 ออกมาจึงแสดงค่า Output เป็น 2
S X=1 I X=1 W 2
Output: 2
กรณีที่ 3 กำหนดให้ X=2 เรากำหนดเงื่อนไขว่า ถ้า X=1 จึงจะเขียนค่า 1 ออกมา แต่ถ้า X มีค่าอื่น ๆ ให้เขียนค่า 2 จึงแสดงค่า Output เป็น 2
S X=2
I X=1 W 1
E W 2
Output: 2
จากทั้ง 3 กรณี สรุปได้ ดังนี้
- If ใช้ I, Else ใช้ E
- สามารถใช้ If อย่างเดียว ไม่ต้องมี Else ก็ได้
- If ใช้เว้นวรรค 1 ครั้งหน้าเงื่อนไขที่ต้องการตรวจสอบ
- Else ใช้เว้นวรรค 2 ครั้งหน้าสิ่งที่ต้องการให้ทำ
23. For Loop
F I=1:1:4 W I+2," "
Output: 3 4 5 6
- F ย่อมาจาก For ตามด้วยเว้นวรรค 2 ที ตามด้วยค่าเริ่มต้น คั่นด้วย Colon ตามด้วยค่าสูงสุด เว้นวรรค 1 ที ตามด้วยสิ่งที่ให้ทำในทุก ๆ Loop
- for I = 1; เพิ่มค่า I ทีละ 1 จนถึง 4; Write I+2 ตามด้วย Space Bar
24. While Loop
F Q:OUT D
- ภาษา M ไม่มี While Loop
- สามารถสร้าง While Loop ได้โดยใช้ For วนภายใต้เงื่อนไขบางอย่างแทนการกำหนดช่วง
- ให้ Loop ใช้ F ตามด้วยวรรค 2 ที ให้ Q คือ Quit หยุด Loop เมื่อค่า OUT เป็น 1 แล้ว D คือ do ให้ทำบางอย่าง ในที่นี้ไม่ได้ให้ทำอะไร
25. การ Traverse ใน Global หรือ Array มีอยู่ 3 คำสั่ง
25.1. $G คือการ Get ของใน Array ออกมา ใช้ Get ของในตัวแปรก็ได้
- ถ้าเรา Write ค่าตัวแปรที่ไม่เคยประกาศและกำหนดไว้จะ Error Undefined ตัวแปรนั้น ๆ
- แต่ถ้าเราใช้ $G มา Get ค่าของตัวแปร Y จะได้ค่าว่าง ๆ แทน Error ดังนั้น ถ้าต้องยุ่งกับ Input จาก User แล้วไม่อยากให้โปรแกรม Error ให้ครอบ $G() ที่ตัวแปรที่ต้องการเอาค่ามาใช้จะปลอดภัยกว่า
W Y
Output: %YDB-E-LVUNDEF, Undefined local variable: Y
W $G(Y)
Output:
25.2. $D คือ Is Defined ดูว่าตัวแปรนั้นมีค่ามั้ย คืนค่าได้ 4 แบบคือ
- 0 ใช้กับ Parameter ที่เก็บแค่ค่าเดียว จะคืนค่าเมื่อ Parameter นั้นไม่มีอยู่จริง
- 1 ใช้กับ Parameter ที่เก็บแค่ค่าเดียว จะคืนค่าเมื่อ Parameter นั้นมีจริงและมีค่า
- 11 ใช้กับ Array หรือตัวแปรประเภทต้นไม้ (Array หลายชั้น) จะคืนค่าเมื่อ Array นั้นมีลูก และเช็คว่าตัวแปรนั้น ๆ เองก็มีค่า
- 10 ใช้กับ Array หรือตัวแปรประเภทต้นไม้ (Array หลายชั้น) จะคืนค่าเมื่อ Array นั้นมีลูก และเช็คว่าตัวแปรนั้น ๆ เองไม่มีค่า
W $D(Y)
Output: 0
S A=4
W $D(A)
Output: 1
S X=1
S X(1)=1
S X(1,1)=1
S X(1,4)=1
S X(2)=1
S X(2,1)=1
S X(3,1)=1
S X("New")=1
W $D(X)
Output: 11
W X(3)
Output: %YDB-E-LVUNDEF, Undefined local variable: X(3)
W $D(X(3))
Output: 10
จากตัวอย่างสรุปได้ ดังนี้
- ตัวแปร Y ยังไม่ถูกประกาศ เมื่อเช็ค Is Defined มั้ยเลยได้ 0 คือตัวแปร Y ไม่มีจริง จึงคืนค่า 0
- ตัวแปร A ถูกประกาศและมีค่า 4 เมื่อเช็ค Is Defined จึงได้ค่า 1 คือตัวแปร A มีจริง จึงคืนค่า 1
- ตัวแปร X เก็บค่า 1 และมีค่าลูกเป็น Key-Value ด้วยคือมี Tree ซ้อนเข้าไปอีก เป็นทั้ง Array และตัวแปรธรรมดา เมื่อเช็ค Is Defined จึงได้ว่าตัว X มีลูกคือ Tree ที่เก็บข้อมูลแบบ Key-Value และตัว X เองก็มีค่าเป็น 1 จึงคืนค่า 11
- ตัวแปร X(3) ไม่ได้เก็บค่า มีเฉพาะส่วนที่เก็บค่าแบบ Key-Value เมื่อเช็ค Is Defined จึงได้ว่าตัว X(3) มีลูกคือ X(3,1) แต่ตัว X(3) เองไม่มีค่า จึงคืนค่า 10
มาดูแผนภาพเพื่อให้เข้าใจมากขึ้น
25.3. $O ใช้กับ Tree ในฐานข้อมูล ใช้ดึง Key ของค่าลำดับถัดจาก Parameter ที่เราใส่เข้าไปออกมา นิยมใช้กับ For Loop โดยจะไล่ทีละ Layer จากซ้ายไปขวา แต่ถ้าใส่ -1 จะไล่ย้อนกลับจากขวาไปซ้าย ล่างขึ้นบน
S X(1)=“A”
S X(2)=“B”
S X(3)=“C”
S X(4)=“D”
S I=“”
F S I=$O(X(I)) Q:I="" W !,I
Output:
1
2
3
4
จากตัวอย่าง สรุปได้ ดังนี้
- For วรรค 2 ที ตามด้วยการกำหนดค่าเริ่มต้น วรรค 2 ที ตามด้วยเงื่อนไขที่จะหยุด วรรค 2 ที ตามด้วยสิ่งที่จะให้ทำในทุก ๆ Loop
- ตอนแรก I=“” พอเริ่ม Loop จะมาทำคำสั่ง Set I = $O(X(I)) ก็คือ $O(X(“”)) = 1
- ตอนนี้ I ถูก Set เป็น 1 แล้ว
- เช็คว่า I = “” มั้ย ซึ่งไม่ใช่เลย Print ขึ้นบรรทัดใหม่กับ 1 ออกมา
- วน For Loop ใหม่ ทำ $O(X(I)) ตอนนี้ I=1 จะได้ $O(X(1)) = 2
- Set I=2
- I ไม่เป็น “” เลย Write I เป็น 2 ออกมา
- วน For Loop ใหม่ ทำ $O(X(I)) ตอนนี้ I=2 จะได้ $O(X(2)) = 3
- I ไม่เป็น “” เลย Write I เป็น 3 ออกมา
- วน For Loop ใหม่ ทำ $O(X(I)) ตอนนี้ I=3 จะได้ $O(X(3)) = 4
- I ไม่เป็น “” เลย Write I เป็น 4 ออกมา
- วน For Loop ใหม่ ทำ $O(X(I)) ตอนนี้ I=4 จะได้ $O(X(4)) = “”
- เพราะ I เป็น “” เลย Quit ออกมา
มาดูแผนภาพเพื่อให้เข้าใจมากขึ้น
26. การสร้างฟังก์ชัน
สร้างไฟล์นามสกุล .m ให้ชื่อว่า ZDOLLFUNC.m แล้วเขียนฟังก์ชัน NEWDOLL ลงไป
NEWDOLL(ID,NAME,PRICE)
S ID=$G(ID)
I A=“” W !,“ID is required!” Q
S NAME=$G(NAME)
I NAME=“” W !,“Name is required!” Q
S PRICE=+$G(PRICE)
I PRICE=“” W !,“Price is required!” Q
S ^ZDOLLS(ID)=NAME_“|”_PRICE
Q
- Function NEWDOLL จะรับ 3 ค่าคือ ID ชื่อ และราคาของตุ๊กตา โดย ID และ NAME เป็น String แต่ PRICE เป็น Number
- ถ้ามีค่าใดไม่กรอกมาจะจบการทำงานทันที
- เมื่อกรอกค่าครบจะบันทึกค่าในตัวแปร global ชื่อ ZDOLLS และให้ ID เป็น Key มี Value 2 ค่า เป็น NAME คั่นด้วย Pipe ตามด้วย PRICE แล้วจบการทำงาน
กลับมาที่ ydb ลองเรียกใช้ฟังก์ชัน
zl “ZDOLLFUNC”
d NEWDOLL^ZDOLLFUNC(1,“Miab”,110)
zwr ^ZDOLLS
Output
^ZDOLLS(1)=“Miab|110”
d NEWDOLL^ZDOLLFUNC(2,“Yuyu”,300)
zwr ^ZDOLLS
Output:
^ZDOLLS(1)=“Miab|110”
^ZDOLLS(2)=“Yuyu|300”
- คำสั่ง zl ใช้ Build File นามสกุล .m ให้พร้อม Run จะได้ไฟล์ นามสกุล .o ออกมา
- จากนั้นใช้คำสั่ง d คือ d ตามด้วยเว้นวรรค 1 ครั้ง ตามด้วยชื่อฟังก์ชันตามด้วยเครื่องหมาย Arrow Head ตามด้วยชื่อไฟล์นามสกุล .o ตามด้วย Arguments ที่ใส่ให้ฟังก์ชัน
- ตาราง ^ZDOLLS จะมีค่าแล้ว สามารถ Write ค่าออกมาดูได้ด้วยคำสั่ง zwr
- เราจะเรียกใช้ฟังก์ชันกี่รอบก็ได้ ในที่เรียก 2 รอบเพื่อ Add ค่าตุ๊กตาเข้าไป 2 ตัว
27. การ Comment ใช้ Semicolon นำหน้าบรรทัดที่ต้องการ แล้วเว้นวรรค 1 ครั้ง แล้วเว้นวรรค 1 ครั้ง
; This is a comment
ก่อนจะจบบทความนี้ ขอแพร่มอะไรนิดหน่อย 555
เหตุผลที่อยากเขียนหัวข้อนี้เพราะความหงุดหงิดของตัวเองที่อยากหาอ่านเรื่องนี้เป็นภาษาไทยแต่หายังไงก็ไม่เจอ เพราะ ณ ตอนนี้ยังไม่เห็นมีคนไทยพูดถึงเรื่องนี้กันสักเท่าไหร่ ลอง Google เป็นภาษาไทยเกี่ยวกับ “ภาษา M” ก็เจอแต่ ภาษา M script ที่ใช้กับ Power Query หรือพอ search ว่า “ภาษา MUMPS” ก็เจอแต่ “โรคคางทูม” อย่างที่บอกไปข้างต้น ยิ่งแย่ไปกว่าเมื่อ search ว่า “ภาษามัมส์” ก็เจอแต่ศัพท์แสลงว่า “มัมหมี ตัวแม่ ตัวมัม ตัวมารดากันเลยทีเดียวนะฮะ” เฮ้อ เราก็เพิ่งจะได้ยินครั้งแรกมาจากที่ทำงานเก่านั่นแหละ พองงก็ไม่รู้จะถามใคร ไหน ๆ ก็ได้วิชามาจากที่ทำงานเก่าแล้วก็อยากแบ่งปันให้คนไทยได้รู้เรื่องนี้กันบ้าง ถือเป็น guideline ให้สำหรับคนที่อยากทำงาน IT สายธนาคารหรือวิทยาศาสตร์การแพทย์ละกันนะว่า อาจจะต้องเจอเจ้า YottaDB กับภาษา M นี่ได้ในอนาคต เป็นกำลังใจให้ทุกคนผ่านความฉงนงงงวยไปได้ละกันนะ สู้ ๆ
แต่ ๆๆๆ อย่าเพิ่งท้อไป ปัจจุบันนี้ YottaDB ก็ได้พัฒนาไปไกลระดับที่สามารถเอาภาษาโปรแกรมที่เราคุ้นเคยมาครอบเป็น wrapper ได้แล้ว ความรู้สึกเหมือนเรา import พวก library หรือ package mysql มาใช้ใน Node.js หรือ Golang ประมาณนั้นที่ทำให้เราสามารถใช้งาน SQL database ผ่านภาษาโปรแกรมอื่นได้ หรือแม้แต่เอาเจ้าตัว Octo ที่ทีม YottaDB พัฒนาเองมาช่วยในการ mapping YottaDB กับ SQL Database ก็ยังได้เพื่อให้ใช้งานง่ายขึ้นไปอีก เอาเป็นว่าจะแปะลิงก์ไว้ในอ้างอิง เผื่อใครที่สนใจไปศึกษาเพิ่มเองละกันเน้ออออ
สรุป
ก็จบกันไปแล้วนะกับบทความที่ 2 ของเรา เนื้อหาจัดหนักจัดเต็มจริง ๆ แต่บอกเลยว่านี่ก็แค่น้ำจิ้มของภาษา M เท่านั้น ความจริงมีรายละเอียดมากกว่านี้ สามารถ Google ว่า M/MUMPS เพื่อศึกษาเพิ่มเติมได้เลย แล้วจะพบความงง เอ้ย! ความเจ๋งของภาษา M ให้ค้นหาอีกมากมายเลย รอติดตามบทความต่อไปได้เลยจ้าาาา
อ้างอิง
- Introduction to the Mumps Language. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://www.cs.uni.edu/~okane/source/MUMPS-MDH/MumpsTutorial.pdf
- The M Programming Language. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://mumps.dev/
- YottaDB. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://yottadb.com/
- Learn X in Y minutes. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://learnxinyminutes.com/docs/m/#:~:text=M%2C%20or%20MUMPS%20(Massachusetts%20General,a%20built%2Din%20NoSQL%20database.
- General Language Features of M. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://docs.yottadb.com/ProgrammersGuide/langfeat.html#general-language-features-of-m
- ACID Properties. สืบค้นเมื่อ 4 เม.ย. 2567. จาก: https://www.facebook.com/borntodev/photos/a.830302417028053/4423505217707737/?type=3&locale=th_TH