blog.tkeo.info

rubyのrefinementsを使ってみたかった

今やってるプロジェクトでrefinementsを使うのが適していそうな場面が出てきたので初めて使ってみることにしたがなんだか微妙な感じになったという日記。

試したバージョンは2.4.0で、このあたりを参考にした。

同じmoduleをincludeしているクラスに対して共通のrefinementsを適用したかったが、moduleに対してrefineは使えないのでrefineブロック内でincludeしてみたが…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
module C
end
class A
  include C
end
class B
  include C
end

module Foo
  def foo
    "foo"
  end

  def foobar
    foo + "bar"
  end
end

module R
  refine A do
    include Foo
  end

  refine B do
    include Foo
  end
end

using R
puts A.new.foo    # => foo
puts B.new.foo    # => foo
puts A.new.foobar # => undefined local variable or method `foo' for #<A:0x007fc71782dcb0> (NameError)

どうもそう単純にはいかないらしい。ぐぬぬ。

いろいろこねくり回した結果、思った通りの動きをするコードは一応何通りか書けた。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module C
end
class A
  include C
end
class B
  include C
end

# module_evalで無理やり突っ込むパターン
FooMethods = -> {
  def foo
    "foo"
  end

  def foobar
    foo + "bar"
  end
}

module R
  refine A do
    module_eval do
      FooMethods.call
    end
  end

  refine B do
    module_eval do
      FooMethods.call
    end
  end
end

# module_eval内でrefineしちゃうパターン
module R2
  %w(A B).each do |klass|
    module_eval <<-CODE
      refine #{klass} do
        def foo
          "foo"
        end

        def foobar
          foo + "bar"
        end
      end
    CODE
  end
end

# あきらめたパターン
module R3
  refine Object do
    def foo
      if kind_of?(C)
        "foo"
      else
        raise NoMethodError
      end
    end

    def foobar
      if kind_of?(C)
        foo + "bar"
      else
        raise NoMethodError
      end
    end
  end
end

using R
puts A.new.foo    # => foo
puts B.new.foo    # => foo
puts A.new.foobar # => foobar

うーん…どれもなんかやだな。 もうちょっとうまいやり方はないものか。

rdbtoolsを使ってredisのデータの内訳を調べた

最近redisのデータ量が増えすぎて、スワップを使い始めている状態になってしまった。 メモリ使用量は7.3GBでキーの数は1400万ぐらい。 スケールアップを検討しつつも、余計なデータがないか軽く調査。 以前にもやったことがあるけど忘れるので後のためにメモとして残しておく。

まずrdbファイルを取得する。バックアップのエクスポートで今日のバックアップをS3にエクスポートした。1.8GBぐらい。

ファイルがでかいのでAWS上で作業する。 本番ウェブサーバーのコピーを使って適当に立てたインスタンスにrdbtoolsをインストール。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ sudo pip install rdbtools
Downloading/unpacking rdbtools
  Downloading rdbtools-0.1.9.tar.gz
  Running setup.py (path:/tmp/pip_build_root/rdbtools/setup.py) egg_info for package rdbtools
    warning: no files found matching 'README.textile'
Downloading/unpacking redis (from rdbtools)
  Downloading redis-2.10.5-py2.py3-none-any.whl (60kB): 60kB downloaded
Installing collected packages: rdbtools, redis
  Running setup.py install for rdbtools
    warning: no files found matching 'README.textile'
    Installing redis-memory-for-key script to /usr/bin
    Installing redis-profiler script to /usr/bin
    Installing rdb script to /usr/bin
Successfully installed rdbtools redis
Cleaning up…

これでOKなはずだったが・・・

1
2
3
4
5
6
7
8
9
10
11
$ rdb -c memory dump-2017-03-06-0001.rdb -f redis-memory-2017-03-06.csv
Traceback (most recent call last):
  File "/usr/bin/rdb", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 2655, in <module>
    working_set.require(__requires__)
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 648, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.6/site-packages/pkg_resources.py", line 546, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: redis

あれ?

1
2
$ pip list | grep redis
redis (2.10.5)

??

以前やったときはこんなことにはならなかったが???

