ฉันรู้ว่ามันเป็นเวลานานแล้วที่คำถามนี้ถูกถามครั้งแรก แต่ฉันมีคำตอบเพิ่มเติมที่ฉันต้องการจะแบ่งปัน
ฉันมีแอปพลิเคชัน Ruby หลายตัวที่พัฒนาโดยโปรแกรมเมอร์คนอื่นในช่วงหลายปีที่ผ่านมาและพวกเขาใช้คลาสเดียวกันซ้ำในแอปพลิเคชั่นอื่นแม้ว่าพวกเขาอาจเข้าถึงฐานข้อมูลเดียวกัน เนื่องจากสิ่งนี้ละเมิดกฎ DRY ฉันจึงตัดสินใจสร้างไลบรารีชั้นเรียนเพื่อแชร์โดยแอปพลิเคชัน Ruby ทั้งหมด ฉันสามารถวางไว้ในไลบรารี Ruby หลักได้ แต่จะซ่อนโค้ดที่กำหนดเองใน codebase ทั่วไปที่ฉันไม่ต้องการทำ
ฉันมีปัญหาที่ฉันมีความขัดแย้งของชื่อระหว่างชื่อที่กำหนดไว้แล้ว "profile.rb" กับคลาสที่ฉันใช้อยู่ ความขัดแย้งนี้ไม่ใช่ปัญหาจนกว่าฉันจะพยายามสร้างไลบรารีรหัสทั่วไป โดยปกติ Ruby จะค้นหาตำแหน่งของแอปพลิเคชันก่อนจากนั้นไปที่ตำแหน่ง $ LOAD_PATH
application_controller.rb ไม่พบคลาสที่ฉันสร้างและทำให้เกิดข้อผิดพลาดในนิยามดั้งเดิมเนื่องจากไม่ใช่คลาส เนื่องจากฉันลบคำจำกัดความของคลาสออกจากส่วนแอพ / รุ่นของแอปพลิเคชัน Ruby ไม่พบที่นั่นและไปหามันในพา ธ Ruby
ดังนั้นฉันจึงแก้ไขตัวแปร $ LOAD_PATH เพื่อรวมพา ธ ไปยังไดเร็กทอรีไลบรารีที่ฉันใช้ ซึ่งสามารถทำได้ในไฟล์ environment.rb ในเวลาเริ่มต้น
แม้ว่าจะมีการเพิ่มไดเร็กทอรีใหม่ลงในเส้นทางการค้นหา แต่ Ruby ก็ยังแสดงข้อผิดพลาดเนื่องจากถูกนำไฟล์ที่ระบบกำหนดไว้ก่อน เส้นทางการค้นหาในตัวแปร $ LOAD_PATH จะค้นหาเส้นทาง Ruby ก่อน
ดังนั้นฉันต้องเปลี่ยนลำดับการค้นหาเพื่อให้ Ruby พบคลาสในไลบรารีทั่วไปของฉันก่อนที่จะค้นหาไลบรารีในตัว
รหัสนี้ทำในไฟล์ environment.rb:
Rails::Initializer.run do |config|
* * * * *
path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)
* * * * *
end
ฉันไม่คิดว่าคุณจะสามารถใช้โครงสร้างการเข้ารหัสขั้นสูงใด ๆ ที่ให้มาก่อนในระดับนี้ได้ แต่จะใช้ได้ดีหากคุณต้องการตั้งค่าบางอย่างในเวลาเริ่มต้นในแอปของคุณ คุณต้องรักษาลำดับเดิมของตัวแปร $ LOAD_PATH เดิมเมื่อเพิ่มกลับไปยังตัวแปรใหม่มิฉะนั้นคลาส Ruby หลักบางส่วนจะสูญหายไป
ในไฟล์ application_controller.rb ฉันใช้ไฟล์
require 'profile'
require 'etc'
และสิ่งนี้จะโหลดไฟล์ไลบรารีที่กำหนดเองสำหรับแอปพลิเคชันทั้งหมดกล่าวคือฉันไม่ต้องใช้คำสั่งที่ต้องการในทุกคอนโทรลเลอร์
สำหรับฉันนี่คือวิธีแก้ปัญหาที่ฉันกำลังมองหาและฉันคิดว่าจะเพิ่มเข้าไปในคำตอบนี้เพื่อส่งต่อข้อมูลไป
File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}