Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

「irb」「bundle exec irb」「bundle console」「rails console」の違いとは?Ruby・Railsコンソールの使い分け完全ガイド

RubyやRailsのコンソールを起動する方法はいくつもあります。irbbundle exec irbbundle consolerails consoleはその中でも特によく使われるコマンドです。どれも似て見えますが、実際にはそれぞれ動作が少し異なります。

これらの違いを理解していないと、思わぬ問題に直面することになります。ActiveRecordモデルがデータベースに接続できない、requireしたのに意図しないバージョンのファイルが読み込まれる、使えるはずだったライブラリが存在しない――そんな経験はないでしょうか。

どうすれば、適切なタイミングで適切なコンソールを使い分けられるのでしょうか?この記事では、4つのコンソールの違いを順番に解説します。

Bundlerを使う場合と使わない場合の違い

irbは、単なるプレーンなRubyコンソールです。Gemfileのことは一切考慮せず、Rubyのコアライブラリ以外は何も読み込みません。それ以外のものを使いたい場合は、自分でrequireする必要があります。

gem installでインストールしたgemであれば、irb内で問題なくrequireできます。一方、bundle installでインストールした場合は、Bundlerがgemをどこに配置したかによってrequireできるかどうかが変わります(bundle install --pathbundle install --deploymentを実行すると、BundlerはRubyGemsの標準パスの外にgemを配置することがあります)。

irbGemfileを無視するため、Gemfile.lockに記載されたバージョンもまったく関係ありません。irbは、見つかった中で最新のバージョンのgemを読み込みます。

~/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"

Gemfileでは4.1.5を指定しているのに、実際に読み込まれたのは4.2.0.beta2です。この挙動を想定していないと、コードに非常に奇妙な問題が発生することがあります。

Ruby本体の挙動を確認したいだけなら、irbは最適です。起動が速く、セットアップも不要だからです。

しかし、コンソール実行時にGemfileを反映させたいなら、代わりにbundle exec irbを使いましょう。bundle execを付けることで、irbはBundlerが認識しているgemだけを読み込めるようになります。

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

今度は、期待していたRailsのバージョンが正確に読み込まれました。

bundler/setup と Bundler.require の違い

では、bundle exec irbではなくbundle consoleを使うのは、どんな場面でしょうか?

bundle exec irbは、Gemfile.lockに記載されたgemだけをrequireできるように環境を整えるものです。ただし、gemを使うには依然として自分でrequireする必要があります。

bundle consoleは、そこからさらに一歩進んでいます。bundle consoleを実行すると、Gemfile内のgemを自分でrequireする必要すらありません。あらかじめすべて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"

bundle exec irbではRails定数が未定義エラーになる一方、bundle consoleでは即座にRails.versionを参照できています。

この動作は、bundle exec irbのコンソール内でBundler.requireを呼び出しても再現できます。Gemfile内のrequire: falseとマークされていないすべてのgemが自動的にrequireされ、追加の作業なしですぐに使えるようになります。Gemfileを持つプロジェクトで作業する際には、非常に便利な機能です。

Railsアプリケーションへのアクセス

まだ比較すべき違いが一つ残っています。それはbundle consolerails 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は、単に多数のgemをrequireするだけです。rails consoleも同様にgemをrequireしますが、それに加えてRailsアプリケーション全体の環境を読み込み、オートローディングを設定し、アプリケーションを初期化して、完全なRails環境を提供してくれます。

ちなみに、config/environment.rbをrequireすれば、bundle consoleからでもRailsコンソールに近い状態を作ることができます。

~/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...

まとめ:少しずつ複雑になっていく4つのコンソール

ここまでの内容を整理しましょう。

  • irbは、基本となるRubyコンソールです。Gemfileを無視し、requireしなければコアのRubyクラスしか利用できません。BundlerがRubyGemsのロードパス外にインストールしたgemを簡単に読み込むことはできません。

  • bundle exec irbは、「bundler/setupをrequireした状態のirb」のようなものです。Gemfile.lockにあるgemだけを簡単にrequireできますが、Bundlerがgemをどこに配置していても読み込める点が強みです。

  • bundle consoleは、さらに「Bundler.requireを呼び出した状態のbundle exec irb」のようなものです。Gemfile内のrequire: falseとマークされていないすべてのgemが、requireなしでそのまま使えます。独自のgemを開発しているときや、Rails以外のRubyコードを書いているときに特に便利です。

  • rails consoleは、さらに「config/environment.rbまでrequireしたbundle console」のようなものです。アプリケーション全体を自由に操作でき、オートロードもデータベース接続も正常に機能し、すべてが期待どおりに連携します。Railsアプリで作業しているなら、これが最も役立つコンソールです。

補足:近年のBundler 2系ではbundle consoleコマンド自体が廃止されています。Bundler 2以降の環境では、bundle exec irbを使うか、必要に応じてconfig/environment.rbを読み込むことで同等の環境を構築してください。

これらのコンソールの間に、劇的な違いがあるわけではありません。ほとんどの違いは些細なもので済みます(「このファイルがrequireされていない?じゃあrequireしよう」)。しかし、何が起きているのかを把握していないと、途方もなくイライラさせられることもあります(なぜまたRakeの違うバージョンが読み込まれるんだ!?)。

それぞれのコンソールの背後にある仕組みさえ理解しておけば、適切なタイミングで適切なコンソールを選べるようになります。そうすれば、必要なライブラリはいつでもすぐ手元にあるはずです。

  1. OneDriveとOneDrive for Businessの違いとは?使い分けのポイントを徹底解説

    Microsoftのクラウドストレージサービス「OneDrive」を使えば、どこにいても自分のファイルにアクセスできます。しかし、実はMicrosoftは名前がよく似た2種類のOneDriveを提供しています。「OneDrive」と「OneDrive for Business」のどちらを使うべきかは、クラウドに何を保存するのか、そしてどうやってアクセスする必要があるのかによって変わってきます。 OneDrive(個人向け)の特徴 「OneDrive」は、個人ユーザー向けに設計されたMicrosoftのクラウドサービスです。個人のOutlookアカウントに含まれており、Windows 10では自

  2. Windows 10 HomeとProの違いを徹底解説!自分に合ったエディションの選び方

    新しいPCの購入を検討している場合でも、Windowsを単体で購入する場合でも、Windows 10 HomeとProの違いをあらかじめ把握しておくことが大切です。製品ページなどに特に表記がない場合は、そのデバイスにはWindows 10 Homeが搭載されていると考えてよいでしょう。 そもそも「Home」という名称はやや分かりにくく、実態としては「Windows 10 スタンダード」と呼ぶ方がぴったりです。価格1,000ポンド(約15万円)未満のWindowsデバイスの大半に搭載されており、OSのコア機能がすべて含まれています。 一方のProは、プロフェッショナル、パワーユーザー、ビジネ