はじめに
最近私用で Ruby を書く機会があるのですが、IntelliJ 上に Ruby の開発環境を設定する際に少しつまづいた点がいくつかあったので、まとめておきます。
環境情報
- macOS High Sierra : 10.13.3
- IntelliJ IDEA 2018.2 (Ultimate Edition) Build #IU-182.3684.101, built on July 24, 2018
- Ruby : 2.2.3
つまずいたポイント
1. Ruby SDK の設定
まずは、普通に Ruby プラグインをインストールした後に、公式ドキュメント を参考に SDK を設定してみたものの、IntelliJ が Ruby インタープリタを上手く認識してくれませんでした。
IntelliJ の画面で、File > Project Structure > Platform Settings > SDKs > + Ruby SDK > New local... を選択すると、自動で Finder が立ち上がるので、anyenv と rbenv を使用してインストールした ruby のバイナリ(/Users/username/.anyenv/envs/rbenv/versions/x.x.x/bin/ruby
)を指定し、SDK の設定を保存します。
このとき、以下のように Finder 上でドットディレクトリ(.anyenv
) が選択できなくて困るかと思いますが、Cmd + Shift + g
のショートカットで、ディレクトリのパスを文字列で指定することが可能です。
上記で設定した SDK を File > Project Structure... > Project > Project SDK で選択し、設定を保存しようとしてみるものの、「No Ruby interpreter configured for the module 'xxx'」のエラーで保存できず。。。
もしやと思い、再度 公式ドキュメント を確認してみると、
- IntelliJ IDEA supports rbenv Ruby interpreters installed in the default rbenv folder ~/.rbenv only.
との記載がありました。ああ、これが原因ね。。。
というわけで、以下のコマンドでシンボリックリンクを張ることで、無事に問題は解決できました。
$ ln -s ~/.anyenv/envs/rbenv ~/.rbenv
2. minitest の利用
今回は、RubyGems の作成のために Ruby の開発環境が必要だったのですが、IntelliJ から Ruby のテスティングフレームワークである minitest を利用する際にも少しつまずきました。
対象とするプロジェクトは、Bundler を使用して bundle gem <作成するGem名>
コマンドで作成したばかりのものであり、ターミナルから rake test
コマンドでテストが実行可能であることはもちろん確認済みです。
$ rake test master ✚ ✱ ◼
Run options: --seed 52631
# Running:
..
Finished in 0.000988s, 2024.2894 runs/s, 2024.2894 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/*_test.rb"]
end
task :default => :test
こちらも、まずは普通に IntelliJ の画面で、Run > Edit Configurations... > + > Rake からテストの実行のための設定を追加し、Task name には上記 Rakefile にもデフォルトで存在する "test" というタスクを設定する。
設定を保存し、 ボタンでテストを走らせるも、以下のようなエラーでテストが失敗する。
/Users/okamotoyuki/.anyenv/envs/rbenv/versions/2.3.3/bin/ruby /Users/okamotoyuki/.anyenv/envs/rbenv/versions/2.3.3/bin/rake test
Started
##teamcity[enteredTheMatrix timestamp = '2018-08-05T11:33:38.826+0900']
##teamcity[testCount count = '0' timestamp = '2018-08-05T11:33:38.826+0900']
/Users/okamotoyuki/Library/Application Support/IntelliJIdea2018.2/ruby/rb/testing/patch/testunit/minitest/rm_reporter_plugin.rb:112:in `record': undefined method `ends_with?' for "SampleTest":String (NoMethodError)
Did you mean? end_with?
from /Users/okamotoyuki/.anyenv/envs/rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/minitest-5.8.5/lib/minitest.rb:632:in `block in record'
...
rake aborted!
Command failed with status (1): [ruby -I"lib:test:lib" -I"/Users/okamotoyuki/.anyenv/envs/rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/rake-10.4.2/lib" "/Users/okamotoyuki/.anyenv/envs/rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/rake-10.4.2/lib/rake/rake_test_loader.rb" "test/sample_test.rb" ]
Tasks: TOP => test
(See full trace by running task with --trace)
Process finished with exit code 1
エラーの内容としては String.ends_with?
というメソッドが見つからないことを示すもののようですが、メッセージの中にも、
Did you mean? end_with?
と出力されているように、Ruby でデフォルトでサポートされているのは String.end_with? の方だったはず。
調べてみると、これは RUBY-22214 の不具合で、Rails 拡張の API である String.ends_with? を使ってしまっていることが原因のようでした。
すでに修正はされているようですが、まだ修正版がリリースされていないようなので、取り急ぎ String.end_with?
を使用するようにソースを書き換えてみたところ、無事に問題が解消されました。
def record(result)
...
if "#{result.class}".ends_with?("Minitest::Result")
fqn = "#{result.klass}.#{test_name}"
end
...
end
def record(result)
...
if "#{result.class}".end_with?("Minitest::Result")
fqn = "#{result.klass}.#{test_name}"
end
...
end
おわりに
Ruby は最近書き始めたばかりなので、他にも何か気をつけるポイントなどあればコメントいただけると助かります。