วิธีที่ดีที่สุดที่จะต้องใช้ไฟล์ทั้งหมดจากไดเรกทอรีในทับทิมคืออะไร?
วิธีที่ดีที่สุดที่จะต้องใช้ไฟล์ทั้งหมดจากไดเรกทอรีในทับทิมคืออะไร?
คำตอบ:
เกี่ยวกับ:
Dir["/path/to/directory/*.rb"].each {|file| require file }
require
ไม่สับสนกับการมีหรือไม่มี.rb
นามสกุล ทดสอบกับ MRI 1.8.7-p374, 2.1.5 และ 2.2.0 ทดสอบ ตำนานในเมืองนี้มาจาก Rails ซึ่งการโหลดอัตโนมัติที่ "ฉลาด" แสดงพฤติกรรมที่เขาอธิบายในเวอร์ชั่นที่เก่ากว่า (และอาจยังคงแสดงไว้)
หากเป็นไดเรกทอรีที่สัมพันธ์กับไฟล์ที่ต้องการ (เช่นคุณต้องการโหลดไฟล์ทั้งหมดในไดเรกทอรี lib):
Dir[File.dirname(__FILE__) + '/lib/*.rb'].each {|file| require file }
แก้ไข:ตามความคิดเห็นด้านล่างเวอร์ชันที่อัปเดต:
Dir[File.join(__dir__, 'lib', '*.rb')].each { |file| require file }
Dir[File.dirname(__FILE__) + '/support/**/*.rb'].each {|file| require file }
Dir[File.join(File.dirname(__FILE__), 'lib', '*.rb')].each {|file| require file }
__dir__
File.dirname(__FILE__)
require_relative
จะใช้เพื่อกำหนดไฟล์ทั้งหมดในไดเรกทอรีได้อย่างไร?
ลองใช้ require_all gem:
มันช่วยให้คุณ:
require_all 'path/to/directory'
require_all
แก้ปัญหาการพึ่งพาของวงจรแก้ไขปัญหาในซอร์สโค้ดของคุณ: คุณมีไฟล์ทับทิมที่ไม่ต้องการการพึ่งพา วิธีนี้จะปิดประตูเมื่อมีการโหลดมีดผ่าตัดทำให้คุณสามารถโหลดได้ทั้งหมดหรือไม่ใช้เลย นั่นไม่ใช่ปัญหาในห้องสมุดขนาดเล็ก แต่เป็นการตัดสินใจที่คุณควรทำอย่างมีสติ
Dir[File.dirname(__FILE__) + '/../lib/*.rb'].each do |file|
require File.basename(file, File.extname(file))
end
หากคุณไม่ได้ตัดส่วนขยายคุณอาจต้องใช้ไฟล์เดียวกันสองครั้ง (ทับทิมจะไม่ทราบว่า "foo" และ "foo.rb" เป็นไฟล์เดียวกัน) การใช้ไฟล์เดียวกันสองครั้งอาจทำให้เกิดคำเตือนปลอม (เช่น "คำเตือน: ค่าเริ่มต้นคงที่แล้ว")
require "foo.rb"; require "foo";
จะโหลดfoo.rb
เพียงครั้งเดียว
require
ไม่สับสนกับการมีหรือไม่มี.rb
นามสกุล ทดสอบกับ MRI 1.8.7-p374, 2.1.5 และ 2.2.0 ตำนานในเมืองนี้มาจาก Rails ซึ่งการโหลดอัตโนมัติที่ "ฉลาด" แสดงพฤติกรรมที่อธิบายไว้ในเวอร์ชั่นที่เก่ากว่า (และอาจยังคงแสดงไว้)
Dir.glob(File.join('path', '**', '*.rb'), &method(:require))
หรืออีกวิธีหนึ่งหากคุณต้องการกำหนดขอบเขตไฟล์ที่จะโหลดไปยังโฟลเดอร์เฉพาะ:
Dir.glob(File.join('path', '{folder1,folder2}', '**', '*.rb'), &method(:require))
คำอธิบาย:
Dir.globรับบล็อกเป็นอาร์กิวเมนต์
เมธอด (: require) จะส่งคืนเมธอด require
& method (: ต้องการ) จะแปลงวิธีการเป็นกลุ่ม
Dir.glob( File.join( File.dirname(__FILE__), '{lib,addons}', 'subfolder', '**', '*.rb' ), &method(:require) )
กำจัดการพึ่งพาแพลตฟอร์ม (เช่น '/' หรือ '\') ทำได้ดี. ขอบคุณ
วิธีที่ดีที่สุดคือการเพิ่มไดเรกทอรีไปยังโหลดพา ธ แล้วrequire
ตามชื่อไฟล์ของแต่ละไฟล์ นี่เป็นเพราะคุณต้องการหลีกเลี่ยงการต้องการไฟล์เดียวกันสองครั้งโดยไม่ตั้งใจซึ่งมักจะไม่ใช่พฤติกรรมที่ตั้งใจไว้ ไม่ว่าจะโหลดไฟล์หรือไม่นั้นขึ้นอยู่กับว่าrequire
เคยเห็นพา ธ ที่ส่งผ่านมาก่อนหรือไม่ ตัวอย่างเช่นเซสชัน irb แบบง่ายนี้แสดงว่าคุณสามารถต้องการและโหลดไฟล์เดียวกันสองครั้งโดยไม่ตั้งใจ
$ irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> require './test'
=> true
irb(main):003:0> require './test.rb'
=> false
irb(main):004:0> require 'test'
=> false
โปรดทราบว่าการคืนสองบรรทัดแรกtrue
หมายความว่าไฟล์เดียวกันโหลดทั้งสองครั้ง เมื่อมีการใช้พา ธ แม้ว่าเส้นทางจะชี้ไปที่ตำแหน่งเดียวกันrequire
ไม่ทราบว่าไฟล์นั้นจำเป็นต้องใช้แล้ว
ที่นี่แทนเราเพิ่มไดเรกทอรีไปยังโหลดพา ธ แล้วต้องใช้ชื่อฐานของไฟล์ * .rb แต่ละไฟล์ภายใน
dir = "/path/to/directory"
$LOAD_PATH.unshift(dir)
Dir[File.join(dir, "*.rb")].each {|file| require File.basename(file) }
หากคุณไม่สนใจเกี่ยวกับไฟล์ที่ถูกต้องมากกว่าหนึ่งครั้งหรือความตั้งใจของคุณเป็นเพียงการโหลดเนื้อหาของแฟ้มบางทีควรจะนำมาใช้แทนload
require
ใช้การโหลดในกรณีนี้เพราะเป็นการแสดงถึงสิ่งที่คุณพยายามทำให้ดีขึ้น ตัวอย่างเช่น:
Dir["/path/to/directory/*.rb"].each {|file| load file }
ฉันใช้File.expand_path
:
Dir[File.expand_path('importers/*.rb', File.dirname(__FILE__))].each do |file|
require file
end
ปรับปรุง:
แทนที่จะใช้File.dirname
คุณสามารถทำสิ่งต่อไปนี้:
Dir[File.expand_path('../importers/*.rb', __FILE__)].each do |file|
require file
end
ที่ไหนแถบชื่อไฟล์ของ..
__FILE__
File.expand_path
Rails.root.join
คำตอบต่าง ๆยังใช้ได้ถ้าคุณอยู่ในราง
Dir[File.join(__dir__, "/app/**/*.rb")].each do |file|
require file
end
สิ่งนี้จะทำงานซ้ำในเครื่องของคุณและรีโมต (Like Heroku) ซึ่งไม่ได้ใช้เส้นทางที่สัมพันธ์กัน
ใน Rails คุณสามารถทำได้:
Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
อัปเดต: แก้ไขด้วยคำแนะนำของ @Jiggneshh Gohel เพื่อลบเครื่องหมายทับ
Rails.root.join('/lib')
ไม่สร้างเส้นทางที่ถูกต้อง ผมพบว่าหนึ่งในการทำงานอย่างถูกต้อง:Dir[Rails.root.join('lib', 'ext', '*.rb')].each { |file| require file }
ฉันไปปาร์ตี้ไม่กี่ปี แต่ฉันชอบวิธีแก้ปัญหาแบบบรรทัดเดียวที่ฉันใช้เพื่อให้ rails รวมทุกอย่างในแอพ / คนงาน / ข้อกังวล:
Dir[ Rails.root.join *%w(app workers concerns *) ].each{ |f| require f }
และสิ่งที่เกี่ยวกับ: require_relative *Dir['relative path']
?
require_relative *Dir['*.rb']
ทำงานถ้ามีเพียงหนึ่งทับทิมสคริปต์ แต่ถ้าพบสคริปต์ทับทิมหลายตัวคุณจะได้รับrequire_relative': wrong number of arguments (4 for 1) (ArgumentError)