Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

การเรียนรู้อาร์กิวเมนต์อย่างเชี่ยวชาญในส่วนขยาย Ruby C:คำแนะนำทีละขั้นตอน

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

ด้วยเหตุนี้ ข้อโต้แย้งของ Ruby จึงมีความยืดหยุ่นมาก ซึ่งทำให้เราสามารถแสดง API ของเราได้อย่างชัดเจน แต่สิ่งนี้มาพร้อมกับข้อเสียเปรียบ:Ruby นั้นค่อนข้างยากที่จะแยกวิเคราะห์สำหรับนักพัฒนา Cextension!

ในบทความนี้ เราจะอธิบายสองวิธีในการตั้งค่า Ruby API ที่ซับซ้อนซึ่งเขียนด้วยภาษา C:

  • ด้วย 03 และแยกวิเคราะห์ด้วย 19
  • การใช้อินเทอร์เฟซ Ruby

มาเริ่มกันเลย!

C และ Ruby:บทนำ

ตามที่กล่าวไว้ Ruby นั้นแยกวิเคราะห์ได้ยากสำหรับนักพัฒนาส่วนขยาย C

ตัวอย่างเช่น:

 

ความงดงามของภาษา C ซึ่งเป็นภาษา Ruby ที่เขียนขึ้นนั้น มีต้นกำเนิดมาจากความเรียบง่าย รวมถึงในพารามิเตอร์ฟังก์ชันด้วย:

  • 23
  • 30 สำหรับการโต้แย้งที่หลากหลาย

สิ่งเหล่านี้จะช่วยคุณรักษาฐานโค้ดที่เข้าใจได้ไม่ยาก

นี่เป็นวิธีที่ซับซ้อนที่สุดในการกำหนดฟังก์ชัน C:

 

เมื่อคุณเขียนโค้ดส่วนขยาย C สำหรับโค้ดเบส Ruby คุณจะเริ่มเข้าใจว่าความซับซ้อนเริ่มต้นที่ใด แต่ไม่ต้องกังวล — นักพัฒนา Ruby MRI ให้เราครอบคลุมแล้ว

คำจำกัดความวิธีการอย่างง่ายในส่วนขยาย Ruby C

เราจะเริ่มต้นด้วยวิธีการที่คุณจะต้องใช้ ณ จุดใดจุดหนึ่ง 41 .

คุณยังสามารถปฏิบัติตามตัวอย่างโค้ดใน repo นี้ได้อีกด้วย

นี่คือ 56 ลายเซ็นต์:

 

และตาม extension.rdoc ของ Ruby:

argc คือจำนวนอาร์กิวเมนต์ ถ้า argc เป็น -1 ฟังก์ชันจะได้รับ 3 อาร์กิวเมนต์:argc, argv และ self ถ้า argc เป็น -2 ฟังก์ชันจะรับ 2 อาร์กิวเมนต์ คือ self และ args โดยที่ args คืออาร์เรย์ Ruby ของอาร์กิวเมนต์ของเมธอด

โดยสรุป:

 

ดังนั้น หาก API ของคุณประกอบด้วยเมธอดที่มีความยาวพารามิเตอร์คงที่ หรือมีพารามิเตอร์แปรผันเพียงตัวเดียว (64 ) ไม่ต้องอ่านต่อ — คุณทำเสร็จแล้ว! หากคุณต้องการวิธีการเรียก API ของคุณที่สมบูรณ์ยิ่งขึ้น โปรดมาเป็นแขกของฉัน

อย่างไรก็ตาม หากคุณต้องการตัวอย่างที่เกี่ยวข้องเพิ่มเติมใน 73 ขอแนะนำให้คุณอ่านบทความของ Peter Zhu เกี่ยวกับ Dinning Methods

การใช้ Ruby C API ภายใน

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

แต่ก่อนอื่น เรามาดูข้อจำกัดของการใช้ 82 เพียงอย่างเดียว .

ข้อเสียของ 95

ไม่มีการกล่าวถึงข้อโต้แย้งที่ถูกบล็อก