よく見るとどうやら最新は9日前にリリースされたバージョンで、前回使ったのは古いやつだったらしい。

1
2
$ sudo pip uninstall rdbtools
$ sudo pip install rdbtools==0.1.8

これでとりあえず動いた。pythonのバージョンの問題な気がするが、よくわからんので放置。

CSVの生成には20分ぐらいかかった。 次は出力されたCSVを加工していく。

1
2
3
4
5
6
7
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,string,"user:6665644:ip_address",104,string,13,13
0,string,"user:5568100:logged_in_time",96,string,8,8
0,string,"user:7540191:ip_address",104,string,13,13
0,string,"user:3428265:ip_address",104,string,12,12
0,string,"user:2176673:logged_in_time",96,string,8,8
...

出力されたCSVの中身はこんな感じ。 redis-objects gem使ってるとこういうキーのやつがいっぱいできちゃうよなー。 まとめやすいようにidっぽい部分を雑に置換する。

1
$ cat redis-memory-2017-03-06.csv | ruby -ne '_,_,key,size = $_.split(","); puts [key.gsub(/:\d+/, ":*"), size].join(",")' > tmp.csv
1
2
3
4
5
6
7
key,size_in_bytes
"user:*:ip_address",104
"user:*:logged_in_time",96
"user:*:ip_address",104
"user:*:ip_address",104
"user:*:logged_in_time",96
...

こいつを合計するスクリプトをざっと書いた。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cat redis-summary.rb
#!/usr/bin/env ruby

count = Hash.new {|h,k| h[k] = 0 }
sum = Hash.new {|h,k| h[k] = 0 }

while line = $stdin.gets
  key,size = line.split(",")
  count[key] += 1
  sum[key] += size.to_i
end

count.keys.each do |key|
  puts [key, count[key], sum[key]].join(",")
end
1
2
3
4
5
6
"user:*:ip_address",5537264,583765440
"user:*:logged_in_time",5538922,531736432
"room:*:ready_members",25817,3654184
"user_deck:*:total_power_cache",548302,57306072
"room:*:status_value",175756,19190496
...

余計なものがたくさんありそうなことはわかったけど、こいつらを消してもまだ足りなさそうな気がするなあ。

追記

定期的に削除する/できるようにする前のデータが残っていたのでまとめて削除した。 実装に手を入れたタイミングで消したつもりだった…。

graph

Octopressデプロイ環境を作り直した

雑なメモ。 会社からでも更新できるように環境を作った。

とりあえずcloneしてsourceブランチに切り替える。

1
2
3
git clone git@github.com:tkeo/tkeo.github.io.git blog
cd blog
git co -t origin/source

もろもろ必要なgemをinstallする。bundle execとか付けたくないので雑にgemsetに突っ込む。

1
2
rbenv gemset init blog
bundle

デプロイするには_deployディレクトリにmasterブランチが必要なのでworktreeを作る。

1
git worktree add _deploy master

これでOK。

fish shellに移行した

学生の頃にzshを使い始めてかれこれ10年以上になるが、2ヶ月ほど前にfishに移行した。 ようやく慣れてきたのでメモを残しておく。

使用しているfishのバージョンは2.4.0で、プラグインなどは入れてない。 oh-my-fishを使うと便利っぽいけど、困ったときに入れたらいいかなと思ってまだ困ってないので使ってない。

config

とりあえず~/.zshrcをベースに~/.config/fish/config.fishを作った。 aliasとかexportとかは大体そのままコピペで動くが、なぜかPATHのexportだけはうまくいかなかったのでsetを使うように変更した。

他はifendで閉じるとか、&&のかわりに; andを使うとか、$( )( )にするとか、気をつけないといけないポイントはいくつかあるけどそのへんは適当に。

補完

サーバーにログインするときはsshrcを使っていて、sshコマンドと同じようにタブでホスト名を補完してほしい。そういうときの設定は以下。

1
complete -c sshrc -w ssh

complete - edit command specific tab-completions

一時的な環境変数

例えばzshの場合だとこんな感じのコマンドを実行することがあるけど

