There's an echo in my head

日々のメモ。

OS X 10.11 El Capitanでnokogiriをインストールする

$ brew install libxml2 libxslt libiconv
$ gem install nokogiri -- --use-system-libraries

bundlerでインストールするときのためにも設定しておく。

$ bundle config build.nokogiri --use-system-libraries

なお前提として、公式サイトのインストール方法の"Other OS X tips"にあるように

  • rubyが最新のclangでビルドされていてgccでの依存に無い状態で
  • gemのネイティブ拡張もおなじようにclangでコンパイルされるようになっている

ことが必要になる模様。

なのでアップグレードしてrbenvの環境をそのまま引き継いだ場合などでコンパイラgccだったりする場合は、export CC=clangなどしてrubyをビルドしなおしてからnokogiriのインストールに入れば良いのだと思う。

OS X 10.11 El Capitanでeventmachineをインストールする

OS XがOpenSSLの共有ライブラリを含めなくなった(のかな?)ために、homebrew等でインストールしてその場所をオプションで指定する必要があった。

github.com

$ gem install eventmachine -- --with-cppflags=-I$(brew --prefix openssl)/include

bundlerでインストールするときのためにもbundle-config(1)で事前に設定しておく。

$ bundle config build.eventmachine --with-cppflags=-I$(brew --prefix openssl)/include

同様の記事がStackOverflowにもあった。gem eventmachine fatal error: 'openssl/ssl.h' file not found

pipeの途中でエラーが起きたタイミングでエラーを返す

パイプを繋げたときの返り値は最後のコマンドの返り値になる。

例えば

stat = system "a | b |c"

としたとき、途中でaやbがエラーになっても返り値statはfalseにならずcの返り値であるtrueになる。 cがエラーに成った時にはfalseになる。*1

これだとパイプの途中でエラーが起きた場合に捕捉できない。

そういうときはbash-o pipefailオプションを使う。*2 これを指定するとパイプの途中でエラーが起こった時にはそのときの返り値が、なにも起きなければ最後のcの返り値が全体の返り値が返ってくるようになる。 さらに-eを付けておくことでエラーが起きたタイミングで終了するようになる。

stat = system %{bash -e -o pipefail -c "a | b | c"}

参考

*1:具体的な返り値は個々のコマンドの実装依存なので、エラーになってもtrueを返すやつがいるかもしれない

*2:bash 3.0から。zshも5.0以降で実装されてるらしい

El CapitanでSIMBLを有効にする

How to Install SafariStand on El Capitanから勝手に抜粋。

1 Macを再起動し、「ジャーン!」となったらCommand+Rをあるていど押し続けてリカバリモードで起動する

  • 一度押しただけでは切り替わらなかった
  • タイミングの判定がわりと細かい

2 メニューからTerminal.appを起動する

3 次のようにコマンドを叩いてSIPを無効にする

bash3.2# csrutil disable

4 再起動する(rebootでも、メニューからのRestartでもOK)

5 SIMBLのサイトからSIMBL-0.9.9.zipを落としてきて解凍する

6 Terminal.app等で次のようにコマンドを叩いてSIMBLを手動でインストールする

$ cd /path/to/SIMBL-0.9.9 # zipを解凍してできたディレクトリに移動する
$ sudo installer -verbose -pkg SIMBL-0.9.9.pkg -target /
$ sudo rm -rf /System/Library/ScriptingAdditions/SIMBL.osax
$ sudo mv /Library/ScriptingAdditions/SIMBL.osax /System/Library/ScriptingAdditions/
$ sudo cp -p /System/Library/ScriptingAdditions/SIMBL.osax/Contents/Resources/SIMBL\ Agent.app/Contents/Resources/net.culater.SIMBL.Agent.plist /System/Library/LaunchAgents/
$ sudo sed -e "s/Library/System\/Library/" -i "" /System/Library/LaunchAgents/net.culater.SIMBL.Agent.plist

7 リカバリモードで再起動する(先ほどと同じように「ジャーン!」でCommand+R)

8 Terminal.appから次のように叩いてSIPを有効にする

bash3.2# csrutil enable

