Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เข้าใจ Ruby & Rails Consoles: `irb`, `bundle exec irb`, `bundle console`, และ `rails console`

มีหลายวิธี launch Ruby/Rails console: irb, bundle exec irb, bundle console, rails console ดูคล้ายกัน แตทำงานต่างกันนิดหน่อย

ถ้าไม่รู้ความต่าง จะมีปัญหา อาจเชื่อม ActiveRecord models กับ database ไม่ได้ หรือ require file ได้ version ผิด หรือ library ที่คิดว่ามี จริงๆ แล้วไม่มี

ทำยังไงให้แน่ใจว่าใช้ console ถูกต้องตอนที่ถูกต้อง?

Bundler vs non-Bundler

irb คือ plain Ruby console ไม่สนใจ Gemfile โหลดแค่ core Ruby libraries อะไรอยากได้ ต้อง require เอง

ติดตั้ง gem ด้วย gem install require ใน irb ได้ ถ้า bundle install อาจ require ได้ ขึ้นอยู่กับ Bundler วางไว้ไหน (Bundler วาง gems นอก Ruby gem path บางครั้ง ถ้า bundle install --path หรือ --deployment)

เพราะ irb ไม่สน Gemfile versions ใน Gemfile.lock ไม่มีผล irb โหลด version ใหม่สุดที่หาเจอ:

~/Source/testapps/consoles[master *] jweiss$ gem list rails *** LOCAL GEMS *** rails (4.2.0.beta2, 4.2.0.beta1, 4.1.5, 4.1.1) ~/Source/testapps/consoles jweiss$ cat Gemfile | grep rails gem 'rails', '4.1.5' ~/Source/testapps/consoles jweiss$ irb irb(main):001:0> require 'rails' => true irb(main):002:0> Rails.version => "4.2.0.beta2" 

ทำให้ปัญหาแปลกๆ กับโค้ด ถ้าไม่คาดคิด

irb ดีสำหรับเล่น core Ruby files เร็ว ไม่ต้อง setup

แต่ถ้าอยากใช้ Gemfile ตอนรัน console ให้รัน bundle exec irb แทน bundle exec ให้ irb โหลด gems ที่ Bundler รู้ และ แค่ gems ที่ Bundler รู้:

~/Source/testapps/consoles jweiss$ bundle exec irb irb(main):001:0> require 'rails' => true irb(main):002:0> Rails.version => "4.1.5" 

ได้ Rails version ที่ต้องการพอดี

bundler/setup vs Bundler.require

รัน bundle console แทน bundle exec irb เมื่อไหร่?

bundle exec irb setup ให้ require gems ใน Gemfile.lock ได้อย่างเดียว

bundle console ไปอีกขั้น ตอนรัน bundle console ไม่ต้อง require gems ใน Gemfile แล้ว มัน require ให้หมด:

~/Source/testapps/consoles jweiss$ bundle exec irb irb(main):001:0> Rails.version NameError: uninitialized constant Rails from (irb):1 from /usr/local/bin/irb:11:in `<main>' ~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.version => "4.1.5" 

พฤติกรรมนี้ได้จากการเรียก Bundler.require ใน bundle exec irb console ด้วย Gem ใน Gemfile ที่ไม่ marked require: false จะ auto-required ใช้ได้เลยโดยไม่ต้อง require เพิ่ม ตอนทำงาน projects ที่มี Gemfile สะดวกมาก

เข้าถึง Rails

ยังมีความต่างอีก: bundle console และ rails console

~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.application => nil ~/Source/testapps/consoles jweiss$ rails console Loading development environment (Rails 4.1.5) irb(main):001:0> Rails.application => #<Consoles::Application:0x007f8db4d5ab30 @_all_autoload_paths=["/Users/jweiss... 

bundle console แค่ require gems มากๆ rails console require gems นั้น แต่ยัง load ทั้ง Rails environment, setup autoloading, initialize application, และให้ full Rails environment เล่น

ได้แบบ Rails console จาก bundle console ถ้า require config/environment.rb:

~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.application => nil irb(main):002:0> require_relative 'config/environment.rb' => true irb(main):003:0> Rails.application => #<Consoles::Application:0x007fd264f0b7c8 @_all_autoload_paths=["/Users/jweiss... 

แต่ละอัน ซับซ้อนขึ้นนิดหน่อย

สรุป:

  • irb basic Ruby console ไม่สน Gemfile มีแค่ core Ruby classes โดยไม่ต้อง require ไม่โหลด gems ที่ Bundler วางนอก RubyGems load path ได้ง่าย

  • bundle exec irb เหมือน irb ถ้า require bundler/setup ด้วย require gems ใน Gemfile.lock ได้ แตโหลด gems นั้นได้ ไม่ว่าจะวางไหน

  • bundle console เหมือน bundle exec irb ถ้าเรียก Bundler.require ด้วย Gems ใน Gemfile (ยกเว้น require: false) ใช้ได้เลยโดยไม่ require สะดวกมากตอนเขียน gems หรือ non-Rails code

  • rails console เหมือนรัน bundle console ใน Rails app ถ้า require config/environment.rb ด้วย เล่นกับทั้งแอป Rails autoloads และ database connections ทำงาน ทุกอย่าง hooked up ตามที่คาด หากทำงานใน Rails app นี่ console ที่ช่วยมากที่สุด

ความต่างไม่มาก แตบางอย่างไม่ใหญ่ (Oh file นี้ไม่ required? require ใหม่ซิ!) บางอย่างน่าหงุดหงิดมากถ้าไม่รู้ (WHY WRONG RAKE VERSION AGAIN!?)

แตถ้ารู้ concept แต่ละ console จะใช้ console ที่ถูกต้องตอนที่ถูกต้อง และ libraries ที่ต้องการจะอยู่ใกล้มือตอนต้องการ