ข้อจำกัดประการหนึ่งคือ 105 ไม่เคยกล่าวถึงข้อโต้แย้งแบบบล็อก สิ่งเหล่านั้นไม่ได้รับการพิจารณาเพราะมันไม่สำคัญสำหรับ Ruby อยู่แล้วหากคุณผ่านบล็อก คุณยังคงสามารถมั่นใจได้ว่าบล็อกถูกส่งผ่านโดยใช้119 หรือ 123 . มีข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนั้นในบทความของ Peter Zhu

อาร์กิวเมนต์อาจแตกต่างกันไป

ข้อจำกัดที่สำคัญอีกประการหนึ่งคือ args อาจแตกต่างกันไป แต่ตัววิธีการเรียกนั้นไม่ได้ถูกจำกัดมากนัก ดังนั้น หากคุณต้องการให้ API ของคุณเป็น 138 คุณจะต้องแยกวิเคราะห์ข้อโต้แย้งของคุณ มีหลายวิธีที่จะช่วยคุณในเส้นทางนั้น 149 เป็นเวอร์ชันที่คุณสามารถใช้ได้พร้อมกับเวอร์ชัน -1 ของ 158 .

นี่คือลายเซ็นของฟังก์ชัน:

 

ข้อโต้แย้งของคำหลัก

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

เราต้องดึงข้อโต้แย้งของคำหลักก่อนจึงจะสามารถแยกวิเคราะห์ได้อย่างถูกต้อง โชคดีที่ Ruby C API มาพร้อมกับวิธีการนี้161 .

นี่คือ 171 ลายเซ็นต์:

 

คุณผ่าน 184 198 และ 209 มอบให้โดย 210 — สตริงที่ระบุว่าควรแยกอาร์กิวเมนต์อย่างไร (222 ) และผู้รับข้อโต้แย้งเหล่านั้น เอาล่ะ ความซับซ้อน args ทั้งหมดของ Ruby ถูกแยกวิเคราะห์ในบรรทัดเดียว! เกือบแล้ว

คุณสามารถอ้างอิงถึง extension.rdoc เพื่อเป็นตัวแทนอย่างเป็นทางการว่า 231 ควรเขียนไว้ แม้ว่าเราจะกล่าวถึงบางส่วนในตัวอย่างด้านล่างก็ตาม

เขียนและแยกวิเคราะห์ฟังก์ชัน:ตัวอย่าง

สำหรับส่วนที่เหลือของบทความนี้ ลองพิจารณาว่าเราต้องการเขียนฟังก์ชันนี้:

 

แยกวิเคราะห์โดยใช้ 247 จะมีลักษณะดังนี้:

 

250 พูดพล่อยๆ หมายถึง:

  • 264 :อาร์กิวเมนต์ตำแหน่งที่ต้องการหนึ่งรายการ
  • 277 :ไม่จำเป็นต้องใช้ข้อโต้แย้งเกี่ยวกับตำแหน่งจำนวนเท่าใดก็ได้
  • 281 :อาร์กิวเมนต์คำหลักในตอนท้าย

แยกวิเคราะห์อาร์กิวเมนต์คำหลัก

ตอนนี้เราได้จำกัดวิธีการไว้แล้ว แต่น่าเสียดายที่เรายังดำเนินการไม่เสร็จ API ปัจจุบันของเราคือ 290 .

ท้ายที่สุด เราจำเป็นต้องแยกวิเคราะห์ข้อโต้แย้งของคำหลักเหล่านั้นโดยใช้ 308 .

 

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

 

ได้แล้ว! วิธี Ruby ที่ซับซ้อน แยกวิเคราะห์โดยใช้ C เท่านั้น อย่างไรก็ตาม หากวิธีนี้ซับซ้อนเกินไปสำหรับคุณ ก็มีตัวเลือกอื่น

การใช้อินเทอร์เฟซ Ruby

อีกวิธีหนึ่งในการจัดการปัญหาคือการใช้ไวยากรณ์ของ Ruby โดยตรงและทำการแยกวิเคราะห์ที่ระยะ Ruby

 

ด้วยวิธีนี้ คุณสามารถใช้รูปแบบที่สามของ 336 ได้โดยตรง สำหรับวิธี C ที่มีลักษณะดังนี้:

 

