ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
ฉันแค่พยายามเข้าถึงไฟล์. rb จากไดเร็กทอรีและบทช่วยสอนกำลังบอกให้ใช้โค้ดนี้ แต่ฉันไม่เห็นว่ามันค้นหาไฟล์ gem ได้อย่างไร
ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
ฉันแค่พยายามเข้าถึงไฟล์. rb จากไดเร็กทอรีและบทช่วยสอนกำลังบอกให้ใช้โค้ดนี้ แต่ฉันไม่เห็นว่ามันค้นหาไฟล์ gem ได้อย่างไร
คำตอบ:
File.expand_path('../../Gemfile', __FILE__)
เป็นสำนวน Ruby ที่ค่อนข้างน่าเกลียดสำหรับการรับเส้นทางสัมบูรณ์ไปยังไฟล์เมื่อคุณทราบเส้นทางที่สัมพันธ์กับไฟล์ปัจจุบัน อีกวิธีหนึ่งในการเขียนคือ:
File.expand_path('../Gemfile', File.dirname(__FILE__))
ทั้งคู่น่าเกลียด แต่ตัวแปรแรกสั้นกว่า อย่างไรก็ตามตัวแปรแรกยังไม่ใช้งานง่ายจนกว่าคุณจะได้รับความยุ่งยาก ทำไมต้องพิเศษ..
? (แต่ตัวแปรที่สองอาจให้เบาะแสว่าเหตุใดจึงจำเป็นต้องใช้)
นี่คือวิธีการทำงาน: File.expand_path
คืนค่าพา ธ สัมบูรณ์ของอาร์กิวเมนต์แรกโดยสัมพันธ์กับอาร์กิวเมนต์ที่สอง (ซึ่งเป็นค่าเริ่มต้นของไดเร็กทอรีการทำงานปัจจุบัน) __FILE__
คือพา ธ ไปยังไฟล์ที่โค้ดอยู่เนื่องจากอาร์กิวเมนต์ที่สองในกรณีนี้คือพา ธ ไปยังไฟล์และFile.expand_path
ถือว่าไดเร็กทอรีเราต้องติดส่วนเสริม..
ในพา ธ เพื่อให้พา ธ ถูกต้อง นี่คือวิธีการทำงาน:
File.expand_path
ถูกนำไปใช้โดยทั่วไปเช่นนี้ (ในรหัสต่อไปนี้path
จะมีค่า../../Gemfile
และrelative_to
จะมีค่าเป็น/path/to/file.rb
):
def File.expand_path(path, relative_to=Dir.getwd)
# first the two arguments are concatenated, with the second argument first
absolute_path = File.join(relative_to, path)
while absolute_path.include?('..')
# remove the first occurrence of /<something>/..
absolute_path = absolute_path.sub(%r{/[^/]+/\.\.}, '')
end
absolute_path
end
(มีอีกเล็กน้อยมันขยาย~
ไปยังโฮมไดเร็กทอรีและอื่น ๆ - อาจมีปัญหาอื่น ๆ เกี่ยวกับโค้ดด้านบน)
การก้าวผ่านการโทรไปยังรหัสด้านบนabsolute_path
ก่อนอื่นจะได้รับค่า/path/to/file.rb/../../Gemfile
จากนั้นสำหรับแต่ละรอบในลูปครั้งแรก..
จะถูกลบออกพร้อมกับองค์ประกอบเส้นทางที่อยู่ข้างหน้า ครั้งแรก/file.rb/..
จะถูกลบออกแล้วในรอบต่อไปจะถูกลบออกและเราได้รับ/to/..
/path/Gemfile
หากต้องการทำให้เรื่องยาวสั้นFile.expand_path('../../Gemfile', __FILE__)
เป็นเคล็ดลับในการรับเส้นทางที่แน่นอนของไฟล์เมื่อคุณทราบเส้นทางที่สัมพันธ์กับไฟล์ปัจจุบัน ความพิเศษ..
ในเส้นทางสัมพัทธ์คือการกำจัดชื่อของไฟล์ใน__FILE__
.
ใน Ruby 2.0 มีKernel
ฟังก์ชันที่เรียก__dir__
ว่าใช้งานเป็นFile.dirname(File.realpath(__FILE__))
.
File.expand_path('../Gemfile',__dir__)
File.expand_path assumes a directory
แม้ว่า__FILE__
จะไม่ใช่ไดเร็กทอรี สำหรับสิ่งที่ควรใช้__dir__
ซึ่งจริงๆแล้วคือไดเร็กทอรี
ข้อมูลอ้างอิงสองรายการ:
วันนี้ฉันเจอสิ่งนี้:
หากคุณขึ้นสองไดเร็กทอรีจาก boot.rb ในแผนผังไดเร็กทอรี:
/ railties / lib / ราง / เครื่องกำเนิดไฟฟ้า / ราง / แอป / เทมเพลต
คุณเห็น Gemfile ซึ่งทำให้ฉันเชื่อว่าFile.expand_path("../../Gemfile", __FILE__)
การอ้างอิงไฟล์ต่อไปนี้:/path/to/this/file/../../Gemfile