1 โหมด "classic" และโหมด "zeitwerk" คืออะไร?
ตั้งแต่ต้นเริ่มและจนถึง Rails 5, Rails ใช้ autoloader ที่ได้รับการนำเสนอใน Active Support โหมดนี้เรียกว่า "classic" และยังคงใช้ได้ใน Rails 6.x แต่ Rails 7 ไม่รวม autoloader นี้อีกต่อไป
เริ่มต้นด้วย Rails 6, Rails จัดส่งพร้อมกับวิธีการโหลดอัตโนมัติใหม่และดีกว่า ซึ่งจะมอบหมายงานให้กับ Zeitwerk gem นี้คือโหมด "zeitwerk" โดยค่าเริ่มต้นแอปพลิเคชันที่โหลดเฟรมเวิร์ก 6.0 และ 6.1 ทำงานในโหมด "zeitwerk" และนี่เป็นโหมดเดียวที่มีใน Rails 7
2 เหตุผลที่ต้องเปลี่ยนจากโหมด "classic" เป็นโหมด "zeitwerk"?
autoloader โหมด "classic" มีประโยชน์อย่างมาก แต่มีปัญหาบางอย่างที่ทำให้การโหลดอัตโนมัติเป็นเรื่องที่ยากและสับสนบ้างครั้ง Zeitwerk ถูกพัฒนาขึ้นเพื่อแก้ไขปัญหานี้ รวมถึงแรงบันดาลใจอื่น ๆ ด้วย
เมื่ออัปเกรดไปยัง Rails 6.x แนะนำให้เปลี่ยนเป็นโหมด "zeitwerk" เพราะเป็น autoloader ที่ดีกว่า โหมด "classic" ถูกยกเลิกใช้
Rails 7 จะสิ้นสุดระยะเวลาการเปลี่ยนแปลงและไม่รวมโหมด "classic" อีกต่อไป
3 ฉันกลัว
ไม่ต้องกลัว :)
Zeitwerk ถูกออกแบบให้เข้ากันได้มากที่สุดกับ autoloader โหมด "classic" หากคุณมีแอปพลิเคชันที่ทำงานโหลดอัตโนมัติได้อย่างถูกต้องในปัจจุบัน โอกาสที่การเปลี่ยนจะง่ายมาก โครงการมากมายทั้งใหญ่และเล็กได้รายงานว่าการเปลี่ยนโหมดเป็นราบรื่นมาก
คู่มือนี้จะช่วยคุณเปลี่ยน autoloader โดยมั่นใจ
หากเพราะเหตุใดก็ตามคุณพบสถานการณ์ที่คุณไม่รู้วิธีแก้ไข อย่าลังเลที่จะ เปิดปัญหาใน rails/rails
และแท็ก @fxn
4 วิธีเปิดใช้โหมด "zeitwerk"
4.1 แอปพลิเคชันที่ทำงานด้วย Rails 5.x หรือต่ำกว่า
ในแอปพลิเคชันที่ทำงานด้วยเวอร์ชัน Rails ก่อน 6.0 โหมด "zeitwerk" ไม่สามารถใช้ได้ คุณต้องอยู่ใน Rails 6.0 หรือสูงกว่า
4.2 แอปพลิเคชันที่ทำงานด้วย Rails 6.x
ในแอปพลิเคชันที่ทำงานด้วย Rails 6.x มีสองสถานการณ์
หากแอปพลิเคชันกำลังโหลดค่าเริ่มต้นของเฟรมเวิร์ก 6.0 หรือ 6.1 และทำงานในโหมด "classic" คุณต้องเลือกที่จะไม่ใช้โหมด "zeitwerk" คุณต้องมีสิ่งที่คล้ายกันกับนี้:
# config/application.rb
config.load_defaults 6.0
config.autoloader = :classic # ลบบรรทัดนี้
อย่างที่กล่าวไว้เพียงแค่ลบการแทนที่ โหมด "zeitwerk" เป็นค่าเริ่มต้น
ในทางกลับกันหากแอปพลิเคชันกำลังโหลดค่าเริ่มต้นเก่าคุณต้องเปิดใช้โหมด "zeitwerk" โดยชัดเจน:
# config/application.rb
config.load_defaults 5.2
config.autoloader = :zeitwerk
4.3 แอปพลิเคชันที่ทำงานด้วย Rails 7
ใน Rails 7 มีเพียงโหมด "zeitwerk" เท่านั้น คุณไม่ต้องทำอะไรเพื่อเปิดใช้งาน
ใน Rails 7 นั้น setter config.autoloader=
ไม่มีอยู่จริงๆ ถ้า config/application.rb
ใช้มัน กรุณาลบบรรทัดนั้น
5 วิธีการตรวจสอบแอปพลิเคชันว่าทำงานในโหมด zeitwerk
หรือไม่?
เพื่อตรวจสอบว่าแอปพลิเคชันทำงานในโหมด zeitwerk
หรือไม่ ให้รันคำสั่ง
bin/rails runner 'p Rails.autoloaders.zeitwerk_enabled?'
ถ้าพิมพ์ true
ออกมา แสดงว่าโหมด zeitwerk
เปิดใช้งาน
6 แอปพลิเคชันของฉันเป็นไปตามกฎระเบียบของ Zeitwerk หรือไม่?
6.1 config.eager_load_paths
การทดสอบความเป็นไปตามกฎระเบียบจะทำงานเฉพาะไฟล์ที่โหลดแบบเร่งด่วนเท่านั้น ดังนั้นเพื่อตรวจสอบความเป็นไปตามกฎระเบียบของ Zeitwerk แนะนำให้มีทุกเส้นทางการโหลดอัตโนมัติอยู่ในเส้นทางการโหลดแบบเร่งด่วน
นั่นเป็นค่าเริ่มต้นอยู่แล้ว แต่ถ้าโปรเจกต์มีเส้นทางการโหลดอัตโนมัติที่กำหนดเอง เช่นนี้:
config.autoload_paths << "#{Rails.root}/extras"
เส้นทางเหล่านั้นไม่ได้โหลดแบบเร่งด่วนและจะไม่ถูกตรวจสอบ การเพิ่มเส้นทางเหล่านั้นในเส้นทางการโหลดแบบเร่งด่วนง่ายดาย:
config.autoload_paths << "#{Rails.root}/extras"
config.eager_load_paths << "#{Rails.root}/extras"
6.2 zeitwerk:check
เมื่อเปิดใช้งานโหมด zeitwerk
และตรวจสอบการกำหนดค่าเส้นทางการโหลดแบบเร่งด่วนอีกครั้ง กรุณารัน:
bin/rails zeitwerk:check
ผลการตรวจสอบที่ประสบความสำเร็จจะมีลักษณะดังนี้:
% bin/rails zeitwerk:check
Hold on, I am eager loading the application.
All is good!
อาจมีผลลัพธ์เพิ่มเติมขึ้นอยู่กับการกำหนดค่าแอปพลิเคชัน แต่ "All is good!" ที่สุดคือผลลัพธ์ที่คุณต้องการ
ถ้าการตรวจสอบครั้งก่อนหน้านี้กำหนดว่าจริงๆ ต้องมีเส้นทางการโหลดอัตโนมัติที่กำหนดเองนอกเส้นทางการโหลดแบบเร่งด่วน งานจะตรวจจับและเตือนเกี่ยวกับเรื่องนั้น อย่างไรก็ตาม ถ้าชุดทดสอบโหลดไฟล์เหล่านั้นได้สำเร็จ คุณก็ไม่มีปัญหา
ตอนนี้ถ้ามีไฟล์ใดที่ไม่กำหนดค่าคงที่ที่คาดหวัง งานจะแจ้งให้คุณทราบ โดยทำเช่นนี้ไฟล์ละหนึ่งไฟล์ เพราะถ้ามันเลื่อนไป การโหลดไฟล์ที่ล้มเหลวหนึ่งไฟล์อาจกระจายไปยังความล้มเหลวอื่นที่ไม่เกี่ยวข้องกับการตรวจสอบที่เราต้องการ และรายงานข้อผิดพลาดจะทำให้สับสน
ถ้ามีค่าคงที่หนึ่งรายการที่รายงาน ให้แก้ไขรายการนั้นและรันงานอีกครั้ง ทำซ้ำจนกว่าคุณจะได้ผลลัพธ์ "All is good!"
เช่น:
% bin/rails zeitwerk:check
Hold on, I am eager loading the application.
expected file app/models/vat.rb to define constant Vat
VAT เป็นภาษีของยุโรป ไฟล์ app/models/vat.rb
กำหนดค่า VAT
แต่ autoloader คาดหวัง Vat
ทำไม?
6.3 คำย่อ
นี่เป็นประเภทที่พบบ่อยที่สุดของความไม่สอดคล้อง มันเกี่ยวกับคำย่อ มาเรียนรู้ว่าทำไมเราจึงได้รับข้อความผิดพลาดนั้น
autoloader แบบคลาสสิกสามารถโหลด VAT
เพราะข้อมูลนำเข้าของมันคือชื่อค่าคงที่ที่ขาดหายไป VAT
จะเรียกใช้ underscore
บนมันซึ่งจะให้ผลลัพธ์เป็น vat
และมองหาไฟล์ที่ชื่อ vat.rb
มันทำงาน
ข้อมูลนำเข้าของ autoloader ใหม่คือระบบไฟล์ โดยให้ Zeitwerk เรียกใช้ camelize
บน vat
ซึ่งจะให้ผลลัพธ์เป็น Vat
และคาดหวังให้ไฟล์กำหนดค่าคงที่ Vat
นั่นคือสิ่งที่ข้อความผิดพลาดกล่าวถึง
การแก้ไขปัญหานี้ง่าย เพียงแค่บอก inflector เกี่ยวกับคำย่อนี้:
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "VAT"
end
การทำเช่นนี้จะมีผลต่อวิธีการเปลี่ยนรูปคำทั่วโลกของ Active Support อาจจะเป็นไปได้ แต่ถ้าคุณต้องการคุณยังสามารถส่งการแทนที่ไปยัง inflector ที่ใช้โดย autoloader ได้เช่นกัน ```ruby
config/initializers/zeitwerk.rb
Rails.autoloaders.main.inflector.inflect("vat" => "VAT") ```
ด้วยตัวเลือกนี้คุณจะมีการควบคุมมากขึ้น เนื่องจากเฉพาะไฟล์ที่เรียกว่า vat.rb
หรือไดเรกทอรีที่เรียกว่า vat
เท่านั้นที่จะถูกเปลี่ยนรูปเป็น VAT
ไฟล์ที่เรียกว่า vat_rules.rb
จะไม่ได้รับผลกระทบจากนั้นและสามารถกำหนด VatRules
ได้ดี นี่อาจเป็นสิ่งที่มีประโยชน์ถ้าโปรเจกต์มีความไม่สอดคล้องในการตั้งชื่อแบบนี้
เมื่อทุกอย่างเรียบร้อยแล้ว แนะนำให้ยังคงตรวจสอบโปรเจกต์ในชุดทดสอบ ส่วน ตรวจสอบความเข้ากันได้ของ Zeitwerk ในชุดทดสอบ อธิบายวิธีการทำนี้
6.4 ข้อกังวล
คุณสามารถโหลดและโหลดแบบกระจายจากโครงสร้างมาตรฐานด้วยไดเรกทอรีย่อย concerns
เช่น
app/models
app/models/concerns
โดยค่าเริ่มต้น app/models/concerns
เป็นส่วนหนึ่งของเส้นทางการโหลดและดังนั้นถือว่าเป็นไดเรกทอรีราก ดังนั้น โดยค่าเริ่มต้น app/models/concerns/foo.rb
ควรจะกำหนด Foo
ไม่ใช่ Concerns::Foo
หากแอปพลิเคชันของคุณใช้ Concerns
เป็นเนมสเปซ คุณมีตัวเลือกสองอย่าง:
- ลบเนมสเปซ
Concerns
จากคลาสและโมดูลเหล่านั้นและอัปเดตโค้ดไคลเอ็นต์ - ปล่อยให้สิ่งที่เป็นไปได้โดยการลบ
app/models/concerns
จากเส้นทางการโหลดแบบกระจาย:
# config/initializers/zeitwerk.rb
ActiveSupport::Dependencies.
autoload_paths.
delete("#{Rails.root}/app/models/concerns")
6.5 มี app
ในเส้นทางการโหลดแบบกระจาย
บางโปรเจกต์ต้องการสิ่งที่เหมือนกับ app/api/base.rb
เพื่อกำหนด API::Base
และเพิ่ม app
เข้าไปในเส้นทางการโหลดแบบกระจายเพื่อทำให้เป็นไปได้
เนื่องจาก Rails จะเพิ่มไดเรกทอรีย่อยทั้งหมดของ app
เข้าสู่เส้นทางการโหลดแบบอัตโนมัติ (กับข้อยกเว้นบางอย่าง) เราจึงมีสถานการณ์อีกหนึ่งที่มีไดเรกทอรีรากที่ซ้อนกัน เหมือนกับสิ่งที่เกิดขึ้นกับ app/models/concerns
การตั้งค่านี้จะไม่ทำงานอีกต่อไป
อย่างไรก็ตาม คุณสามารถเก็บโครงสร้างนั้นไว้ได้ เพียงแค่ลบ app/api
ออกจากเส้นทางการโหลดแบบกระจายในไฟล์เริ่มต้น:
# config/initializers/zeitwerk.rb
ActiveSupport::Dependencies.
autoload_paths.
delete("#{Rails.root}/app/api")
ระวังเรื่องไดเรกทอรีย่อยที่ไม่มีไฟล์ที่จะโหลดแบบกระจาย / โหลดแบบกระจาย เช่น หากแอปพลิเคชันมี app/admin
พร้อมกับทรัพยากรสำหรับ ActiveAdmin คุณต้องละเว้นการโหลดแบบกระจายของพวกเขาเช่นกัน เช่นเดียวกับ assets
และเพื่อนๆ:
# config/initializers/zeitwerk.rb
Rails.autoloaders.main.ignore(
"app/admin",
"app/assets",
"app/javascripts",
"app/views"
)
โดยไม่ตั้งค่าดังกล่าวแอปพลิเคชันจะโหลดแบบกระจายพวกนั้น จะเกิดข้อผิดพลาดใน app/admin
เนื่องจากไฟล์ของมันไม่ได้กำหนดค่าคงที่ และจะกำหนดโมดูล Views
เป็นตัวอย่างที่ไม่ต้องการเป็นผลข้างเคียง
ดังที่คุณเห็น การมี app
ในเส้นทางการโหลดแบบกระจายเป็นเรื่องที่เป็นไปได้ทางเทคนิค แต่ค่อนข้างยาก
6.6 ค่าคงที่ที่โหลดแบบกระจายและเนมสเปซที่ระบุโดยชัดแจ้ง
หากมีเนมสเปซที่ระบุในไฟล์ เช่น Hotel
ที่นี่:
app/models/hotel.rb # กำหนด Hotel
app/models/hotel/pricing.rb # กำหนด Hotel::Pricing
ค่าคงที่ Hotel
ต้องถูกกำหนดโดยใช้คีย์เวิร์ด class
หรือ module
เช่น:
class Hotel
end
ถูกต้อง
การเลือกทางเลือกอื่น เช่น
Hotel = Class.new
หรือ
Hotel = Struct.new
จะไม่ทำงาน อ็อบเจกต์ลูกเช่น Hotel::Pricing
จะไม่พบ
ข้อจำกัดนี้ใช้เฉพาะเนมสเปซที่ระบุโดยชัดแจ้ง เท่านั้น คลาสและโมดูลที่ไม่กำหนดเนมสเปซสามารถกำหนดได้โดยใช้รูปแบบเหล่านั้น
6.7 ไฟล์หนึ่งไฟล์หนึ่งค่าคงที่ (ในระดับบนเดียวกัน)
ในโหมด classic
คุณสามารถกำหนดค่าคงที่หลายค่าในระดับบนเดียวกันและให้โหลดใหม่ทั้งหมดได้ เช่น โดยให้
class A
end
class B
end
# app/models/foo.rb
class Foo
end
class Bar
end
ในขณะที่ Bar
ไม่สามารถโหลดอัตโนมัติได้ การโหลดอัตโนมัติ Foo
จะทำให้ Bar
ถูกทำเครื่องหมายว่าโหลดอัตโนมัติด้วย
นี่ไม่ใช่กรณีในโหมด zeitwerk
คุณจำเป็นต้องย้าย Bar
ไปยังไฟล์ของตัวเอง bar.rb
หนึ่งไฟล์หนึ่งค่าคงที่ด้านบน
สิ่งนี้มีผลเฉพาะค่าคงที่ในระดับบนเดียวกันเช่นในตัวอย่างด้านบน คลาสและโมดูลภายในจะไม่มีปัญหา ตัวอย่างเช่นพิจารณา
# app/models/foo.rb
class Foo
class InnerClass
end
end
หากแอปพลิเคชันโหลด Foo
อีกครั้ง จะโหลด Foo::InnerClass
อีกครั้งด้วย
6.8 การใช้ Globs ใน config.autoload_paths
ระวังการกำหนดค่าที่ใช้เครื่องหมาย * อย่างเช่น
config.autoload_paths += Dir["#{config.root}/extras/**/"]
ทุกส่วนของ config.autoload_paths
ควรแทนที่เนมสเปซระดับบน (Object
) นั่นจะไม่ทำงาน
ในการแก้ไขปัญหานี้ เพียงเอาเครื่องหมาย * ออก:
config.autoload_paths << "#{config.root}/extras"
6.9 การตกแต่งคลาสและโมดูลจากเอ็นจิน
หากแอปพลิเคชันของคุณตกแต่งคลาสหรือโมดูลจากเอ็นจิน โอกาสที่มันจะทำอย่างนี้ที่บางที่:
config.to_prepare do
Dir.glob("#{Rails.root}/app/overrides/**/*_override.rb").sort.each do |override|
require_dependency override
end
end
นั่นต้องอัปเดต: คุณต้องแจ้งให้ autoloader หลักรู้ว่าจะเพิกถอนการใช้งานไดเรกทอรีที่มีการแทนที่และคุณต้องโหลดพวกเขาด้วย load
แทน อย่างเช่นนี้:
overrides = "#{Rails.root}/app/overrides"
Rails.autoloaders.main.ignore(overrides)
config.to_prepare do
Dir.glob("#{overrides}/**/*_override.rb").sort.each do |override|
load override
end
end
6.10 before_remove_const
Rails 3.1 เพิ่มการสนับสนุนสำหรับ callback ที่เรียกว่า before_remove_const
ซึ่งถูกเรียกใช้หากคลาสหรือโมดูลตอบสนองต่อเมธอดนี้และกำลังจะโหลดใหม่ การเรียกใช้งานนี้ยังไม่ได้รับการเอกสารอื่น และมันเป็นไปไม่ได้ว่าโค้ดของคุณจะใช้งานมัน
อย่างไรก็ตาม ในกรณีที่มันทำงาน คุณสามารถเขียนใหม่ได้เช่น
class Country < ActiveRecord::Base
def self.before_remove_const
expire_redis_cache
end
end
เป็น
# config/initializers/country.rb
if Rails.application.config.reloading_enabled?
Rails.autoloaders.main.on_unload("Country") do |klass, _abspath|
klass.expire_redis_cache
end
end
6.11 Spring และ Environment test
Spring โหลดโค้ดแอปพลิเคชันหากมีการเปลี่ยนแปลงอะไรบางอย่าง ในสภาพแวดล้อม test
คุณต้องเปิดใช้งานการโหลดใหม่เพื่อให้มันทำงาน:
# config/environments/test.rb
config.cache_classes = false
หรือตั้งแต่ Rails 7.1:
# config/environments/test.rb
config.enable_reloading = true
มิฉะนั้น คุณจะได้รับ:
reloading is disabled because config.cache_classes is true
หรือ
reloading is disabled because config.enable_reloading is false
สิ่งนี้ไม่มีผลกระทบต่อประสิทธิภาพ
6.12 Bootsnap
โปรดตรวจสอบว่าคุณได้รับการขึ้นอยู่กับ Bootsnap เวอร์ชัน 1.4.4 ขึ้นไป
7 ตรวจสอบการปฏิบัติตาม Zeitwerk ในชุดทดสอบ
งาน zeitwerk:check
มีประโยชน์ในขณะที่กำลังย้าย หลังจากที่โครงการเป็นไปตามมาตรฐานแล้ว แนะนำให้ทำการตรวจสอบนี้อัตโนมัติ ในการทำเช่นนี้ การโหลดแอปพลิเคชันอย่างรวดเร็วเพียงพอ ซึ่งเป็นสิ่งที่ zeitwerk:check
ทำจริงๆ
7.1 การสร้างความสัมพันธ์ต่อเนื่อง
หากโครงการของคุณมีการสร้างความสัมพันธ์ต่อเนื่องอยู่ คุณควรทำการโหลดแอปพลิเคชันอย่างรวดเร็วเมื่อชุดทดสอบทำงานที่นั่น หากแอปพลิเคชันไม่สามารถโหลดอย่างรวดเร็วได้ด้วยเหตุผลใดๆ คุณต้องการทราบใน CI ดีกว่าที่จะเกิดขึ้นในการใช้งานจริง ใช่ไหม?
CI โดยทั่วไปจะตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างเพื่อแสดงให้รู้ว่าชุดทดสอบกำลังทำงานที่นั่น ตัวอย่างเช่นอาจเป็น CI
:
# config/environments/test.rb
config.eager_load = ENV["CI"].present?
ตั้งแต่ Rails 7 เริ่มต้นแอปพลิเคชันที่สร้างขึ้นใหม่จะถูกกำหนดค่าเช่นนั้นโดยค่าเริ่มต้น
7.2 ชุดทดสอบเบา
หากโครงการของคุณไม่มีการรวมต่อเนื่อง คุณยังสามารถโหลดชุดทดสอบเบาๆ ได้โดยเรียกใช้ Rails.application.eager_load!
:
7.2.1 Minitest
require "test_helper"
class ZeitwerkComplianceTest < ActiveSupport::TestCase
test "โหลดไฟล์ทั้งหมดโดยไม่มีข้อผิดพลาด" do
assert_nothing_raised { Rails.application.eager_load! }
end
end
7.2.2 RSpec
require "rails_helper"
RSpec.describe "การปฏิบัติตาม Zeitwerk" do
it "โหลดไฟล์ทั้งหมดโดยไม่มีข้อผิดพลาด" do
expect { Rails.application.eager_load! }.not_to raise_error
end
end
8 ลบการเรียกใช้ require
ตามประสบการณ์ของฉัน โครงการทั่วไปไม่ทำเช่นนี้ แต่ฉันเคยเห็นบางตัวอย่างและได้ยินเกี่ยวกับบางตัวอื่นๆ
ในแอปพลิเคชัน Rails คุณใช้ require
ในการโหลดโค้ดจาก lib
หรือจากบุคคลที่สามเช่น gem dependencies หรือ standard library อย่าโหลดโค้ดแอปพลิเคชันที่สามารถโหลดอัตโนมัติได้ด้วย require
ดูว่าทำไมนี่เป็นไอเดียที่ไม่ดีแล้วในโหมด classic
ที่นี่.
require "nokogiri" # ดี
require "net/http" # ดี
require "user" # ไม่ดี, ลบส่วนนี้ (ถ้ามี app/models/user.rb)
โปรดลบการเรียกใช้ require
ของประเภทนี้ทั้งหมด
9 คุณสามารถใช้คุณลักษณะใหม่ได้
9.1 ลบการเรียกใช้ require_dependency
ทุกกรณีที่รู้จักของ require_dependency
ถูกกำจัดด้วย Zeitwerk คุณควรค้นหาในโปรเจกต์และลบมัน
หากแอปพลิเคชันของคุณใช้ Single Table Inheritance โปรดดูส่วน Single Table Inheritance ของเรื่อง Autoloading and Reloading Constants (Zeitwerk Mode) guide.
9.2 ชื่อที่มีคุณสมบัติในการกำหนดค่าคลาสและโมดูล
คุณสามารถใช้เส้นทางคงที่ในการกำหนดค่าคลาสและโมดูลได้อย่างเข้มแข็ง:
# Autoloading ในส่วนของคลาสนี้ตรงกับเซมันติกของ Ruby ตอนนี้
class Admin::UsersController < ApplicationController
# ...
end
สิ่งที่ควรระวังคือ ขึ้นอยู่กับลำดับการดำเนินการ โหลดโค้ดแบบคลาสิกอาจสามารถโหลด Foo::Wadus
ใน
class Foo::Bar
Wadus
end
ซึ่งไม่ตรงกับเซมันติกของ Ruby เนื่องจาก Foo
ไม่ได้อยู่ในการซ้อนกัน และจะไม่ทำงานเลยในโหมด zeitwerk
หากคุณพบกรณีเช่นนี้คุณสามารถใช้ชื่อที่มีคุณสมบัติ Foo::Wadus
:
class Foo::Bar
Foo::Wadus
end
หรือเพิ่ม Foo
เข้าไปในการซ้อนกัน:
module Foo
class Bar
Wadus
end
end
9.3 ความปลอดภัยของเธรดทุกที่
ในโหมด classic
การโหลดค่าคงที่ไม่ปลอดภัยสำหรับเธรด แต่ Rails มีการล็อคเพื่อทำให้การร้องขอเว็บปลอดภัยสำหรับเธรด
การโหลดค่าคงที่ปลอดภัยสำหรับเธรดในโหมด zeitwerk
ตัวอย่างเช่น คุณสามารถโหลดอัตโนมัติในสคริปต์ที่ใช้หลายเธรดที่ถูกดำเนินการโดยคำสั่ง runner
9.4 การโหลดแบบกระจายและโหลดอัตโนมัติเป็นความสอดคล้องกัน
ในโหมด classic
หาก app/models/foo.rb
กำหนด Bar
คุณจะไม่สามารถโหลดไฟล์นั้นได้ แต่การโหลดแบบกระจายจะทำงานเนื่องจากโหลดไฟล์แบบลูกโซ่โดยไม่คำนึงถึงอะไร สิ่งนี้อาจเป็นแหล่งกำเนิดของข้อผิดพลาดหากคุณทดสอบสิ่งที่โหลดแบบกระจายก่อน การดำเนินการอาจล้มเหลวในการโหลดอัตโนมัติในภายหลัง
ในโหมด zeitwerk
ทั้งการโหลดแบบกระจายและโหลดอัตโนมัติเป็นความสอดคล้องกัน พวกเขาล้มเหลวและมีข้อผิดพลาดในไฟล์เดียวกัน
ข้อเสนอแนะ
คุณสามารถช่วยปรับปรุงคุณภาพของคู่มือนี้ได้
กรุณาช่วยเพิ่มเติมหากพบข้อผิดพลาดหรือข้อผิดพลาดทางความจริง เพื่อเริ่มต้นคุณสามารถอ่านส่วน การสนับสนุนเอกสาร ของเราได้
คุณอาจพบเนื้อหาที่ไม่สมบูรณ์หรือเนื้อหาที่ไม่ได้อัปเดต กรุณาเพิ่มเอกสารที่ขาดหายไปสำหรับเนื้อหาหลัก โปรดตรวจสอบ Edge Guides ก่อนเพื่อตรวจสอบ ว่าปัญหาได้รับการแก้ไขหรือไม่ในสาขาหลัก ตรวจสอบ คู่มือแนวทาง Ruby on Rails เพื่อดูรูปแบบและกฎเกณฑ์
หากคุณพบข้อผิดพลาดแต่ไม่สามารถแก้ไขได้เอง กรุณา เปิดปัญหา.
และสุดท้าย การสนทนาใด ๆ เกี่ยวกับ Ruby on Rails เอกสารยินดีต้อนรับที่สุดใน เว็บบอร์ดอย่างเป็นทางการของ Ruby on Rails.