概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Ruby 2.6 added option to raise exception in Kernel#system
- 原文公開日: 2018/04/15
- 著者: Amit Choudhary
- サイト: BigBinary
Ruby 2.6先行チェック: Kernel#systemにexception:
オプションが追加(翻訳)
Ruby 2.6シリーズの記事です。Ruby 2.6.0-preview2は最近リリースされました。
私たちが書くRailsアプリの設定/デプロイ自動化スクリプトでは、bundle install
やrake db:create
やrake db:migrate
などのシステムコマンドをあちこちで実行しています。
Railsプロジェクトのセットアップスクリプトでのマイグレーションをrake db:migrate
で行う必要があるとします。これはKernel#system
メソッドで実行できます。
irb> system('rake db:migrate')
Ruby 2.5.0
system
を実行するとtrue
かfalse
が返ります。system
のもうひとつの機能は、例外を握りつぶすことです。
system
コマンドでマイグレーションが成功した場合は、true
を返します。
irb> system('rake db:migrate')
# => true
マイグレーションでテーブルにカラムを追加しようとしたら、テーブルが存在しなかったとしましょう。この場合system
コマンドはfalse
を返します。
irb> system('rake db:migrate')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
# => false
system
コマンドの実行に失敗した場合にfalse
が返るので、上では例外が発生しません。
しかし次のように明示的にraise
すればセットアップスクリプトを停止できます。
irb> system('rake db:migrate') || raise('Failed to run migrations')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
2: from /Users/amit/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `<main>'
1: from (irb):4
RuntimeError (Failed to run migrations)
Ruby 2.6.0-preview1
Ruby 2.6のKernel#system
ではexception: true
オプションが使えるようになったので、上のように明示的なraise
によるスクリプト停止コードを書かなくて済むようになりました。
irb> system('rake db:migrate', exception: true)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
3: from /Users/amit/.rvm/rubies/ruby-2.6.0-preview1/bin/irb:11:in `<main>'
2: from (irb):2
1: from (irb):2:in `system'
RuntimeError (Command failed with exit 1: rake)
exception
オプションが指定されていない場合はRuby 2.5と同様にfalse
を返します。
irb> system('rake db:migrate', exception: false)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "admins" does not exist
: ALTER TABLE "admins" ADD "first_name" character varying
.
.
.
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
=> false
- コミット: fb29cffab0
- やりとり: #14386
なお、スクリプト実行に使えるのはsystem
だけではありません。6年前のBigBinaryブログで、backtick
、exec
、sh
、popen3
、 popen2e
、Process.spawn
との違いについて説明しています。