Dentoo.LT #16 での発表資料です。
https://atnd.org/events/85762
自己紹介
普段やってること
SideCI
自動コードレビュー
Shibart
GitHub の芝を Tシャツにする
Agenda
RuboCop の完全さについて
RuboCop とは?
- Ruby 用の静的解析ツール
- スタイルチェッカ
- Lint
例1
スタイルが崩れているのをチェックできる
def foo
do_something
end
test.rb:1:3: C: Indentation of first line in file detected.
def foo
^^^
test.rb:2:1: C: Use 2 (not -2) spaces for indentation.
do_something
^^
例2
バグの元を検査できる
# Ruby では 0 < x && x < 20 のように書かないと死ぬ
if 0 < x < 20
do_something
end
test.rb:2:4: W: Use the && operator to compare multiple values.
if 0 < x < 20
^^^^^^^^^^
本日のメイン
Auto Correct
- RuboCop には Auto Correct という便利機能がある
- 名前のとおり、自動修正
例1 おかしいコードを自動で修正できる
def foo
bar
end
$ rubocop
Inspecting 1 file
C
Offenses:
test.rb:1:3: C: [Corrected] Indentation of first line in file detected.
def foo
^^^
test.rb:2:1: C: [Corrected] Use 2 (not 4) spaces for indentation.
bar
^^^^
test.rb:2:3: C: [Corrected] Use 2 (not 0) spaces for indentation.
bar
1 file inspected, 3 offenses detected, 3 offenses corrected
$ cat test.rb
def foo
bar
end
例2 ループできる
def foo
if cond
bar
else
nil
end
end
else
節は省略出来る
def foo
if cond
bar
end
end
else
節が存在せず body が1行のif
は後置で書ける
def foo
bar if cond
end
これを一発で変換してくれる!
メリット
RuboCop の使用者
- 雑にコードを書いて RuboCop が整形!
RuboCop の実装者
- ループするから、多少雑に Auto-Correct を実装しても ok
- 「不要な空白が出来てしまったらー」とか考えなくてよい
しくみ
- 問題のあるコードを探す
- 問題のあるコードがなければ終了
- 問題のあるコードを直す
- 1に戻る
仕組みの要点
- ループがある
- コードを直せる
- 状態が変わる
つまり、ループの中で状態を変化できる
なんでもできそうな気がしてきましたね?
やってみた
RuboCop の Auto-Correct で Brainfuck インタプリタの実装
Brainfuck とは
- 難解プログラミング言語の一種
- チューリング完全
- つまり、Brainfuck を実装できる言語はチューリング完全
言語仕様
出来る操作は以下の8つのみ
- ポインタのインクリメント、デクリメント(
>
,<
) - ポインタが示す値のインクリメント、デクリメント
(
+,
-`) - ポインタが示す値を出力(
.
) - ポインタが指す先に入力を代入(
,
) - ポインタが指す値が0なら、対応する
]
の直後にジャンプ([
) - 対応する
[
にジャンプ(]
)
Hello, world!
Brainfuck の Hello World 例
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
RuboCop で実行
class Program < BrainFuck
PC = 0
Code = <<-EOS
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
EOS
Memory = []
Stdout = ''
Stdin = ''
Pointer = 0
end
$ rubocop -r rubocop/brainfuck --only Brainfuck/Interpreter -a
Inspecting 1 file
C
Offenses:
test.rb:1:1: C: [Corrected] Interpreting the brainfuck code...
class Program < BrainFuck ...
^^^^^^^^^^^^^^^^^^^^^^^^^
1 file inspected, 1 offense detected, 1 offense corrected
after
class Program < BrainFuck
PC = 119
Code = <<-EOS
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
EOS
Memory = [0, 72, 100, 33]
Stdout = "Hello, world!"
Stdin = ''
Pointer = 3
end
実装
See https://github.com/pocke/rubocop-brainfuck/blob/master/lib/rubocop/cop/brainfuck/interpreter.rb
まとめ
- RuboCop の Auto-Correct はチューリング完全である
- とはいえループ以外は Ruby を書いているだけなので、当たり前とも言える
- いろんなもので Brainfuck を実装してチューリング完全であることを証明しよう!
- 例: https://cpplover.blogspot.jp/2013/10/blog-post_20.html