1
RAILS_ENV=test rake db:reset

fishだとこれではダメで、envをつける必要がある。

1
env RAILS_ENV=test rake db:reset

How do I set an environment variable for just one command?

ブレース展開

{ }の中身が展開されるため、展開を抑制したいときはエスケープが必要。

1
git stash drop stash@\{1\}

とか、

1
rails g model foo bar:references\{polymorphic\}

とか。ちょっと面倒。gitの引数の場合はタブ補完でバックスラッシュをちゃんとつけてくれる。

プロセス置換

コマンド実行結果をファイルのように扱うやつ。zshだとこんな感じ。

1
diff <(foo) <(bar)

fishの場合はpsubを使う。

1
diff (foo | psub) (bar | psub)

psub - perform process substitution

履歴

zshのshare_history相当のものが無いため最初は戸惑ったが、普段使っているコマンドのパターンはそれほど多くなかったので履歴が育てば不要だった。

それでもtmuxの別のwindow/paneで少し前に打ったコマンドがほしくなることはたまにあって、そういうときはhistory mergeを実行して履歴を再読込している。

自動でmergeするのを試してみたけどコマンド実行のたびに微妙に待たされてストレスたまるので手動運用のほうがよいと思う。

history - Show and manipulate command history

UTF-16なファイルのgit diffを見たい

gitがUTF-16のファイルをバイナリだと認識してしまって、diffが表示されずに困ったので以下の設定をした。

1
$ git config diff.toutf8.textconv 'nkf -w8'

.gitattributesファイルに以下の一行を書く。

1
*.cs diff=toutf8

これでcsファイルをUTF-8に変換してからdiffを取るようになった。

ググるとiconvを使うのが見つかるけど、UnityアセットのソースコードがUTF-8のものとUTF-16のものが混在しているので、入力をよしなに判別してくれるnkfを使うようにした。

社内LT大会で家電ChatOpsについて話した

IRKitを使って、ChatOpsやってみたよっていう話を先週の社内LT大会で話しました。 ChatOpsしたい、rubotyとhubot使いたいっていうのが目的なので、わざとまわりくどいことをやってます。

EmacsでUnity開発をする

これはドリコム Advent Calendar 2014の10日目の記事です。

9日目は@hiracyさんによるサーバが増えた時にインフラ担当者がやってきたことです。

自己紹介

  • @tkeo
  • 2007年新卒でドリコムに入社、8年目
  • メインの仕事はスマホゲームのサーバサイド(Rails)で、今年からクライアント(Unity)のほうも触り始めた
  • Rails歴 6年、Unity歴 8ヶ月
  • いまの作業比率は サーバ:クライアント = 2:1 ぐらい

今回の話

Unityを始めた当初はMonoDevelopを使っていたのですが、どうにも手になじまず腹が立ったので、普段サーバ側の開発で使っているemacsを使うことにしました。

以下はいろいろハマりながらも、インターネット上の先人の力を借りてまとめた自分の設定です。

環境

  • Mac OS X Mavericks
  • emacs 24.4.1
  • パッケージ管理はcask

csharp-mode

これがなくては始まらないC#用のメジャーモード。

