読者です 読者をやめる 読者になる 読者になる

CLI から Wandbox を利用してソースファイルを実行する gem をつくった

Web からプログラミングのソースコードを実行できる Wandbox というサイトがあるんですが、それの API を利用してプログラミング環境がなくても CLI からソースファイルを実行する事ができる CLI ツールをつくりました。

インストール

$ gem install wandbox

ソースコード

使い方

wandbox コマンドを使用してソースファイルを実行したりします。

ソースファイルを実行する

wandbox run <filename><filename> を Wandbox で実行する事ができます。

$ cat test.rb
5.times.each { |n|
    puts n
}
$ wandbox run test.rb
0
1
2
3
4

使用するコンパイラを指定する

--compiler= オプションで使用するコンパイラを指定できます。

$ cat test.cpp
#include <iostream>

int
main(){
    std::cout << __VERSION__ << std::endl;
    return 0;
}
$ wandbox run test.cpp --compiler=clang-head
4.2.1 Compatible Clang 3.7.0 (trunk 241983)

使用できるコンパイラ環境の一覧を出力する

サブコマンド compiler-listコンパイラ環境一覧を出力します。

$ wandbox compiler-list
Compiler list:
  gcc-head
  gcc-5.2.0
  gcc-5.1.0
  gcc-4.9.2
  gcc-4.9.1
  gcc-4.9.0
  gcc-4.8.2
  gcc-4.8.1
  gcc-4.7.3
  gcc-4.6.4
  gcc-4.5.4
  gcc-4.4.7
  gcc-4.3.6
  clang-head
  clang-3.6
  clang-3.5
  clang-3.4
  clang-3.3
  clang-3.2
  clang-3.1
  clang-3.0
  gcc-4.8.2-c
  clang-3.3-c
  gcc-4.8.2-pp
  gdc-head
  rill-head
  ghc-head
  ghc-7.8.3
  ghc-7.6.3
  mcs-head
  mcs-3.2.0
  mcs-2.6.7
  perl-head
  perl-5.19.2
  perl-5.18.0
  python-head
  python-2.7-head
  python-3.3.2
  python-2.7.3
  pypy-2.1
  ruby-head
  ruby-2.0.0-p247
  ruby-1.9.3-p0
  mruby-head
  php-head
  php-5.5.6
  erlang-head
  erlang-maint
  elixir-head
  node-head
  node-0.10.24
  mozjs-24.2.0
  coffee-script-head
  coffee-script-1.7.1
  coffee-script-1.6.3
  sqlite-head
  sqlite-3.8.1
  scala-2.12.x
  scala-2.11.x
  scala-2.11.2
  lua-5.3.0
  lua-5.2.2
  rust-head
  rust-1.0.0
  vim-7.4.729
  bash
  lazyk
  clisp-2.49.0
  fpc-2.6.2
  java7-openjdk
  groovy-2.2.1

ここで出力された値は --compiler= に渡すことができます。

コンパイラのオプションを設定する

--options= オプションで Wandbox で用意されているオプションを指定します。
例えば、boost を使用したい場合は boost-1.58 というオプションを渡します。

$ cat test.cpp
#include <boost/config.hpp>
#include <iostream>

int
main(){
    std::cout << BOOST_COMPILER << std::endl;
    return 0;
}
$ wandbox run test.cpp --options=boost-1.58
GNU C++ version 6.0.0 20150711 (experimental)

また、--options= に設定できる値は『実行するコマンドのオプションではない』ので注意してください。
この --options= に設定できるオプション一覧はサブコマンド compiler <compiler-name> で調べることができます。

$ wandbox compiler gcc-head --options=warning,c++11
[Compiler]:
  gcc HEAD

[Language]:
  C++

[Version]:
  6.0.0 20150718 (experimental)

[Compiler command]:
  $ g++ prog.cc -Wall -Wextra -std=c++11

[Option list]:
  boost-1.47           : -I/usr/local/boost-1.47.0/include
  boost-1.48           : -I/usr/local/boost-1.48.0/include
  boost-1.49           : -I/usr/local/boost-1.49.0/include
  boost-1.50           : -I/usr/local/boost-1.50.0/include
  boost-1.51           : -I/usr/local/boost-1.51.0/include
  boost-1.52           : -I/usr/local/boost-1.52.0/include
  boost-1.53           : -I/usr/local/boost-1.53.0/include
  boost-1.54           : -I/usr/local/boost-1.54.0/include
  boost-1.55           : -I/usr/local/boost-1.55.0/include
  boost-1.56           : -I/usr/local/boost-1.56.0/include
  boost-1.57           : -I/usr/local/boost-1.57.0/include
  boost-1.58           : -I/usr/local/boost-1.58.0/include
  c++11                : -std=c++11
  c++14                : -std=c++14
  c++1z                : -std=c++1z
  c++98                : -std=c++98
  cpp-pedantic         : -pedantic
  cpp-pedantic-errors  : -pedantic-errors
  cpp-verbose          : -v
  gnu++11              : -std=gnu++11
  gnu++14              : -std=gnu++14
  gnu++1z              : -std=gnu++1z
  gnu++98              : -std=gnu++98
  optimize             : -O2 -march=native
  sprout               : -I/usr/local/sprout
  warning              : -Wall -Wextra

複数のソースファイルを実行する

run には複数のソースファイル名を渡すことができます。

$ cat prog.rb
require_relative "./test"

puts X.method
$ cat test.rb
module X
    def self.method
        "X.method"
    end
end
$ wandbox run prog.rb test.rb
X.method

この場合、2つ目以降のファイル名をソースファイル内で参照する事ができます。

Wandbox の permlink を取得する

--save オプションをつけると Wandbox の permlink も一緒に出力します。

$ wandbox run prog.rb --save
http://melpon.org/wandbox/permlink/rCVQCfbdmsqGXaO7
hello world

所感

と、いう感じで Ruby ではじめて CLI ツールをつくってみました。
元々は Thor の練習がてらサクッとつくってみようかなーと初めてみたんですが、凝ってるうちに結構時間が経っていたので一旦リリースすることに。
実装したい機能はまだあるんですが、一応最低限の機能は実装できたかなーという感じです。
gem を公開したのはこれで3回目なんですが、最初に公開した gem-iolite よりはだいぶ Ruby に慣れてきましたね(逆にいえば Ruby のよくわからん部分というのも見えてきた感じもありますが…。

また、今回 CLI ツールをつくるにあたって Thor を使ったんですが、サブコマンドやオプションなんかがさくっと定義する事ができたのでなかなかに便利でした。痒いところに手が届かないこともあったけど
あと本格的に iolite を使ってみたんですが、もう iolite を使わないと Ruby を書くのがだるくなるぐらい便利でした。
実際 gem-wandbox だとほとんどの場面で iolite を使っていてブロックは全く使ってないんじゃないかなーというほど。
いや、マジで便利よ。
そんな感じで雑につくってみたので、問題や要望があれば issues までお願いします。