และไปได้แล้ว — คุณหลีกเลี่ยงปัญหาได้อย่างสมบูรณ์ด้วยโซลูชันที่หรูหราซึ่งจริง ๆ แล้วใช้สำหรับวิธีการบางอย่างในการใช้งาน Rubyimplementation (ด้วย 346 คลาส).

แม้ว่าคลาสที่ใช้โดย MRI จะค่อนข้างซับซ้อนและสร้าง C ขึ้นมาเอง แต่เราก็สามารถได้รับแรงบันดาลใจจากมันได้

มาสร้างวัตถุและเสียบวิธีการของเราเพื่อหลีกเลี่ยงการมองเห็น 357 สำหรับผู้ใช้ API ของเรา:

 
 

ลองดูกรณีการใช้งานจริงของคลาสนี้ในโค้ดเบสของ RGeo

การแยกวิเคราะห์อาร์กิวเมนต์:ฉันควรใช้วิธีใด

Repo นี้แสดงสองวิธีในการตั้งค่า Ruby API ที่ซับซ้อนซึ่งเขียนด้วยภาษา C — เพื่อสรุป:

  • ด้วย 364 และแยกวิเคราะห์ด้วย 372
  • การใช้อินเทอร์เฟซ Ruby

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

ใน RGeo lib ตัวเลือกการออกแบบแรกของเราคือการมี API ที่ใช้อาร์กิวเมนต์ความยาวแปรผันเท่านั้น ไม่มีคำหลัก ไม่มีการบล็อก สิ่งนี้อาจเป็นการจำกัด และตอนนี้เรากำลังใช้ 384 วิธีที่จะยอมให้มีข้อโต้แย้งที่ซับซ้อนมากขึ้น

ประโยชน์ของการใช้อินเทอร์เฟซ Ruby

คำแนะนำของฉันคือการใช้อินเทอร์เฟซ Ruby ด้วยเหตุผลหลายประการ รวมถึง:

  • ขนาดโค้ดเล็กลง
  • การเปลี่ยนแปลงทำได้ง่ายขึ้น

โดยรวมแล้ว สิ่งนี้ทำให้ประสบการณ์การอ่านโค้ดเบสของคุณง่ายขึ้น

การดึงดูดผู้ใช้ Ruby ให้อ่านซอร์สโค้ดของ gems ที่พวกเขาใช้นั้นสำคัญสำหรับฉัน เนื่องจาก Ruby อ่านง่าย อัญมณีก็ควรจะเป็นเช่นนั้นเช่นกัน

ประโยชน์ของการใช้ 390

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

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

สรุป

ในโพสต์นี้ เราได้สำรวจสองวิธีในการแยกวิเคราะห์อาร์กิวเมนต์ในส่วนขยาย Ruby C ของคุณ — โดยใช้ 412 (ดูข้อ จำกัด ของมันโดยสังเขปด้วย) และแยกวิเคราะห์ด้วย 425 และใช้อินเทอร์เฟซ Ruby

หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับส่วนขยาย C ฉันขอแนะนำ:

  • การสร้างส่วนขยาย Ruby C ตั้งแต่เริ่มต้น
  • นักทับทิมเดินเลียบฝั่ง C
  • การทำงานกับส่วนขยาย Ruby C บน Mac

และคำแนะนำสุดท้ายของฉันสำหรับคุณ:ลองดู RGeo เป็นโค้ดเบสส่วนขยาย C ที่ใช้กันอย่างแพร่หลายในการพัฒนาอย่างแข็งขัน ตัวอย่างของฉันส่วนใหญ่มาจากที่นี่

ขอให้สนุกกับการเขียนโค้ด!

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

ยูลิสซี บูโอโนโม

Ulysse ผู้เขียนรับเชิญของเราคืออดีตนักพัฒนา Ruby ในอุตสาหกรรมที่อุทิศเวลาส่วนใหญ่ให้กับการเดินทางรอบโลก เวลาว่างของเขาทุ่มเทให้กับ RGeo และ Ruby และเขาชอบที่จะปรับแต่งระบบภายในของ Ruby

บทความทั้งหมดโดย Ulysse Buonomo