คำถามของฉันคล้ายกับ "ความแตกต่างระหว่างการรวมและการขยายในทับทิมคืออะไร "
ความแตกต่างระหว่างrequire
และinclude
ในทับทิมคืออะไร? ถ้าฉันเพียงต้องการใช้วิธีการจากโมดูลในชั้นเรียนของฉันฉันควรrequire
หรือinclude
ไม่
คำถามของฉันคล้ายกับ "ความแตกต่างระหว่างการรวมและการขยายในทับทิมคืออะไร "
ความแตกต่างระหว่างrequire
และinclude
ในทับทิมคืออะไร? ถ้าฉันเพียงต้องการใช้วิธีการจากโมดูลในชั้นเรียนของฉันฉันควรrequire
หรือinclude
ไม่
คำตอบ:
ความแตกต่างระหว่าง "รวม" และ "ต้อง" ในทับทิมคืออะไร?
ตอบ:
การรวมและต้องการวิธีการทำสิ่งที่แตกต่างกันมาก
วิธีต้องการสิ่งที่รวมอยู่ในภาษาการเขียนโปรแกรมอื่น ๆ ส่วนใหญ่: เรียกใช้ไฟล์อื่น นอกจากนี้ยังติดตามสิ่งที่คุณต้องการในอดีตและไม่ต้องการไฟล์เดียวกันสองครั้ง หากต้องการเรียกใช้ไฟล์อื่นโดยไม่มีฟังก์ชั่นเพิ่มนี้คุณสามารถใช้วิธีโหลดได้
วิธีการรวมใช้วิธีการทั้งหมดจากโมดูลอื่นและรวมไว้ในโมดูลปัจจุบัน นี่คือสิ่งที่ระดับภาษาเมื่อเทียบกับสิ่งที่ระดับไฟล์เช่นเดียวกับต้องการ วิธีการรวมเป็นวิธีหลักในการ "ขยาย" เรียนกับโมดูลอื่น ๆ (มักจะเรียกว่าเป็นมิกซ์) ตัวอย่างเช่นถ้าคลาสของคุณกำหนดวิธีการ "แต่ละ" คุณสามารถรวมโมดูล mixin ที่นับได้และมันสามารถทำหน้าที่เป็นคอลเลกชัน สิ่งนี้อาจทำให้เกิดความสับสนเนื่องจากมีการใช้กริยารวมในภาษาอื่น
require
ดังนั้นถ้าคุณเพียงต้องการที่จะใช้โมดูลแทนที่จะขยายมันหรือผสมในแล้วคุณจะต้องการที่จะใช้
ผิดปกติพอทับทิมrequire
จะคล้ายคลึงกับซีinclude
ขณะที่ทับทิมเกือบจะไม่มีอะไรเหมือนซีinclude
include
include
ใน Ruby เป็นเพียงการสืบทอด class C; include M end
ทำให้M
superclass ของC
และ (อดีต) superclass ของC
superclass M
ของ ฉันไม่คิดว่าinclude
งานของ C ผ่านการสืบทอดฉันคิดว่าเป็นการทดแทนข้อความ / ศัพท์แบบง่าย
หากคุณใช้โมดูลนั่นหมายความว่าคุณกำลังนำวิธีการทั้งหมดเข้าสู่ชั้นเรียนของคุณ หากคุณextend
ชั้นที่มีโมดูลที่หมายความว่าคุณกำลัง "นำ" วิธีการของโมดูลเป็นระดับวิธีการ หากคุณinclude
ชั้นที่มีโมดูลที่หมายความว่าคุณกำลัง "นำ" วิธีการของโมดูลเป็นเช่นวิธีการ
EX:
module A
def say
puts "this is module A"
end
end
class B
include A
end
class C
extend A
end
B.say
=> วิธีที่ไม่ได้กำหนด 'พูด' สำหรับ B: Class
B.new.say
=> นี่คือโมดูล A
C.say
=> นี่คือโมดูล A
C.new.say
=> วิธีที่ไม่ได้กำหนด 'พูด' สำหรับ C: Class
จากหนังสือ Metaprogramming Ruby
require()
วิธีการค่อนข้างคล้ายกับload()
แต่มันมีความหมายสำหรับวัตถุประสงค์ที่แตกต่างกัน คุณใช้load()
เพื่อเรียกใช้รหัสและคุณใช้require()
เพื่อนำเข้าไลบรารี
Ruby require
เป็นเหมือน "รวม" ในภาษาอื่น ๆ (เช่น C) มันบอกทับทิมว่าคุณต้องการนำเนื้อหาของไฟล์อื่นมา กลไกที่คล้ายกันในภาษาอื่นคือ:
Ruby include
เป็นกลไกการสืบทอดเชิงวัตถุที่ใช้สำหรับมิกซ์อิน
มีคำอธิบายที่ดีที่นี่ :
[คำตอบง่ายๆ] คือความต้องการและการรวมนั้นไม่เกี่ยวข้องกันเป็นหลัก
"ต้องการ"คล้ายกับ C รวมซึ่งอาจทำให้เกิดความสับสนมือใหม่ (สิ่งหนึ่งที่น่าสังเกตคือความแตกต่างคือคนในไฟล์ "ระเหย" ที่ต้องการเมื่อทำเสร็จ)
การรวมทับทิมนั้นไม่เหมือนกับที่ C รวมอยู่ คำสั่ง include "มิกซ์ใน" โมดูลเข้ากับคลาส มันเป็นรูปแบบที่ จำกัด ของการสืบทอดหลายอย่าง โมดูลที่รวมอยู่นั้นมอบความสัมพันธ์แบบ "is-a" ให้กับสิ่งที่รวมอยู่ด้วย
เน้นการเพิ่ม
คุณเคยลองrequire
โมดูลหรือไม่? ผลลัพธ์คืออะไร เพียงแค่พยายามที่:
MyModule = Module.new
require MyModule # see what happens
ไม่สามารถใช้โมดูลรวมอยู่ในนั้นเท่านั้น!
TypeError
) ถ้าคำว่าจะเปลี่ยนไปModule
Class
จากการเขียนโปรแกรม Ruby 1.9
เราจะทำสองสามจุดเกี่ยวกับคำสั่ง include ก่อนที่เราจะไปต่อ ก่อนอื่นไม่มีอะไรเกี่ยวข้องกับไฟล์ โปรแกรมเมอร์ C ใช้คำสั่ง preprocessor ชื่อ #include เพื่อแทรกเนื้อหาของไฟล์หนึ่งไปยังอีกไฟล์หนึ่งระหว่างการคอมไพล์ คำสั่ง Ruby include จะทำการอ้างอิงไปยังโมดูล หากโมดูลนั้นอยู่ในไฟล์แยกต่างหากคุณต้องใช้ต้องการ (หรือลูกพี่ลูกน้อง, โหลด) เพื่อลากไฟล์นั้นก่อนใช้งาน ประการที่สองการรวม Ruby ไม่เพียง แต่คัดลอกวิธีการของโมดูลไปยังคลาส แต่จะทำการอ้างอิงจากคลาสไปยังโมดูลที่รวมไว้ หากหลายคลาสมีโมดูลนั้นพวกเขาทั้งหมดจะชี้ไปที่สิ่งเดียวกัน หากคุณเปลี่ยนคำจำกัดความของวิธีการภายในโมดูลแม้ในขณะที่โปรแกรมของคุณกำลังทำงาน
รวมเมื่อคุณรวมโมดูลเข้าไปในคลาสของคุณดังแสดงด้านล่างราวกับว่าคุณได้ใส่รหัสที่กำหนดไว้ในโมดูลและใส่เข้าไปในคลาสที่คุณ 'รวม' ไว้ จะช่วยให้พฤติกรรม 'mixin' มันใช้เพื่อเพิ่มโค้ดของคุณเพื่อหลีกเลี่ยงการทำซ้ำเช่นถ้ามีหลายคลาสที่จะต้องใช้รหัสเดียวกันภายในโมดูล
โหลดวิธีโหลดนั้นคล้ายกับวิธีต้องการยกเว้นว่าจะไม่ติดตามว่ามีการโหลดไลบรารีหรือไม่ ดังนั้นจึงเป็นไปได้ที่จะโหลดไลบรารีหลาย ๆ ครั้งและเมื่อใช้วิธีการโหลดคุณต้องระบุนามสกุล“ .rb” ของชื่อไฟล์ไลบรารี
ต้องการวิธีการต้องการให้คุณโหลดไลบรารีและป้องกันไม่ให้โหลดมากกว่าหนึ่งครั้ง เมธอด require จะส่งคืน 'false' หากคุณพยายามโหลดไลบรารี่เดียวกันหลังจากครั้งแรก เมธอด need จำเป็นต้องใช้เฉพาะถ้าไลบรารีที่คุณกำลังโหลดถูกกำหนดในไฟล์แยกต่างหากซึ่งโดยปกติจะเป็นตัวพิมพ์เล็ก
คุณสามารถชอบ http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/
ด้านล่างมีความแตกต่างพื้นฐานเล็กน้อยระหว่างความต้องการและการรวม:
จำเป็นต้อง:
รวมถึง:
require(name)
มันจะคืนค่าโบลีนจริง / เท็จ
ชื่อที่ถูกส่งผ่านเป็นพารามิเตอร์ไปยังที่ต้องการทับทิมจะพยายามหาไฟล์ต้นฉบับที่มีชื่อนั้นในเส้นทางโหลดของคุณ เมธอด require จะส่งคืน 'false' หากคุณพยายามโหลดไลบรารี่เดียวกันหลังจากครั้งแรก เมธอด need จำเป็นต้องใช้เฉพาะถ้าไลบรารีที่คุณกำลังโหลดถูกกำหนดในไฟล์แยกต่างหาก ดังนั้นจึงติดตามว่ามีการโหลดไลบรารีนั้นหรือไม่
include module_name
สมมติว่าคุณมีวิธีการบางอย่างที่คุณจำเป็นต้องมีในสองชั้นที่แตกต่างกัน จากนั้นคุณไม่ต้องเขียนมันทั้งสองคลาส สิ่งที่คุณสามารถทำได้คือกำหนดไว้ในโมดูล แล้วรวมโมดูลนี้ในชั้นเรียนอื่น ๆ จัดทำโดย Ruby เพื่อให้มั่นใจถึงหลักการของ DRY ใช้เพื่อเพิ่มรหัสของคุณเพื่อหลีกเลี่ยงการทำซ้ำ
ประกอบด้วย
เมื่อคุณ
include
ใส่โมดูลในชั้นเรียนของคุณมันก็เหมือนกับว่าคุณเอารหัสที่กำหนดไว้ในโมดูลและใส่เข้าไปในชั้นเรียนที่คุณรวมไว้ จะช่วยให้พฤติกรรม 'mixin' มันใช้เพื่อเพิ่มโค้ดของคุณเพื่อหลีกเลี่ยงการทำซ้ำเช่นถ้ามีหลายคลาสที่จะต้องใช้รหัสเดียวกันภายในโมดูล
module Log
def class_type
"This class is of type: #{self.class}"
end
end
class TestClass
include Log
# ...
end
tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error
จำเป็นต้อง
เมธอด require อนุญาตให้คุณโหลดไลบรารีและป้องกันไม่ให้โหลดมากกว่าหนึ่งครั้ง เมธอด require จะส่งคืน 'false' หากคุณพยายามโหลดไลบรารี่เดียวกันหลังจากครั้งแรก เมธอด need จำเป็นต้องใช้เฉพาะถ้าไลบรารีที่คุณกำลังโหลดถูกกำหนดในไฟล์แยกต่างหากซึ่งโดยปกติจะเป็นตัวพิมพ์เล็ก
ดังนั้นจึงติดตามว่ามีการโหลดไลบรารีนั้นหรือไม่ คุณไม่จำเป็นต้องระบุส่วนขยาย“ .rb” ของชื่อไฟล์ไลบรารี นี่คือตัวอย่างวิธีการใช้ที่ต้องการ วางเมธอด need ที่ด้านบนสุดของไฟล์“ .rb” ของคุณ:
ภาระ
วิธีการโหลดนั้นเกือบจะเหมือนวิธีที่ต้องการยกเว้นว่ามันจะไม่ติดตามว่ามีการโหลดไลบรารีนั้นหรือไม่ ดังนั้นจึงเป็นไปได้ที่จะโหลดไลบรารีหลาย ๆ ครั้งและเมื่อใช้วิธีการโหลดคุณต้องระบุนามสกุล“ .rb” ของชื่อไฟล์ไลบรารี
ต่ออายุ
เมื่อใช้วิธีการขยายแทนการรวมคุณจะเพิ่มวิธีการโมดูลเป็นวิธีการเรียนแทนวิธีการเช่น
module Log
def class_type
"This class is of type: #{self.class}"
end
end
class TestClass
extend Log
# ...
end
tc = TestClass.class_type
'โหลด' - แทรกเนื้อหาของไฟล์ (แยกวิเคราะห์ไฟล์ทุกครั้งที่มีการเรียกไฟล์)
'Require'- แทรกเนื้อหาแยกไฟล์ (แยกวิเคราะห์ไฟล์ครั้งเดียวและเก็บไว้ในหน่วยความจำ)
'Include'- รวมโมดูลเข้าไปในคลาสและสามารถใช้เมธอดภายในโมดูลเป็นวิธีอินสแตนซ์ของคลาส
'Extend' - รวมโมดูลเข้าไปในคลาสและสามารถใช้วิธีการภายในโมดูลเป็นวิธีการเรียน
require
และและยังเกี่ยวข้องinclude
Module#append_features