9 これでSIMBLが有効になったので、あとはこれまでどおり/Library/Application\ Support/SIMBL/Pluginsプラグインをインストールする

手動でRailsのビューをレンダリングする

バッチで生成しておきたいとかそういうときに。

class FooController < AbstractController::Base
  include AbstractController::Rendering
  include AbstractController::Translation
  include AbstractController::AssetPaths
  include ActionView::Layouts

  self.view_paths = "app/views"

  def index
    render template: "foo/index.html.slim"
  end
end

puts FooController.new.index
# => レンダリングされた文字列

もうちょっとActionView側を触るのかと思いきや、パッと調べた感じだとAbstractControllerを用意するやり方が出てきて、なんか無駄な感じもするけど手軽だしまあいいか。

もしかしたらヘルパーメソッドを使うときにはこれ以外にもincludeする必要があるかもしれない。 そのときはaction_controller/base.rbを見てみるといいかも。

参考

Railsのジェネレータを自作する

よく忘れるので。細かい話は他の記事にお任せして、テンプレートからファイルを作れるところまで。

0. こんなのを作りたいとかんがえる

  • 抽象クラスFigureのサブクラスをapp/modelsに作るようなジェネレータがほしい。
  • クラス名は引数で指定したい

こんな感じで使うイメージ:

$ rails g figure triangle --color blue

1. ジェネレータをジェネレートする

 $ rails g generator figure

これでlib/generators/figure以下に

  • USAGE : 使い方を記述するテキストファイ
  • figure_generator.rb : 生成処理を実装するファイル
  • templates/ : テンプレートファイルを置くディレクトリ

が作られる。

2. 作り方を記述する

USAGEファイルに0.のようなことを記述する。

3. 生成処理を記述する

lib/generators/figure/figure_generator.rb に次のように記述する。

class FigureGenerator < Rails::Generators::NamedBase                                               
  source_root File.expand_path('../templates', __FILE__)

  # 引数として受け取る順番に記述する
  # ここで宣言した引数名はそのままその値を返すメソッドとしても使える
  # 追記: NamedBaseの場合はデフォルトでnameが宣言されているのでここではなにもしない
  # argument :name, type: :string, desc: "クラス名。underscoreな形でもOK"

  # オプションを記述する
  # ここで宣言したオプションは`options[:color]`のように参照できる
  class_option :color, type: :string, aliases: "-c", desc: ""

  # 以下に宣言されたpublicなメソッドが上から順に実行される

  def create_model_file
    # テンプレートをもとにapp/modelsにファイルを作る
    template "model.rb.erb", "app/models/#{name.underscore}.rb"
  end

  private

  # このクラス上のメソッドはテンプレートからも呼び出せるので
  # 積極的にprivateメソッドで宣言していきたい
  def class_name
    name.classify
  end
end

4. テンプレートファイルを記述する

figure_generator.rb でtemplateメソッドの引数に渡した model.rb.erb にテンプレートを記述する。ファイル名のとおりERBを使う。 *1

class <%= class_name %> < Figure
  def apexes_count
     # 頂点の数を返す
  end
  def color
    "<%= options[:color] %>"
end

5. 使ってみる

$ rails g figure triangle --color yellow

9/17 追記

class_optionによるオプションの宣言方法を追記した。 ちなみにargumentclass_optionThor::Base::ClassMethodsで定義されているもの。

10/3 追記

NamedBaseの場合はすでにnameargumentで宣言されており別途宣言する必要がないので、ここではコメントアウトした。

*1:もしかしたらファイル名を適切に設定すればERB以外も使えるかもしれない

Capistranoで今処理しようとしているhostの属するroleを判定する

host.rolesを叩くと、role(のSymbol)のSetが返ってくる。

task :foo do
  on release_roles :all do |host|
    host.roles #=> #<Set: {:web, :app, :db}> 
  end
end

git_strategyの中でもcontextを通して同じことができる。

set :git_strategy, MyGitStrategy

module MyGitStrategy
  def release
    context.host.roles #=> #<Set: {:web, :app, :db}> 
  end
end
このブログに出てくるコードスニペッツは、引用あるいは断りがない限りMITライセンスです。