1
2
; cask
(depends-on "csharp-mode")
1
2
3
4
5
6
7
8
9
; init.el
(require 'csharp-mode)
(add-hook 'csharp-mode-hook
          '(lambda ()
             (setq indent-tabs-mode nil)
             (setq c-basic-offset 4)
             (c-set-offset 'substatement-open 0)
             (flycheck-mode 1)
             (omnisharp-mode)))

自動補完

OmniSharpServer

C#のコードをパースしたりいろいろやってくれる(らしい)サーバです。 他のエディタでも使えるらしいです。

monoが必要なのでインストールして、

1
$ brew install mono

あとはREADME通りにビルド。

1
2
3
4
$ git clone https://github.com/nosami/OmniSharpServer.git
$ cd OmniSharpServer
$ git submodule update --init --recursive
$ xbuild

するとOmniSharp/bin/DebugOmniSharp.exeができているはず。 試しに起動してみる。

1
$ mono OmniSharp/bin/Debug/OmniSharp.exe -s /path/to/unity-project.sln

するとずらずらっとLoadingほげほげと出てきて、Solution has finished loadingで起動完了。無事起動が確認できたらCtrl+Cで止めておく(このあとemacsから起動するので)

omnisharp-emacs

OmniSharpServerをemacsから使うためのものです。

1
2
; cask
(depends-on "omnisharp")
1
2
3
; init.el
(require 'omnisharp)
(setq omnisharp-server-executable-path (expand-file-name "/path/to/OmniSharp/bin/Debug/OmniSharp.exe"))

csファイルを開いた時にslnファイルを選べと言われるので、選んであげるとバックグラウンドで起動してくれます。

M-x omnisharp-auto-completeで候補表示、M-x omnisharp-go-to-definitionで定義にジャンプできます。 適当なキーバインドを設定しておくと便利。

文法チェック

flycheck

omnisharp-emacsにcheckerが含まれていて、OmniSharpサーバと連携してチェックをしてくれます。

1
2
; cask
(depends-on "flycheck")
1
2
3
4
; init.el
(require 'flycheck)
(setq flycheck-check-syntax-automatically '(mode-enabled save idle-change))
(setq flycheck-idle-change-delay 2)

emacsclientアプリ化

Unity上でcsファイルをダブルクリックして開きたくなったときのための設定(あまりしないけど)

Unityの設定で外部エディタに指定できるのはMacのアプリ(*.app)だけなので、emacsclientを起動するアプリを作ります。 vim用にやっている人がいたのでその設定を参考にしました。

アプリを作るのにはAutomatorを使います。手順は以下のとおり。

  1. アプリケーションを選択。
  2. アクション>ユーティリティの中にある「AppleScriptを実行」を右にドラッグ&ドロップ。
  3. 下記コードを貼り付けて、appを適当な場所に保存。
1
2
3
on run {input, parameters}
    do shell script "/usr/local/bin/emacsclient -n " & quoted form of POSIX path of input
end run

automator

作ったappをUnity上で指定してあげると、外部エディタとしてemacsが使えるようになります。 あとはserverとして起動するのを忘れずに。

1
2
3
4
; init.el
(require 'server)
(unless (server-running-p)
  (server-start))

リファレンス検索

rubyの開発でも使っているDashを使えるようにします。

dash-at-point

1
(depends-on "dash-at-point")
1
2
3
4
; init.el
(global-set-key (kbd "C-c d") 'dash-at-point)
(global-set-key (kbd "C-c e") 'dash-at-point-with-docset)
(add-to-list 'dash-at-point-mode-alist '(csharp-mode . "cs"))

カーソル位置の単語で検索します。 上記設定ではcsharp-modeのときはキーワード “cs” が設定されたdocsetの中から検索します。

dash

Dash側で画像のようにキーワードを設定しておくと、.NET FrameworkとUnity 3Dのドキュメントを同時に検索できます。

自前docsetを作る

doxygenを使えばDash用のdocsetを作れます。 コードを含むアセットを購入した時に(たまに)やってます。

1
$ brew install doxygen
1
2
3
4
5
6
7
8
9
10
11
12
13
$ cat doxygen.config
GENERATE_DOCSET        = YES
SEARCHENGINE           = NO
DISABLE_INDEX          = YES
GENERATE_TREEVIEW      = NO
GENERATE_LATEX         = NO
GENERATE_HTMLHELP      = YES
RECURSIVE              = YES

PROJECT_NAME           = hogehoge
OUTPUT_DIRECTORY       = output
INPUT                  = path/to/Scripts
DOCSET_BUNDLE_ID       = hogehoge

こんな感じの設定ファイルを作って、まずはHTMLドキュメントを生成。

1
$ doxygen doxygen.config

htmlディレクトリに移動してmakeをたたくとdocsetが作られます。

1
2
3
$ cd output/html
$ make
$ open hogehoge.docset

その他

日本語を含むときはBOM付きで保存しないと化けます。C-x RET futf-8-with-signatureに変更。

まとめ

以上、MonoDevelopを使わずにemacsでUnity開発するための設定を紹介しました。

明日はみっきーさんです。

参考リンク

ブログ引っ越し

hatenablogから引っ越してきた。 octopressお手軽でいい感じ。

zshだとrake new_postのときにglob展開しようとして怒られるので、noglobをつける。

1
2
3
4
5
$ rake new_post['hoge']
zsh: no matches found: new_post[hoge]
$ noglob rake new_post['hoge']
mkdir -p source/_posts
Creating new post: source/_posts/2014-12-09-hoge.markdown

面倒なのでaliasを書いてしまった。

1
alias rake='noglob rake'

日記

railsアプリ開発中にmigrationでエラーが起こって、一部だけ変更が適用された戻すのがめんどくさい中途半端な状態になることがよくあって今日もうぎゃーってなったので、トランザクションで囲んでくれるような仕組みないのかなと思って調べてみると

http://guides.rubyonrails.org/migrations.html

On databases that support transactions with statements that change the schema (such as PostgreSQL or SQLite3), migrations are wrapped in a transaction. If the database does not support this (for example MySQL) then when a migration fails the parts of it that succeeded will not be rolled back. You will have to rollback the changes that were made by hand.

なんだってー

postgresはデフォルトで対応しているが、mysqlはサポートされてなくて非対応。知らなかった…。

一応mysqlのドキュメントにもあたってみる。

http://dev.mysql.com/doc/refman/5.6/en/cannot-roll-back.html

Some statements cannot be rolled back. In general, these include data definition language (DDL) statements, such as those that create or drop databases, those that create, drop, or alter tables or stored routines.

DDLはロールバックできない、と。

開発環境だけDBサーバ変えるとかしたくないし、どうしたらいいかなあ。

という日記。

追記

change_tablebulk: trueオプションを付けてあげればいいらしい。 ひとつのALTERでまとめてカラム追加・削除されるので中途半端な状態は作られない。

Rails4 で MiniTest + Spork + Guard

正式版が出る頃には変わっている可能性が高いが、現時点でのメモを残しておく。

minitest-rails

https://github.com/blowmage/minitest-rails

Gemfile に追加。

gem "minitest-rails"

必要なファイルを生成。

$ rails generate mini_test:install

test/minitest_helper.rb が生成される。

ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)

require "minitest/autorun"
require "minitest/rails"

# Add `gem "minitest/rails/capybara"` to the test group of your Gemfile
# and uncomment the following if you want Capybara feature tests
# require "minitest/rails/capybara"

# Uncomment if you want awesome colorful output
# require "minitest/pride"

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

各testファイルでこれを読み込むために下の一行が必要。

require 'minitest_helper'

動作確認。

$ ruby -Itest test/foo/bar_test.rb

spork-minitest

https://github.com/semaperepelitsa/spork-minitest

Gemfile に追加。

gem "spork", "~> 1.0rc"
gem "spork-minitest", "~> 1.0.0.beta1"

下記コマンドを実行し、minitest_helper に spork 向けの設定を追加する。

$ spork minitest --bootstrap

test/minitest_helper.rb に追記されるので適宜編集する。

$LOAD_PATH << "test"
require 'rubygems'
require 'spork'
#uncomment the following line to use spork with the debugger
#require 'spork/ext/ruby-debug'

Spork.prefork do
  # Loading more in this block will cause your tests to run faster. However,
  # if you change any configuration or code from libraries loaded here, you'll
  # need to restart spork for it take effect.

  ENV["RAILS_ENV"] = "test"
  require File.expand_path('../../config/environment', __FILE__)

  require "minitest/autorun"
  require "minitest/rails"
  require 'simplecov'
  require 'simplecov-rcov'

  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
  SimpleCov.start 'rails'

  # Add `gem "minitest/rails/capybara"` to the test group of your Gemfile
  # and uncomment the following if you want Capybara feature tests
  # require "minitest/rails/capybara"

  # Uncomment if you want awesome colorful output
  # require "minitest/pride"

  class ActiveSupport::TestCase
    # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
    fixtures :all

    # Add more helper methods to be used by all tests here...
  end
end

Spork.each_run do
  # This code will be run each time you run your specs.

end

# --- Instructions ---
# Sort the contents of this file into a Spork.prefork and a Spork.each_run
# block.
#
# The Spork.prefork block is run only once when the spork server is started.
# You typically want to place most of your (slow) initializer code in here, in
# particular, require'ing any 3rd-party gems that you don't normally modify
# during development.
#
# The Spork.each_run block is run each time you run your specs.  In case you
# need to load files that tend to change during development, require them here.
# With Rails, your application modules are loaded automatically, so sometimes
# this block can remain empty.
#
# Note: You can modify files loaded *from* the Spork.each_run block without
# restarting the spork server.  However, this file itself will not be reloaded,
# so if you change any of the code inside the each_run block, you still need to
# restart the server.  In general, if you have non-trivial code in this file,
# it's advisable to move it into a separate file so you can easily edit it
# without restarting spork.  (For example, with RSpec, you could move
# non-trivial code into a file spec/support/my_helper.rb, making sure that the
# spec/support/* files are require'd from inside the each_run block.)
#
# Any code that is left outside the two blocks will be run during preforking
# *and* during each_run -- that's probably not what you want.
#
# These instructions should self-destruct in 10 seconds.  If they don't, feel
# free to delete them.

sporkの動作確認をする。

$ spork

sporkを立ち上げた状態のまま、別窓を開いて testdrb でテスト実行してみる。

$ testdrb test/**/*.rb

guard-minitest

https://github.com/guard/guard-minitest

本家のものを使いたいところではあるが、sporkと組み合わせた時に動かないので一旦他の人が作ったブランチを使わせてもらう。 (ref. https://github.com/guard/guard-minitest/pull/41)

sporkを使わないのであれば本家のものでもおそらく問題ない。

Gemfile に追加。

gem "guard-minitest", github: "itrcdevs/guard-minitest", branch: "fix_for_spork-minitest"

設定ファイルを生成する。すでにファイルが存在する場合は内容が追記される。

$ guard init minitest

生成された Guardfile を編集する。

# More info at https://github.com/guard/guard#readme

guard 'minitest' do
  # with Minitest
  watch(%r|^test/(.*)_test\.rb|)
  watch(%r|^lib/(.*)([^/]+)\.rb|)     { |m| "test/#{m[1]}test_#{m[2]}.rb" }
  watch(%r|^test/test_helper\.rb|)    { "test" }

  # Rails
  watch(%r|^app/controllers/(.*)\.rb|) { |m| "test/controllers/#{m[1]}_test.rb" }
  watch(%r|^app/helpers/(.*)\.rb|)     { |m| "test/helpers/#{m[1]}_test.rb" }
  watch(%r|^app/models/(.*)\.rb|)      { |m| "test/models/#{m[1]}_test.rb" }
end

guard の動作確認。

$ guard

適当にファイルをtouchしてみるとテストが走るはず。 何も起こらない場合はちゃんと監視対象に入っているか記述を見なおしてみる。

guard-spork

Gemfile に追加。

gem "guard-spork"

Guardfile に設定を追加する。

$ guard init spork

Guardfile に追加された spork の箇所の編集と、minitest で drb を使うように変更する。

guard 'spork', minitest: true, minitest_env: { 'RAILS_ENV' => 'test' }, bundler: true do
  watch('config/application.rb')
  watch('config/environment.rb')
  watch('config/environments/test.rb')
  watch(%r{^config/initializers/.+\.rb$})
  watch('Gemfile')
  watch('Gemfile.lock')
  watch('test/minitest_helper.rb') { 'test' }
end

guard 'minitest', drb: true do
  # (省略)
end

実行。

$ guard

これだけで spork が自動的に起動する。 先と同じようにファイルを編集したときに動けばOK

その他

  • factory_firl_rails を入れると mintiest 用のgeneratorがちゃんと動かない (追記:githubのmasterは修正されてた)
  • まだプロジェクトの規模が小さいのでsporkの恩恵を感じられない…
  • spork-rails が必要かと思ってrails4ブランチも含めて試してみたが要らなかった(入れると逆にダメになる)