ความมหัศจรรย์ของการโหลดอัตโนมัติ
ฉันคิดว่าตัวเลือกในการควบคุมโฟลเดอร์ที่สิ่งที่ถูกโหลดอัตโนมัติได้รับการครอบคลุมอย่างเพียงพอในคำตอบอื่น ๆ อย่างไรก็ตามในกรณีที่คนอื่นกำลังมีปัญหาในการโหลดแม้ว่าพวกเขาจะมีการแก้ไขเส้นทางอัตโนมัติตามที่ต้องการก็ตามคำตอบนี้จะพยายามอธิบายว่าอะไรคือความมหัศจรรย์ที่อยู่เบื้องหลังสิ่งที่โหลดอัตโนมัตินี้
ดังนั้นเมื่อพูดถึงการโหลดสิ่งต่าง ๆ จากไดเรกทอรีย่อยจะมี gotcha หรือแบบแผนที่คุณควรระวัง บางครั้งเวทมนต์ Ruby / Rails (คราวนี้ส่วนใหญ่เป็น Rails) อาจทำให้ยากที่จะเข้าใจว่าทำไมบางสิ่งเกิดขึ้น โมดูลใด ๆ ที่ประกาศในเส้นทาง autoload จะถูกโหลดก็ต่อเมื่อชื่อโมดูลสอดคล้องกับชื่อไดเรกทอรีหลัก ดังนั้นในกรณีที่คุณพยายามใส่lib/my_stuff/bar.rb
สิ่งที่ชอบ:
module Foo
class Bar
end
end
มันจะไม่ถูกโหลดโดยอัตโนมัติ จากนั้นอีกครั้งถ้าคุณเปลี่ยนชื่อ dir แม่เพื่อทำให้โฮสติ้งโมดูลของคุณในเส้นทาง:foo
lib/foo/bar.rb
มันจะอยู่ที่นั่นเพื่อคุณ ตัวเลือกอื่นคือตั้งชื่อไฟล์ที่คุณต้องการโหลดอัตโนมัติด้วยชื่อโมดูล เห็นได้ชัดว่ามีเพียงไฟล์เดียวเท่านั้นที่ใช้ชื่อนั้น ในกรณีที่คุณต้องการแบ่งเนื้อหาของคุณเป็นไฟล์หลาย ๆ ไฟล์คุณสามารถใช้ไฟล์หนึ่งไฟล์เพื่อต้องการไฟล์อื่น ๆ ได้ แต่ฉันไม่แนะนำเพราะเมื่ออยู่ในโหมดการพัฒนา โหลดซ้ำให้คุณ แต่ถ้าคุณต้องการจริง ๆ คุณสามารถมีหนึ่งไฟล์โดยชื่อโมดูลที่ระบุไฟล์จริงที่ต้องการใช้โมดูล ดังนั้นคุณอาจมีไฟล์สองไฟล์: lib/my_stuff/bar.rb
และไฟล์lib/my_stuff/foo.rb
เก่าเป็นไฟล์เดียวกับด้านบนและไฟล์หลังมีบรรทัดเดียว:require "bar"
และนั่นก็ใช้ได้เหมือนกัน
ป.ล. ฉันรู้สึกว่าถูกบังคับให้เพิ่มสิ่งสำคัญอีกอย่าง เมื่อเร็ว ๆ นี้เมื่อใดก็ตามที่ฉันต้องการมีบางสิ่งบางอย่างในไดเรกทอรี lib ที่ต้องมีการโหลดอัตโนมัติฉันมักจะเริ่มคิดว่าถ้านี่เป็นสิ่งที่ฉันพัฒนาขึ้นมาโดยเฉพาะสำหรับโครงการนี้ (ซึ่งมักจะเป็นบางวัน) เปลี่ยนเป็นส่วนย่อย "คงที่" ของรหัสที่ใช้ในหลายโครงการหรือ submodule คอมไพล์ ฯลฯ ซึ่งในกรณีนี้มันควรจะอยู่ในโฟลเดอร์ lib) แน่นอนแล้วมันอาจจะไม่ได้อยู่ในโฟลเดอร์ lib เลย บางทีมันควรจะอยู่ในโฟลเดอร์ย่อยภายใต้โฟลเดอร์แอพ·ฉันรู้สึกว่านี่เป็นวิธีใหม่ในการทำสิ่งต่างๆ เห็นได้ชัดว่าเวทมนตร์เดียวกันนั้นใช้ได้ทุกที่ในเส้นทางที่คุณใส่สิ่งของของคุณดังนั้นมันจึงเป็นสิ่งที่ดีสำหรับสิ่งเหล่านี้ อย่างไรก็ตามนี่เป็นเพียงความคิดของฉันในเรื่อง คุณมีอิสระที่จะไม่เห็นด้วย :)
UPDATE: เกี่ยวกับประเภทของเวทย์มนตร์ ..
ในขณะที่ Severin ชี้ให้เห็นในความคิดเห็นของเขาหลัก "autoload a module mechanism" แน่ใจว่าเป็นส่วนหนึ่งของ Ruby แต่สิ่งที่เส้นทาง autoload ไม่ได้ คุณไม่จำเป็นต้องใช้ Rails ทำautoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")
. และเมื่อคุณพยายามอ้างอิงโมดูล Foo เป็นครั้งแรกมันจะโหลดให้คุณ อย่างไรก็ตามสิ่งที่ Rails ทำคือช่วยให้เราสามารถลองและโหลดเนื้อหาโดยอัตโนมัติจากโฟลเดอร์ที่ลงทะเบียนและสิ่งนี้ได้ถูกนำไปใช้ในลักษณะที่ต้องการสมมติบางสิ่งเกี่ยวกับอนุสัญญาการตั้งชื่อ ถ้ามันไม่ได้ถูกนำมาใช้เช่นนั้นทุกครั้งที่คุณอ้างอิงบางสิ่งที่ไม่ได้โหลดในปัจจุบันมันจะต้องผ่านไฟล์ทั้งหมดในโฟลเดอร์ autoload ทั้งหมดและตรวจสอบว่ามีสิ่งใดที่คุณพยายามอ้างอิง สิ่งนี้จะเอาชนะความคิดของการโหลดอัตโนมัติและการโหลดอัตโนมัติ อย่างไรก็ตามด้วยข้อตกลงเหล่านี้ในสถานที่ก็สามารถหักออกจากโมดูล / ชั้นเรียนของคุณพยายามที่จะโหลดในที่ที่อาจมีการกำหนดและเพียงแค่โหลดที่
app/lib
ทรีย่อยทั้งหมดของ