Ruby - โมดูลและ Mixins
โมดูลเป็นวิธีการจัดกลุ่มเมธอดคลาสและค่าคงที่เข้าด้วยกัน โมดูลให้ประโยชน์หลักสองประการแก่คุณ
โมดูลจัดเตรียมเนมสเปซและป้องกันการขัดแย้งของชื่อ
โมดูลใช้สิ่งอำนวยความสะดวกmixin
โมดูลกำหนดเนมสเปซซึ่งเป็นแซนด์บ็อกซ์ที่วิธีการและค่าคงที่ของคุณสามารถเล่นได้โดยไม่ต้องกังวลว่าจะถูกเหยียบโดยวิธีการและค่าคงที่อื่น ๆ
ไวยากรณ์
module Identifier
statement1
statement2
...........
end
ค่าคงที่ของโมดูลมีชื่อเหมือนกับค่าคงที่ของคลาสโดยมีอักษรตัวพิมพ์ใหญ่เริ่มต้น นิยามเมธอดก็คล้ายกันเช่นกัน: วิธีการของโมดูลถูกกำหนดเช่นเดียวกับวิธีการคลาส
เช่นเดียวกับเมธอดคลาสคุณเรียกใช้เมธอดโมดูลโดยนำหน้าชื่อด้วยชื่อของโมดูลและจุดและคุณอ้างอิงค่าคงที่โดยใช้ชื่อโมดูลและสองโคลอน
ตัวอย่าง
#!/usr/bin/ruby
# Module defined in trig.rb file
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end
เราสามารถกำหนดอีกหนึ่งโมดูลที่มีชื่อฟังก์ชันเดียวกัน แต่มีฟังก์ชันการทำงานต่างกัน -
#!/usr/bin/ruby
# Module defined in moral.rb file
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
# ...
end
end
เช่นเดียวกับเมธอดคลาสเมื่อใดก็ตามที่คุณกำหนดเมธอดในโมดูลคุณระบุชื่อโมดูลตามด้วยจุดแล้วตามด้วยชื่อเมธอด
Ruby ต้องการคำชี้แจง
คำสั่งที่ต้องการนั้นคล้ายกับคำสั่ง include ของ C และ C ++ และคำสั่ง import ของ Java หากโปรแกรมที่สามต้องการใช้โมดูลที่กำหนดไว้ก็สามารถโหลดไฟล์โมดูลโดยใช้คำสั่งRuby require -
ไวยากรณ์
require filename
ที่นี่ไม่จำเป็นต้องให้ .rb พร้อมกับชื่อไฟล์
ตัวอย่าง
$LOAD_PATH << '.'
require 'trig.rb'
require 'moral'
y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
ที่นี่เรากำลังใช้ $LOAD_PATH << '.'เพื่อให้ Ruby ทราบว่าต้องค้นหาไฟล์ที่รวมอยู่ในไดเร็กทอรีปัจจุบัน หากคุณไม่ต้องการใช้ $ LOAD_PATH คุณสามารถใช้require_relative เพื่อรวมไฟล์จากไดเร็กทอรีสัมพัทธ์
IMPORTANT- ที่นี่ไฟล์ทั้งสองมีชื่อฟังก์ชันเดียวกัน ดังนั้นสิ่งนี้จะส่งผลให้เกิดความไม่ชัดเจนของรหัสในขณะที่รวมอยู่ในโปรแกรมการเรียกใช้ แต่โมดูลจะหลีกเลี่ยงความไม่ชัดเจนของรหัสนี้และเราสามารถเรียกใช้ฟังก์ชันที่เหมาะสมโดยใช้ชื่อโมดูล
Ruby รวม Statement
คุณสามารถฝังโมดูลในคลาส ในการฝังโมดูลในคลาสคุณใช้คำสั่งincludeในคลาส -
ไวยากรณ์
include modulename
ถ้าโมดูลที่กำหนดไว้ในแฟ้มแยกต่างหากแล้วมันจะต้องรวมไฟล์ที่ใช้จำเป็นต้องมีคำสั่งก่อนที่จะฝังโมดูลในชั้นเรียน
ตัวอย่าง
พิจารณาโมดูลดังต่อไปนี้เขียนในsupport.rbไฟล์
module Week
FIRST_DAY = "Sunday"
def Week.weeks_in_month
puts "You have four weeks in a month"
end
def Week.weeks_in_year
puts "You have 52 weeks in a year"
end
end
ตอนนี้คุณสามารถรวมโมดูลนี้ในชั้นเรียนได้ดังนี้ -
#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"
class Decade
include Week
no_of_yrs = 10
def no_of_months
puts Week::FIRST_DAY
number = 10*12
puts number
end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months
สิ่งนี้จะให้ผลลัพธ์ดังต่อไปนี้ -
Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120
ส่วนผสมในทับทิม
ก่อนที่จะอ่านส่วนนี้เราถือว่าคุณมีความรู้เกี่ยวกับแนวคิดเชิงวัตถุ
เมื่อคลาสสามารถสืบทอดคุณสมบัติจากคลาสพาเรนต์มากกว่าหนึ่งคลาสคลาสควรจะแสดงการสืบทอดหลายคลาส
Ruby ไม่สนับสนุนการสืบทอดโดยตรง แต่ Ruby Modules มีการใช้งานที่ยอดเยี่ยมอีกอย่างหนึ่ง ในจังหวะที่พวกเขาสวยมากขจัดความจำเป็นในมรดกหลายที่ให้สถานที่ที่เรียกว่าmixin
Mixins ช่วยให้คุณสามารถเพิ่มฟังก์ชันการทำงานในคลาสได้อย่างยอดเยี่ยม อย่างไรก็ตามพลังที่แท้จริงของพวกเขาจะปรากฏออกมาเมื่อโค้ดในมิกซ์อินเริ่มโต้ตอบกับโค้ดในคลาสที่ใช้มัน
ให้เราตรวจสอบโค้ดตัวอย่างต่อไปนี้เพื่อทำความเข้าใจเกี่ยวกับมิกซ์อิน -
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
โมดูล A ประกอบด้วยวิธีการ a1 และ a2 โมดูล B ประกอบด้วยวิธีการ b1 และ b2 ตัวอย่างคลาสมีทั้งโมดูล A และ B คลาสตัวอย่างสามารถเข้าถึงทั้งสี่วิธี ได้แก่ a1, a2, b1 และ b2 ดังนั้นคุณจะเห็นว่าคลาสตัวอย่างสืบทอดมาจากโมดูลทั้งสอง ดังนั้นคุณสามารถพูดได้ว่าคลาสตัวอย่างแสดงการสืบทอดหลายรายการหรือมิกซ์อิน