OmniAICreator/Qiita-1.07M huggingface dataset:
cron上でのコマンド実行を再現する

> シェル上だと動くのにcron上だと動かない。

よく聞くお話ですよね。
大体はcron上と普段のシェル上で環境変数が違うために起こる問題です。

そういう時に使えるtipsを共有します。

個人のマシン上で適当に動かすようなcronだと

```
* * * * * bash -lc /some/wonderful/script.rb
```
みたいにしてログインシェルを間に噛まして環境変数を上書きして実行することでごまかしたりもできます。
これまた別の依存する箇所を増やすので
個人のマシンかrcファイルがちゃんと管理されているような状況以外ではオススメできません。

なのでcron上で実行される状況とほぼ同じ状況でスクリプトを実行してみましょう。
cron上では環境変数はほぼ空なので環境変数を空にしてみましょう。

```bash
env - /some/wonderful/script.rb
```

のようなコマンドを実行することで環境変数が空の状態でスクリプトを実行することができます。

ですけど、cron上では実際には環境変数は空ではありません。
crontab上で環境変数を設定している場合も多くあります。
なのでcron上でコマンドが実際に実行される時の環境変数を取得しましょう。

```
* * * * * env > ~/cron_env
```

上記の用なcrontabを設定することでcronでの実行時の環境変数が取得できます。
これを利用して

```bash
env - `cat ~/cron_env` /some/wonderful/script.rb
```

といった形で実行することでcron経由で実行した時の環境変数を再現した上でスクリプトを起動できます。

何度も試すときは

```bash
env - `cat ~/cron_env` sh
```

といったコマンドを実行してcronの環境変数だけを設定したシェルを立ち上げると

```
/some/wonderful/script.rb
```

だけで試すことも出来ます。
ソースコード上でtextview のpaddingをdpで設定する

textview のpaddingは通常レイアウトのxmlで指定しますが、adapterなどを利用している場合はソースコード上で設定したい時もあります。  
その場合はhogeTv.setPadding(left,top, right, bottom)を利用できるわけですが、px指定となってしまうため、以下のようにしてpdに変換します。  

```java
int paddingDp = 10;  // dpを指定
float scale = getResources().getDisplayMetrics().density; //画面のdensityを指定。
int paddingPx = (int) (paddingDp * scale + 0.5f);
//(int) (paddingDp * scale)とした場合は端数は切り捨て
```
Dockerでdebianプラクティス

#諸元
とはいっても以下のサイトの情報をベースにまとめただけ。
http://d.hatena.ne.jp/mainyaa/20140203/p1
https://index.docker.io/u/flox/debian-openerp/

#実績
一応、動作の確認はできました。
これの応用したものを後で出す予定。
ただ、ビルドで変なログがあるので、よくないことやってるかも(debian的に)。

##やっていること
* ベースイメージ
* メンテナー
* ミラー(CDNからどこでもミラー)
* noninteractive
* ロケール
* --no-install-recommends の例示
* git
* キャッシュ削除

###ベースイメージ
[(セミ)オフィシャル](https://index.docker.io/_/debian/)から。

###メンテナー
ちゃんと入れましょう。

###ロケール
この設定でいいかは一寸微妙です。(そのままもってきてあるだけ)

###noninteractive
ENVとRUN exportの差はちょっと微妙ですが、現在はここに。

###ミラー(CDNからどこでもミラー)
Baseに合せて設定が必要。

###--no-install-recommends の例示とキャッシュ削除
ここらへんはサイズ対策として必要。

###git
これは後述。よく使うとおもうので、サンプルを兼ねて。

```text:Dockerfile
FROM debian:wheezy
MAINTAINER My Name <MyAddress@example.com>

# mirror
RUN echo "deb http://cdn.debian.net/debian/ wheezy main contrib non-free" > /etc/apt/sources.list.d/mirror.jp.list
RUN echo "deb http://cdn.debian.net/debian/ wheezy-updates main contrib" >> /etc/apt/sources.list.d/mirror.jp.list
RUN /bin/rm /etc/apt/sources.list

RUN export DEBIAN_FRONTEND=noninteractive LANG
RUN apt-get update

# set locale
RUN apt-get install -y --no-install-recommends apt-utils locales

RUN echo en_US.UTF-8 UTF-8 > /etc/locale.gen
RUN locale-gen
RUN update-locale LANG=en_US.UTF-8

# sample
RUN apt-get install -y --no-install-recommends xxx

# apt package
# need for git
RUN apt-get install -y --no-install-recommends git
RUN apt-get install -y --no-install-recommends ca-certificates openssl

# clean up
RUN apt-get upgrade -y && apt-get clean && rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/* 

# git clone
RUN git clone https://github.com/xxx/yyy.git

ENTRYPOINT "/bin/bash"
```

#ちょっとハマった所
##イメージ
最新は`debian`でよい。
というか、`debian:wheezy`だと取得サイズがすごい小さいかわりにシェルをENDPOINTにできなかった。
たぶんサービスを稼動させてリリースするに良いようにしていると思われる。
細かい情報はリンク先にあると思う。

ミラーとの絡みがあるので、固定したいんだけどね。

##ENDPOINT
上記イメージの影響で(エラーメッセージあった)、`ENDPOINT [ "/bin/bash" ]` で渡してうまく動かなかった。
調べた時は昔にパラメタ渡しタイプは1つでNGになるIssueがあったが、関係ないはず。

まあ、1つなのでサンプルに落ち着いた。

##git
単純にgitだけだと、httpsアクセスに失敗してしまう。証明書とopensslが必要なんだが、必須パッケージじゃないんだなーと。
nscala-time と specs2 で `1.day` などの変換に失敗する


原因は両方共に implicit conversion があるからです。

````
type mismatch;
[error]  found   : Int(1)
[error]  required: ?{def day: ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error]  both method richInt in trait IntImplicits of type (n: Int)com.github.nscala_time.time.RichInt
[error]  and method intToRichLong in trait TimeConversions of type (v: Int)TimeRangeSpec.this.longAsTime
[error]  are possible conversion functions from Int(1) to ?{def day: ?}
[error]         1.day
[error]         ^
[error] one error found
[error] (redshift/test:compile) Compilation failed
[error] Total time: 3 s, completed May 22, 2014 8:33:52 PM
````

Specs2 は `NoTimeConversions` という trait を用意しているので、 mixin することで specs2 側の implicit を無効にできる。

````
import org.specs2.mutable.Specification
class FooSpec extends Specification with NoTimeConversions
````
npmでnpm管理外のモジュールを指定するには

# 背景
WindowsでAtom Shellをいじっていて、apmを使いたくなり、その時使える環境でapmを入れようとしたら、
さっそくコケた。

調べたところ、ネットワークのアクセスが厳しい環境だったので、sshでgit cloneしていることが原因だった。

# package.jsonのdependenciesは色々と指定可能

npmの公式ページに[解説](https://www.npmjs.org/doc/json.html)があった

バージョン以外に、以下のようなURLも指定でることのと。

```
git://github.com/user/project.git#commit-ish
git+ssh://user@hostname:project.git#commit-ish
git+ssh://user@hostname/project.git#commit-ish
git+http://user@hostname/project/blah.git#commit-ish
git+https://user@hostname/project/blah.git#commit-ish
```

今回、自分の作業的には、ちょとこの説明とは違う形式な気もするが、
試行錯誤した結果、以下の記述で、sshではなく、httpsでcloneが可能となった。

```
"plist": "git+https://github.com/nathansobo/node-plist.git",
```

## 注意

http://のような通常のURLだと、そのURLをtarballとしてDLして展開して
扱うらしい。

# 関連するかもしれないリンク

- [httpsでのgit cloneをやめてssh over https portでcloneした話 - It's raining cats and dogs.](http://tadasy.hateblo.jp/entry/2013/09/27/204432)

# 関連記事

- [Node.jsのサンプルコードをコマンド化する](https://abrakatabura.hatenablog.com/entry/2015/12/15/213131)
- [Windowsでnpmをアップデートするのに苦戦中](https://abrakatabura.hatenablog.com/entry/2017/12/15/233908)
Macにansibleを入れる

ansibleをhomebrewを使ってインストールします。

homebrewのインストールについては、
[コチラ](http://qiita.com/kanuma1984/items/a0e3067b9d1331c9ba70, "homebrew")を参照してください。


# 環境

+ OS X 10.8.5
+ ruby 1.8.7
+ Homebrew 0.9.5

# インストール

```bash
$ brew install ansible
```

以上！！
rbenvのメモ


rbenvのコマンド一覧見てもイマイチどれがどのコマンドか分かんないからメモ。

## インストール可能なバージョン一覧を確認

````
rbenv install -l
````

## ほしいバージョンのインストール
````
rbenv install 2.1.1
````

## インストール済のバージョン確認
````
rbenv versions
````

## 使いたいバージョンを切り替え
````
rbenv global 2.1.1
````

````global```` でシステム全体で使うrubyのバージョンを切り替える。特定のディレクトリ配下のバージョンを切り替える場合は ````local```` を使う

## 今のバージョンの確認
````
ruby --version
````

````-v```` でも良い気がする。もし切り替わってなかったら以下を。

````
rbenv rehash
````
Macにhomebrewを入れる

# 環境
+ OS X 10.8.5
+ ruby 1.8.7

# インストール
Macにはrubyがプリインストールされているので、
早速homebrewのインストールをします。

```bash
$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)"
```

ちゃんと入っているか確認します。

```bash
$ which brew
/usr/local/bin/brew
```

無事入っていました。以上でおしまいです。
rubyでFile.openを使わずにファイルの読み書きをする方法


`File.read`とか`File.write`みたいな便利なメソッドが用意されているので、遠慮なくそれを使う。

```ruby
pry(main)> File.write('hoge.txt', 'ok')
=> 2
pry(main)> File.read('hoge.txt')
=> "ok"
```

### 想定してる状況

ファイル読み込んでいろいろ書き換えて別のファイルに保存したいって時に、

```ruby
File.open('hoge.csv') do |out_f|
  File.open('hoge.txt') do |in_f|
    out_f.write in_f.read.gsub("¥s", ',')
  end
end
```

と書いてもいいけど、

```ruby
File.write 'hoge.csv', File.read('hoge.txt').gsub("¥s", ',')
```

みたいにさっくりも書ける。便利。

### 余談
File.openでFileオブジェクト取得したら、readメソッドで中身のテキストを取得する事も出来る。

```ruby
pry(main)> File.open('hoge.txt').read
=> "ok"
```

`open-uri`使った場合も同じようにreadでテキスト取得出来て、パッとリソース取得したい時には便利。

```ruby
json = open("http://b.hatena.ne.jp/entry/json/#{url}").read
```
CentOSで後からXを追加しようとして詰まった話

CentOSをminimalインストールした後、X(GUI)を追加しようとして
久々にドハマりしたので、恥ずかしながら残しておきます。

#環境
CentOS6.5 x86_64 minmalインストール

#やったこと
1.OSインストール後、下記を実行してX追加。

```
yum groupinstall "X Window System" "GNOME Desktop Environment" 
```

2.追加後、「init 5」を実行してGUI起動！！これで上手くと思っていたが…

```
INIT: Id"x" respawning too fast: disabled for 5 minutes
```

なーんてエラーがでて起動しない。。。
ログ見たり、Xの設定ファイルがなかったりしたので、下記を実行。

```
Xorg -config xorg.conf.new -retro
```

GUIっぽいのが立ち上がったけど、画面が白黒模様で？？？な状態。

3.仕方がないので、グーグル先生に頭を下げまくって調べたところ、
下記のサイトに非常に参考になることが書いてあった。
(というか、この記事そのままやれば行けるという。。。ブログ主の方素敵です。)

http://morrey22.hatenablog.com/entry/2013/04/14/212837


昔、何度か同じことやったけど、

```
yum groupinstall "X Window System" "GNOME Desktop Environment" 
```

で上手く行ってた気がするんだけどなあ。。。
ログにはマウスの動きがキャプチャできない云々あったから、
そのへんのパッケージが足りなかったんだろうけど。
時間ないから、深くは原因追わない。
NSLogをちょっと便利にするTips


iOS開発においてNSLogを利用する事が度々あると思いますが、
それらを少し便利するようなTipsのご紹介を。
※若干俺得感がありますが。

以前もブログに簡単に書いたのですが、記事が分かれてしまっていたので
まとめる意味も込めて。
[iOS向け Xcode開発Tips入門編 -とりあえず最初にやってること-](http://blog.oneworld-inc.com/entry/2013/02/25/151606 "Xcode入門編")

[【iOS】 Xcode開発Tips入門編その3 -NSLogあれこれ3つほど-](http://blog.oneworld-inc.com/entry/2013/03/05/172200 "Xcode入門編")


こちらにも紹介しましたが、マクロを使う事でよりログ出力がよりシンプルに
実装できます。

### 0. デバッグ時のみに出力し、リリース時には出力をしない。

NSLogで出力しているものをそのままリリースすると
だだ漏れするという問題が発生するので、

```objc

#ifndef DEBUG
#define NSLog(...) 
#endif 

```
などとする事で、デバッグ時以外は出力されなくなります。


###1.出力時の関数名及び行数を出力させる
NSLogでは、

```objc

//クラス名及び関数名
NSLog(@"%s", __func__);

//クラス名及び関数名
NSLog(@"%s",__FUNCTION__);

//クラス名及び関数名
NSLog(@"%s",__PRETTY_FUNCTION__);

//行番号
NSLog(@"%d",__LINE__);

```

にようにする事で、関数名や行数を出力してくれます。

ただ毎回書くのは面倒なので、

```objc

#ifdef DEBUG
#define LOG(fmt,...) NSLog((@"%s %d "fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define NSLog(...) 
#endif 


```

と定義し、


```objc
LOG(@"hoge");
```
とすると、自動的に、関数名及び行数が表示されるようになります。


###2.CGPoint/CGSize/CGRect などを一括で出力する。


```objc

NSLog(@"%@",NSStringFromCGRect(self.view.frame));
NSLog(@"%@",NSStringFromCGSize(self.view.frame.size));
NSLog(@"%@",NSStringFromCGPoint(self.view.frame.origin));

```

とこのように、NSStringFrom...系のメソッドを使うと、
出力する事が可能です。

ただこれらのメソッドは長いので、ちょっと使うのが億劫だったりしまして。。

なので、

```objc

#define LOGRect(RECT) NSLog(@"%@",NSStringFromCGRect(RECT));

```

と定義するなどして

```objc
LOGRect(self.view.frame);
```
などという利用もできます。
ちなみに、

NSStringFromClassなどのメソッドも用意されていて

```objc

NSLog(@"%@", NSStringFromClass([self class]));

```

などとするとクラス名を出力する事も可能です


###3.コールスタック を出力する。

このあたりは、デバッグ時の一つの情報として

```objc

NSLog(@"%@" , [NSThread callStackSymbols]);

```

とするとコールスタックが出力する事が可能です。


###おまけ xxx-Prefix.pchファイルに記述する。

ログに関する定義などはプロジェクト全体で利用したいため、
通常特定のヘッダファイルに書いたとしても、別のクラスなどでは
そのヘッダファイルをimportしない限りは利用する事ができません。

このようにプロジェクト全体にかかわるような記述は、
pchファイルに書くと各ファイルでも利用する事が可能になります。





以上です。
iOS UIDynamicBehavior の挙動をおさらい（github にサンプルで XCode Project をアップ）


ようやく手をつける事ができた。
時間を作って UIDynamicBehavior を試してみた。
細かい動きの調整などはまだ体得していないが、何となく使い方が分かった。
有機的な動きを利用してメニューなどつくると、FlatUIは使っていて心地がよいのかも。
ワンポイントで使えるようにライブラリー群を整えておく事が大切かも。
使いすぎるとうざそう。。。

サンプルプロジェクト -> [UIDynamicBehaviorTest XCode Project](https://github.com/JFK/UIDynamicBehaviorTest)


# UIAttachmentBehavior
![UIAttachmentBehaviorTest.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/657df68a-b662-a43b-82b8-c32fcd181d1c.gif "UIAttachmentBehaviorTest.gif")

* * *

# UICollisionBehavior
![UICollisionBehavior.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/84436b14-2d4c-ce38-6e0f-720065c1ba0a.gif "UICollisionBehavior.gif")

* * *

# UIGravityBehavior
![UIGravityBehavior.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/70d16e3b-d3fe-30fb-b1b9-fb5743d850d1.gif "UIGravityBehavior.gif")

* * *

# UIPushBehavior
![UIPushBehavior.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/0fe25f3e-0c99-c141-c2c2-a1a30eadc4f3.gif "UIPushBehavior.gif")

* * *

# UISnapBehavior
![UISnapBehavior.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/66223771-928d-51f0-a46a-eb3e617343c3.gif "UISnapBehavior.gif")

* * *

# UIDynamicItemBehavior
![UIDynamicItemBehavior.gif](https://qiita-image-store.s3.amazonaws.com/0/18766/59bd0826-8517-181b-e423-81125ca63db4.gif "UIDynamicItemBehavior.gif")
Review Board に差分を投稿する時の tips (特にgit)

[Review Board](http://www.reviewboard.org/) 上に差分を投稿するのは [RBTools](http://www.reviewboard.org/docs/rbtools/dev/) というコマンド群を別途入れてやることになります。

## git のグローバル設定に Review Board を設定
`git config --global reviewboard.url http://localhost/reviewboard/`

## rbt post

リポジトリ上で
`rbt post -o`
とすれば、`HEAD`と作業ブランチのリモート（なければ`master`）との差分を投稿します。投稿するとレビューIDが取られて、チケット的に管理されます。オプション`-o`で投稿したリクエストをそのままブラウザで開く。
前まで`post-review`だったんですが、最近だと`rbt post`になったっぽい？

## -rで差分を更新する

先に投稿した差分を修正した場合、その差分を更新できます。
Review Board では投稿した差分の世代管理がされているため、先の差分と後の差分の比較も出すことができます。

`rbt post -o -r xxx`

オプション`-r`の後に既に投稿したレビューのIDを指定することで、その差分を更新します。

## --parentで比較元を指定

gitは作業ブランチのリモートと差分を取ります。ここで差分の更新をした場合、前のコミットを`push`していた場合、めんどくさいことになります。

111AAA -> 222BBB -> 333CCC

といった順でコミットがあり、`111AAA`と`222BBB`の差分でレビューを投稿してたとして、後から`333CCCが`出たのでコミットしたいとします。
この時、`222BBB`を`push`していると、差分を更新しようとすると`222BBB`と`333CCC`の差分が投稿されてしまいます。そうすると、レビュー上の世代管理が壊れてしまいます。なので、`111AAA`を差分元とするよう指定します。

`rbt post -o -r xxx --parent=111CCC`

これで、`111AAA`と`333CCC`の差分が取られ更新されます。後から見た人もこれで安心だっ。

gitの参照ならコミットの直接指定でなくてもよいので、

```
rbt post -o -r xxx --parent=HEAD^^
rbt post -o -r xxx --parent=origin/master
```

みたいな感じで使うことが多いです。あとマージとか入った時にもよく使います。

## --revision-range で区間を指定する

今となってはあんまり使わないですが、コミットを2つ指定してその差分を取って投稿する事もできます。

`rbt post -o --revision-range=111AAA:444DDD`

といった形。
自由度の高さを活かして色々できて良いです。
Market Place プラグインのインストール方法


Help から Eclipse Market Place のメニューが見つからない場合
プラグインをインストールする


## やり方

* Help
* Install new software
* Eclipseのバージョン名を選ぶ (JunoとかKeplerとか)
* General purpose software
* Marketplace client を選んでインストール



## 検索用語

* eclipse, ADT, エクリプス
* Market Place マーケットプレイス
Ext JS の overrides の読込

Ext JS では、パッチを当てるなどのために override という機能が備わっています。
対象となるクラスがロードされた後に、override のクラス定義をロードすると、クラス定義自体を書き換えられるというものです。

http://extjs.sunvisor.net/632

そして、Sencha Cmd で生成された、プロジェクトには overrides というディレクトリが最初から存在しています。

Sencha Cmd と MVC フレームワークにおいて、override を読み込む正しいやり方は、だれもしらないことの一つです。
今回はその使い方です。

override したいことができたら、Ext.define でオーバーライドを定義して、この overrides ディレクトリに配置します。

    Ext.define("App.overrides.Panel", {
        override: "Ext.panel.Panel",
        foo: 42
    });

ファイル名はなんでもいいし、クラス名の部分もなんでもいいです。
アプリケーションの中で、オーバーライドの対象となるクラスを使います。
この場合ですと、パネルを使います。

    requires: ['Ext.panel.Panel']

そして、app.json に次の1行を足します。

    "overrides": "${app.dir}\/overrides",

これをセットしておくと、このフォルダにあるオーバーライドを探しに行ってくれるようになります。
その後、sencha cmd で

    sencha app refresh

を実行すると、bootstrap.js が更新されて、オーバーライドが読み込まれるようになります。

## Ext JS 6 

Ext JS 6 では、overrides ディレクトリの中に、クラス名階層通りのディレクトリを掘って、ファイルを配置します。

Ext.panel.Panel をオーバーライドする場合は、次のようにクラス名部分を指定して、overrides/panel に Panel.js として配置します。

    Ext.define("Ext.overrides.panel.Panel", {
        override: "Ext.panel.Panel",
        foo: 42
    });

### ユニバーサルアプリの場合

ユニバーサルアプリのコンポーネント系のオーバーライドは、ツールキット毎に行います。
modern / classic ディレクトリ直下に overrides ディレクトリを配置して、そこに上記のように配置します。
BOXENやって幸せになったこと


# ~introduction~ (序論)
BOXENはMacの環境自動作成ツールである。
今回は導入した実績をもとに
以下の３点を共有させていただきたい。

1. BOXENやった目的
1. BOXENやって幸せ♡
1. こんなはずじゃなかった

# ~Subject~ (本題)

## BOXEN入れた目的

- 開発環境を共有すること
- 開発者間で同じ環境を得ること
- 新規参画者、新規プロジェクトの環境の自動ウォームアップ

よく皆さんが書かれているような目的だと思う。個人的には、会社と家で合わせて３つMacがあるので、どのMacでも同じ環境であるのは嬉しい。（Windowsの頃からそういうことは思ってて、Windowsの場合の同じ手段を知らない。）

## Yes!BOXENやって幸せ♡

### ほぼ同じ３つのMac

個人で利用するMacが３つあって、それがほぼ同じ環境になること。
「あれ入れて、これ入れて」って考える必要が無くなった。当然、完璧ではないのだが。

### 暗黙知から形式知へ

簡単にいうと設定が保存できたことが嬉しい。難しくいうと、暗黙知を形式知に変えることができたこと。Cheff、Puppet、Ansible、Dockerなどに代表されるような構成管理が得意とする、環境（インフラ）のコード化ができたことは大きなメリットだと思う。

### 形式知化することの習慣化と手順の確定
自分のお気に入りの環境設定を今までどのようにバックアップしてきたかというと結構バラバラだったし、基本的にはメモベースだった。バックアップという考え方よりは作る方法を記載することで同じ環境を作るわけだから

### ほんとに便利と思うのはSublime TextのPackage管理
SublimeTextのPackage Controlでインストールってとても簡単で便利ですよね。だけど、何をインストールしたかって覚えてないし、また同じものをインストールするって面倒。これをテキストで管理できるのは素晴らしい。逆に入れ過ぎて何がどの機能なのかがわからなくなってますが・・。


## No!こんなはずじゃなかった

- 本当に細かい設定はできない（頑張ればできるけど、そこまで頑張ってやる意味あるのか？と思えてくる）
- 本来の目的を完全に達成するのには遠い
- 完全な構築にはならないので壊してまた作る、って気分にはならない

# ~Conclusion~ (結論)

Boxenは開発環境のみであれば、良い要素をいっぱい持っているが、
PCがビジネスツールとして存在しており、簡単な例だとメールの設定など、個人に依存する項目があるので労力や目的を考慮するとその多様性に対応できない。

- 「ツールよりも対話を」とアジャイル開発宣言にもあるように、BOXENを使っても対話による形式知化が必要だということ。
- 環境構築自動化による削減はあまり見込めないこと
- 「BOXEN使えば環境構築何もしなくて良い」ができるのは、個人のみで利用する場合に実現しやすい（が、大変なので現実的ではない。）


# （あとがき）
自分はサーバーサイドの人間だが、今までほとんどWindowsOS上で開発をやってきたのでMacの場合いろいろノウハウ教えて欲しい状況。
Macのほうがものすごく便利なので、組織全体でMacに乗り換えるとかいう場合など一気に環境が整うし、一度に情報交換ができる。
実際、開発環境の場合は情報の共有よりも実際に便利なツールやアプリだったりする。（環境構築作業に問題が多い場合は別だろうが現実的には少ない。）この辺りがBOXENの有効性に関してモヤモヤしてしまう一因でもありそうだ、と思う。dotfilesのように全て設定ファイルで網羅できるようになれば、そのファイルを取得して戻すっていうことができそう。でもそれってバックアップと同じなんだよなぁ。
コードレビューツール Review Board を使う

## 君は Review Board を知っているか
[Review Board](http://www.reviewboard.org/) というwebコードレビューツールがあります。
特徴として、コードレビューに特化して必要十分の機能をコンパクトに提供しています。

Review Boardではコードの差分を投稿するとリクエストとして扱われ、リクエストに対してコメント、コード差分上に指摘を入れていく形になっています。また、差分そのものを後から登録する事で、差分の世代管理・比較もできるようになっています。
[デモサイト](http://demo.reviewboard.org/dashboard/)で実際に動いてる内容が見れます。

現在、Gitとこれを組み合わせてレビュー環境として利用しています。


## 導入手順
CentOSを想定します。あとApacheとMySQLも入っている想定です。
バージョンが一世代古い時の内容なので、今は勝手が違うかも・・・

##### 1. yumでインストール
`yum install ReviewBoard`

##### 2. MySQLの準備
DBの文字コードをutf-8に設定しておけば日本語が使えます。
設定後はmysqlのリスタートが必要。

```text:/etc/my.cnf
[mysql]
default-character-set=utf8

[mysqld]
character-set-server = utf8
```

公式の手順にはないですが、事前にDB管理用のユーザ、スキーマの作成が必要でした。

```
# mysql
mysql> CREATE DATABASE reviewboard;
mysql> GRANT ALL ON reviewboard.* TO reviewboard@localhost;
mysql> FLUSH PRIVILEGES;
mysql> SET PASSWORD FOR reviewboard@localhost=password('reviewboard');
mysql> exit
```

##### 3. Review Board 初期化
`rb-site install /var/www/reviewboard`

基本的に指示に従えばいいです。DBは先ほど作成した物を指定。

memcacheの選択肢が出てくると思いますが、入れていなくても動きます。数人で使う程度であれば、パフォーマンス上も問題は出ていません。

##### 4. Apache設定
3.で作成したサイトにアクセスしたら諸々設定をするよう出ると思われます。
自分が必要だったのは以下のとおり

権限付与
`# chown -R apache:apache /var/www/reviewboard/`
生成されたファイルを配置
`# cp /var/www/reviewboard/conf/apache-wsgi.conf /etc/httpd/conf.d/apache-reviewboard.conf`
httpdリスタート

##### 5. 初期設定
これでとりあえず動くところまでは来たと思います。後はadminでログインしてリポジトリを追加したり色々することになります。
自分がした設定は以下のとおり

* Generalから Time Zone を Asia/Tokyo に変更
* Emailから Send e-mails for review requests and reviews にチェック、Senderを設定
* Loggingから /var/www/reviewboard/logs に Error で出力するよう設定
* グループにITメンバー用のMLを追加
* SSHから Gitリポジトリアクセス用のSSH秘密鍵を登録

##### 6. Gitとの連携
GitリポジトリごとにReviewBoardにリポジトリ登録をして、差分を取ってこれるようにする形です。
リポジトリ登録はGithubとかも指定できる……らしい。ローカルのリポジトリも指定できます。Review Boardが接続するときに使う鍵は、前述のとおり管理画面から登録できます。

開発しているGitリポジトリのリモートのURLと、Review Boardに登録しているリポジトリのPath かMirror Path が同じでないとうまく動かないと思われます。gitwebが入っていればリモートアクセスできるんですが、今の環境だとReview Boardのサーバにミラーを置いてそれを見る形にしています。

## 使用しての雑感

##### 利点
* コードレビューツールとしては申し分ない
* UIが作りこまれている（状態更新の通知など）
* レビューが独立しているため自由度が高い

##### 欠点
* リポジトリ登録がめんどくさい
* 差分の登録がめんどくさい
* 他のシステムと連動させられない
* 英語表記
* 日本語のドキュメントがない

##### まとめ

コードレビューツールとして完全に独立しているので自由度が高く、入れることでめんどくさくなる事はないけど、面倒見るのがめんどくさいという感じでしょうか。
ワークフローを新規構築し、github、bitbucket、ローカルでgerritやgitlabなどを使ってやるのであればそれで良いのではないかと思います。あとはGitに縛られないので、アイデア次第で色々使い道があるかもしれません。

* 運用が軌道に乗った状態を活かしつつ、レビューをツールをつかって効率化する。
* レガシーな環境で、自分のPCに入れて小さく始めてみる。

なんて用途にはうってつけの、小回りの効く良いツールではないかと思います。
NumPy の配列操作 (2)

[前回](http://qiita.com/ynakayama/items/706ae9e59c1b6fd3e3d2)は NumPy の話を一回休みして TeX の話をしましたので[前々回](http://qiita.com/ynakayama/items/af08a2d5f5648c0981fc)の続きです。

## 配列を並べるためのヘルパー関数

NumPy の名前空間には _r と _c という特殊なオブジェクトがあります。これらを使うと配列を簡単に構築することができます。

### _r 関数

_r 関数は、第 1 の軸に沿ってスライスオブジェクトに変換します。

1. インデックス式がカンマで区切られた配列が含まれている場合はスタック
2. インデックス式がスライス表記やスカラー数が含まれている場合は、スライス表記で示される範囲との 1 次元配列

スライス表記とは start:stop:step のことで、これは np.arange(start, stop, step) と等価になります。

戻り値には連結された配列または Matrix オブジェクトが返ります。

```py3
np.r_[np.array([1,2,3]), 0, 0, np.array([4,5,6])]
#=> array([1, 2, 3, 0, 0, 4, 5, 6])

np.r_[-1:1:6j, [0]*3, 5, 6]
#=> array([-1. , -0.6, -0.2,  0.2,  0.6,  1. ,  0. ,  0. ,  0. ,  5. ,  6. ])

a = np.array([[0, 1, 2], [3, 4, 5]])
np.r_['-1', a, a]
#=> array([[0, 1, 2, 0, 1, 2],
#          [3, 4, 5, 3, 4, 5]])

np.r_['0,2', [1,2,3], [4,5,6]]
#=> array([[1, 2, 3],
#          [4, 5, 6]])

np.r_['0,2,0', [1,2,3], [4,5,6]]
#=> array([[1],
#          [2],
#          [3],
#          [4],
#          [5],
#          [6]])

np.r_['1,2,0', [1,2,3], [4,5,6]]
#=> array([[1, 4],
#          [2, 5],
#          [3, 6]])

np.r_['r',[1,2,3], [4,5,6]]
#=> matrix([[1, 2, 3, 4, 5, 6]])
```

### _c 関数

_c 関数は、第 2 の軸に沿ってスライスオブジェクトに変換します。 

これは np.r_['-1,2,0', index expression] と等価であり、つまりは np.r_ の略記のような役割を果たします。

```py3
np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])]
#=> array([[1, 2, 3, 0, 0, 4, 5, 6]])
```

また _r と _c 関数はスライスを配列に変換できます。

```py3
np.c_[1:6, -10:-5]
#=> array([[  1, -10],
#          [  2,  -9],
#          [  3,  -8],
#          [  4,  -7],
#          [  5,  -6]])
```
gitで定期的にファイルをバックアップする

最近はもう [もうFTPを利用することは止めて、Gitを使おう](http://wp-d.org/2014/02/26/5709/) という流れですが
全員がそこまでスキルレベルが高いわけじゃないので、逆をすることにしました。

1. ユーザ（今回の場合デザイナ）はFTPなどを使ってファイルをアップロードする
2. gitを使ってアップロードされたファイルを定期的にバックアップ
3. 知ってる人（今回は自分を含めたプログラマ）がgitを使ってもとに戻せるように

# git push を cron で回してバックアップ

バックアップ用のスクリプトを書いて

```bash:sync.sh
#!/bin/bash
set -e
content_dir="<コンテンツを保存している場所>"

set -x
cd "$content_dir"
git add -A
git commit -m "Commit at $(date "+%Y-%m-%d %T")" || true
git push -f origin master:master
```

`crontab`で呼ぶ（今回は、毎日夜中の4時に）

```text
0 4 * * * /bin/bash /path/to/sync.sh >> /path/to/sync.log 2>&1
```

# 課題

問題はユーザが間違えて `.git` ファイルを消してしまった場合。
その場合 `git clone`して続きからやりたいんだけどいまいち良いやり方がわからない。

普通にやると

1. 現在のファイルを退避して
2. git cloneしなおして
3. 退避したファイルで上書きして
4. syncスクリプトを呼び出す。

退避しなくて済む方法はないかなあ

----

コメントより追記：

@ngyuki

> .git を削除しただけなら次のように .git を復元できるのではないでしょうか

>```bash
git init
git remote add origin "$remote"
git fetch origin
git branch master origin/master
git symbolic-ref HEAD refs/heads/master
```

上記の方法でバッチリ動きました！
gitコマンドの対象リポジトリを指定する

gitコマンドはカレントディレクトリ上のリポジトリを操作しますが、
`--git-dir`オプションで操作対象のリポジトリを指定できます。

なので、

`git clone --mirror ssh://git@xxx.xxx.xxx.xxx/xxxxxxxx.git`

みたいな感じで`/usr/local/gitrepos/`以下に持ってきたリポジトリ群を

```text:crontab
*/10 * * * * ls -1 /usr/local/gitrepos/ | xargs -i git --git-dir=/usr/local/gitrepos/{} remote update | logger -t "update repos" -p local0.info
```

といった形で10分ごとに更新させるといった事が、わりと簡単にできます。
フックスクリプトを使って華麗に解決できるようになりたい感ありますが
osxのシェルをオートサジェスト付きのfishに変更する


インストール

```
brew install fish
```

シェルを置き換え

```
sudo su
echo /usr/local/bin/fish >> /etc/shells
exit
chsh -s /usr/local/bin/fish
```


## 参考にしたサイト

http://fishshell.com/

http://vivafan.com/2013/02/fishfish/
javascript時短ワザ

#JSで時短
何かと時間のかかるjavascriptでのアプリ開発で時間短縮をはかる為に、Tipsを提供していきます。

##document.getElementById()を書かない
JSで開発する際、

```js:
var elem = document.getElementById('id');
```

というように書いていくことになると思います。
１回や２回ならいいですが、5回以上document.getElementById()と書くのは面倒だし、キャメルケースだからうち間違えそうだし・・・という感じではないでしょうか？
実はdocument.getElementByIdを一度も書かなくていもいい方法があるんです！

#Demo
何はともあれデモを
[デモ](http://jsfiddle.net/tabachan/g6c4P/1/ "JSFiddle")

びっくりしました？笑
javascript内で

```js:
divElement.hidden = true;
```

というように、書いていますが、divElementという変数はどこにも宣言していません。
いつもなら、

```js:
var divElement = document.getElementById('divElement');
```

のように書くはずです。
最近気づいたのですが、htmlでid属性を持つタグは、windowの同名のプロパティとして登録されるようです。今回なら、ブラウザがhtmlをロードした後に自動的にwindow.divElementが作成され、そこに対応するElementオブジェクトが登録されているようです。windowは省略できるので、divElementと書くだけでその要素が取得できる訳です。

試しに、

```js:
alert(document.getElementById('divElement')===divElement);  
```

とすると、どうなるでしょうか？("==="　は型も同じときtrueを返す)
[試してみる](http://jsfiddle.net/tabachan/g6c4P/3/ "JSFiddle")
試して分かるように、確かにdocument.getElementById('divElement')とdivElementは同じものであるようです。
つまり、idをjsで直接書くことができます！これでLet's時短開発！

#使用上の注意
javascriptでは、functionの内部の変数はその関数を抜けると参照されなくなるローカル変数ですが、ただ単に

```js:
var hako = 'aa';
```

のように宣言した場合はwindowオブジェクトにhakoというプロパティ名で登録されます。もしさきに同名のプロパティがある場合はそれが上書きされてしまいます。つまり、今回の場合は、もしjavascript上で

```js:
var  divElement = 'aa';
```

と書いてしまうと、上書きされてしまいます。先ほどの例だと[デモ](http://jsfiddle.net/tabachan/g6c4P/4/ "JSFiddle")というようになります。
変数名とid名がかぶらないようにしましょう。かぶる場合は、ちゃんとdocument.getElementById()関数を使うしかないです！

##数字は上書きできない
idを数値にした場合は、上のワザが使えません！いや使えたらヤバいです

##関数は上書きできない
例えばwindow.alert関数はidで上書きできません。できたらヤバいことになります。でもvar　では。。！？[こんなことに](http://jsfiddle.net/tabachan/g6c4P/6/ "JSFiddle")

この方法は、大規模開発ではお勧めしません。
しかし、決まった時間で開発する必要がある時などは時間短縮に効果があります。使用上の注意を良く読んで使ってください！
MavenでテストのJavaDocを生成しないようにする

Mavenを使っているプロジェクトで `mvn site` すると、デフォルトでテストのJavaDocも生成された。

今回は、テストのJavaDocは必要なかったため生成しないようにする。

## pom.xmlの書き方
```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <!-- 中略 -->
  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.9.1</version>
        <configuration>
          <show>private</show>
          <encoding>UTF-8</encoding>
          <charset>UTF-8</charset>
          <docencoding>UTF-8</docencoding>
        </configuration>
        <!-- ここの記述を追加する -->
        <reportSets>
          <reportSet>
            <reports>
              <report>javadoc</report>
              <!--
              ここに
              <report>test-javadoc</report>
              を追加するとテストのJavaDocも生成する
              -->
            </reports>
          </reportSet>
        </reportSets>
        <!-- ここの記述を追加する -->
      </plugin>
    </plugins>
  </reporting>
</project>
```

## 参考URL
[Maven Site Plugin 3 - Configuring Reports](http://maven.apache.org/plugins/maven-site-plugin/examples/configuring-reports.html)
[CakePHP 2.x] implode, explode を使って、文字列と配列を使い分ける方法。あと、cake の ActiveRecord での IN句 の使い方

# 前置き

久しぶりに cakephp に触れて、シェルとコントローラーを連携させるコードを書きました。

# implode, explode

```php:controller
public function hoge() {
・
・
・
  exec('php ' . APP . 'Console' . DS . 'cake.php hoge ' . $myId . ' ' . $media . ' ' . $genre . ' ' . ' add ' . $this->hogeId . ' >> ' . Configure::read('HogeLogPath') . ' &');

  $json = array(
    'result' => parent::SUCCESS,
    'error' => ''
  );

  echo $this->json_xencode($json);
  exit;
}
```

こんな感じ。
例えばこの $this->hogeId に複数の id を指定出来る様にしたい場合。
配列をそのまま送りつけてることが出来なかったので、

```php
1,2,3,4
```

みたいな感じで文字列で渡せる様にしてみました。

$this->hogeId の中身が

```php
array(
        (int) 0 => '1',
        (int) 1 => '2',
        (int) 2 => '3',
        (int) 3 => '4'
)
```

という配列になっていた場合、

```php
$arrayHogeIds = implode(',', $this->hogeId);
```

これで

```php
1,2,3,4
```

となる。

一つの文字列として、シェルの引数に渡せます。

受ける側のシェルで

```php
$arrayIds = explode(',', $hikisuu);
```

ってやることで、配列の状態に戻せます。

# IN句

上の値を、

```php
$hogeResult = $this->Hoge->find('all', array(
  'conditions' => array(
    'hoge.id' => $arrayIds
  )
));
```

こうすると sql の IN句が勝手に使えます。

```sql
select * from `hoge` where `hoge`.`id` IN (1,2,3,4)
```

な感じ。

めんどくさい様で、いい感じでした。


# ref

* http://stackoverflow.com/questions/16971754/how-use-operator-in-sql-on-cakephp
* http://phpnokowaza.seesaa.net/article/30530494.html
RubyからSolrのTermsComponentを利用する

# RubyからSolrのTermsComponentを利用する

## 利用するライブラリ

Solrへのアクセスする際に使用するライブラリとして、`rsolr`を使用します。

## TermsComponentとは?

検索フィールドでの単語の出現数を返すSolrのComponent。

cf. http://wiki.apache.org/solr/TermsComponent

## 検索部分の実装

まず、TermsComponentへリクエストを投げる部分の処理を実装します。

```ruby
require 'rsolr-ext'
class TermSearch
  class << self
    def search(solr_url, terms_params = {})
      solr = RSolr::Ext.connect url: solr_url
      params = build_params(terms_params)
      # #{solr_url}/terms へアクセスする
      response = solr.get 'terms', params: params
      parse_term_response(response)
    end

  private
    #
    # TermsComponent用のクエリーに変換する
    # @return [Hash]
    def build_params(terms_params)
      options = {}
      terms_params.each do |k, v|
        options["terms.#{k}"] = v
      end
      options
    end

    #
    # SolrのレスポンスをHashに変換する
    # @return [Hash]
    def parse_term_response(response)
      terms = {}
      return terms unless response['terms']
      response['terms'].collect { |(terms_area_field, values_and_hits)|
        items = {}
        values_and_hits.each_slice(2) do |k, v|
          items[k] = v
        end
        terms[terms_area_field] = items
      }
      terms
    end
  end
end
```

## 実際のリクエストを投げてみる

上記の実装を利用して、`prefecture`のフィールドでの単語の出現回数を取得してみます。
(注)検索対象のフィールドは、Solrのスキーマに合わせて、変更して下さい。

```rb
# prefectureのfieldでの出現回数の上位5件を取得する。
TermSearch.search("<SolrのURL>", {fl: 'prefecture', limit: 5})
D, [2014-05-22T16:16:26.358840 #18818] DEBUG -- :   SOLR Request (19.7ms)  [ path=terms parameters={terms.fl: ["prefecture_ja", "area_ja"], terms.limit: 10} ]
=> {
    "prefecture" => {
         "東京都" => 22,
        "鹿児島県" => 2,
         "三重県" => 1,
         "千葉県" => 1,
         "宮城県" => 1
    }
}
```

複数のフィールドで、検索を行う場合は、下記のように検索対象のフィールドを配列で指定します。

```rb
# prefectureのfieldでの出現回数の上位5件を取得する。
TermSearch.search("<SolrのURL>", {fl: ['prefecture','area'], limit: 5})
```
conf.d 以下の設定ファイルでApacheのログフォーマットを制御する

HTTPヘッダに特定の値をつけたので、それを Apache のログファイルに出力したい。
でも事情があって httpd.conf は手を入れられない...
そんなときは conf.d 以下に独自のファイルをつくります。

※RedHat系OSでのディレクトリにあわせて記載しているので、適宜読み替えてください。

+ /etc/httpd/conf.d/hoge.conf を以下のように作成

~~~
<VirtualHost *:80>
  CustomLog logs/access_log hoge
  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Original-Header}i\"" hoge
</VirtualHost>
~~~

+ 設定したら、構文エラーがないかチェックしてリスタート

~~~
/etc/init.d/httpd configtest
#=> Syntax OK
/etc/init.d/httpd restart
~~~

+ /var/log/httpd/access_log を確認

~~~
xxx.xxx.xxx.xxx - - [22/May/2014:12:00:00 +0900] "GET /index.html HTTP/1.1" 200 3000 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36" "(Original-Headerの中身)"
~~~
Rack アプリケーションのプロファイリングを手軽に取りたい

Sinatra とか Rails とかは Rack の上で動きます

ということで Rack ミドルウェアを使って手軽にプロファイリングを取りましょう

Gemfile の適当な場所に以下を足します

```rb:Gemfile
gem 'ruby-prof'
gem 'rack-contrib'
```

gem の最新は使えないので github から取るようにしましょう（2015/08/02 今年に入ってからgemも更新されるようになったようなので普通にgemでいいみたいです）

そして `Rack::Profiler` を読み込みます

```rb:config.ru
require 'ruby-prof'
require 'rack/contrib/profiler'

use Rack::Profiler
```

これで準備完了です

あとはプロファイリングを取りたい URL の GET クエリに `profile=process_time` を付与します

こうするといい感じの HTML が表示されるのでそれを見ましょう！

これでお手軽にプロファイリングを取れます
railsのflashを勘違いしてた

色々なブログで、flashは次のリクエストまで有効みたいに取れる書き方がされている。
自分もそれを鵜呑みにしていたので、flashの値が使われなくても勝手にクリアされると思ってた。

実際はcallされないとflashの中身は削除されない。
[actionpack/lib/action_dispatch/middleware/flash.rb](https://github.com/rails/rails/blob/9fc7a6fcedd3adc820d9d481d9362313c356747b/actionpack/lib/action_dispatch/middleware/flash.rb#L253)

適当にscaffoldして、show.html.erbの`<p id="notice"><%= notice %></p>`をindex.html.erbに移せば動作を確認出来るかと思う。
rails歴3年以上だけど、勘違いしてた事が恥ずかしい。
CentOSにfluentdを入れてapacheログをfluentdのログファイルに書き出してみた。

## fluentdインストール

RPMパッケージでインストール
[rpmパッケージからFluentdをインストールする | Fluentd](http://docs.fluentd.org/ja/articles/install-by-rpm#)

手順通り。

### インストール後使えるようになるサービス

``` /etc/init.d/td-agent ```

start, stop, status, restartできる。
設定ファイル直したら``` /etc/init.d/td-agent restart ```する。

### 設定ファイルの場所

- /etc/td-agent/td-agent.conf

## fluentd設定

```$ vi /etc/td-agent/td-agent.conf```

### apacheログファイル読み込む

apacheの設定例は設定ファイルの下の方にコメントアウトされている。

```
<source>
  type tail
  format apache
  path /var/log/httpd/access_log
  pos_file /var/log/td-agent/access.pos
  tag apache.access
</source>
```

#### td-agentの元設定ファイルからの注意点

##### pos_fileを追加すること

5行目のpos_fileがないと、td-agent起動時にワーニングがでる。

```
'pos_file PATH' parameter is not set to a 'tail' source.
this parameter is highly recommended to save the position to resume tailing.
```

##### tagを変えた方が良いかも

最初の状態だと、```tag td.apache.access```のようになっている。
これだと、この後の普通にファイルに出力する際に別のターゲットにマッチしてしまうらしく、ファイルに出てこない。。（これでしばらくハマった・・）

### apacheログファイルをtd-agentで読めるようにする

apacheログファイルのパーミッション設定を変える。
ファイルが読めない権限の場合、```/var/log/td-agent/td-agent.log```にエラーが書きこまれる。

```
# chmod o+rx /var/log/httpd/access_log
```

## 読み込んだログをfluentdのログファイルとして書き出す

```$ vi /etc/td-agent/td-agent.conf```

またもや設定ファイルを直す。さっきapacheログ読み込みを書いたsourceの下にでも追記。

```
<match apache.access>
  type file
  path /var/log/td-agent/access
</match>
```

tag変えた方が良いかも、で変えてない場合、td.apache.accessにすると、設定ファイルの上の方に書かれているtd.*に持ってかれてるっぽい。
Rails で環境ごとに見た目を変える


# 1 変更したい内容を書いた css を環境ごとに用意する

app/assets/stylesheets/environment/ に↓のようなファイルを環境ごとに用意する。

```production.css.scss
.navbar-default {
  background-color: #35fff5;
}

```

# 2 intializer の中で環境ごとに読み込み対象を切り替える
config/initializer/assets
environment.rb で環境ごとに切り替える。
＃もっといい書き方がありそうな・・

```ruby:environment.rb
case Rails.env
  when 'development' then
    Rails.application.config.assets.precompile += %w( environment/development.css )
  when 'staging' then
    Rails.application.config.assets.precompile += %w( environment/staging.css )
  when 'production' then
    Rails.application.config.assets.precompile += %w( environment/production.css )
  else
end

```

# 3 application.html で環境ごとの css を読み込む

```application.html.haml
= stylesheet_link_tag    asset_path "environment/#{Rails.env}", media: 'all', 'data-turbolinks-track' => true

```

Htmlのどこかにも環境名を出しておくと親切な気もする。

```
%a.navbar-brand{:href => "/"} Admin #{Rails.env}環境
```

# 4 できた
![Screenshot 2014-05-22 15.53.41.png](https://qiita-image-store.s3.amazonaws.com/0/27210/9cf32d49-6088-da5f-f5d4-b6a9d30b5f2e.png "Screenshot 2014-05-22 15.53.41.png")

![Screenshot 2014-05-22 15.54.06.png](https://qiita-image-store.s3.amazonaws.com/0/27210/114e4f13-ef54-47a1-dc8a-9a65af82af16.png "Screenshot 2014-05-22 15.54.06.png")

# 5 注意

application.css.scss で require_tree をしてると全環境読み込まれるので個別に css を指定しないといけない。＃view ごとの css にスタイルを書くってあまりないから問題ないような気がしています。
vimで一時的に文字コードを変換するには

例えば、UTF-8な環境でShift-JISで書かれた文書をvimで読むと当然文字化けする。
元のファイルの文字コードは直したくないが、文字コードを指定してファイルを開き直すには

```
:e ++enc=文字コード名
```

とすればよい。文字コードは「euc-jp」「shift_jis」「utf-8」があれば十分だろう。
MojoliciousでTemplate::Toolkitを使う


# 概要

事情があってMojoliciousでTTを使う場合の設定方法。


# Mojolicious::Plugin::TtRenderer

MojoliciousでTTを使うためのプラグイン。
cpanmで普通にインストール。

```shell
$ cpanm Mojolicious::Plugin::TtRenderer
```

# Template::Stash::AutoEscape

自動エスケープ機能を追加するTTのプラグイン。
Makefile.PLに依存モジュールとして"Template::Toolkit"と記載されているため、
インストールに失敗する。
以下の手順で、Makefile.PLを編集してインストールする。

```shell
$ wget http://cpan.metacpan.org/authors/id/M/MA/MALA/Template-Stash-AutoEscape-0.03.tar.gz
$ tar xvzf Template-Stash-AutoEscape-0.03.tar.gz
$ cd Template-Stash-AutoEscape-0.03/
$ perl -i -ple 's{Template::Toolkit}{Template}' Makefile.PL
$ perl Makefile.PL
$ make
$ make test
$ make install
```

# プラグイン有効化

以下のように記述して、プラグインを有効にする。

```perl:myapp.pl
use Mojolicious::Lite;

plugin 'TtRenderer', {template_options => {STASH => Template::Stash::AutoEscape->new}};
```

# Template::Toolkitの利用

テンプレートファイルの拡張子は「html.tt」となる。

url_forなどの関数を読み出すときは「c.url_for」のように記述する。
ヘルパーは「h」経由で呼び出す。

layout機能を使う場合、contentをそのまま記述すると、
contentで読み込まれるHTMLがエスケープされてしまうので、
rawオプションを使用する必要がある。

```html:templates/layouts/default.html.tt
<html>
<head><title>テスト</title></head>
<body>
<div>
[% content.raw %]
</div>
</body>
</html>
```

以下、Template::Toolkitを使った時のサンプルアプリ。

```perl:myapp.pl
use Mojolicious::Lite;

use Template::Stash::AutoEscape;

plugin 'TtRenderer', {template_options => {STASH => Template::Stash::AutoEscape->new}};

my @users = (
    {
        id => 1,
        name => '太郎',
        age => 30,
        note => '<b>太郎</b>',
    },
    {
        id => 2,
        name => '花子',
        age => 31,
        note => '<b>花子</b>',
    },
);

get '/' => sub {
    my $self = shift;

    $self->stash->{users} = \@users;

    $self->render();
} => 'index';

get '/detail/:id' => sub {
    my $self = shift;

    my $id = $self->param('id');
    my ($user) = grep { $_->{id} == $id } @users;

    if (!$user) {
        return $self->render_not_found();
    }

    $self->stash->{user} = $user;

    $self->render();
} => 'detail';



app->start;
__DATA__

@@ layouts/default.html.tt
<html>
<head>
<meta charset="utf8">
<title>[% title %]</title>
</head>
<body>
<h1>[% title %]</h1>
<div>
[% content.raw %]
</div>
</body>
</html>


@@ index.html.tt
[% WRAPPER "layouts/default.html.tt", title="一覧" %]
<table>
<tr>
  <th>ID</th>
  <th>名前</th>
  <th>年齢</th>
  <th>備考</th>
</tr>
[% FOREACH u=users %]
<tr>
  <td>[% u.id %]</td>
  <td><a href="[% c.url_for('detail', id => u.id) %]">[% u.name %]</a></td>
  <td>[% u.age %]</td>
  <td>[% u.note %]</td>
</tr>
[% END %]
</table>
[% END %]

@@ detail.html.tt
[% WRAPPER "layouts/default.html.tt", title="詳細" %]
<a href="[% c.url_for('index') %]">戻る</a>

<table>
<tr>
  <th>ID</th>
  <td>[% user.id %]</td>
</tr>
<tr>
  <th>名前</th>
  <td>[% user.name %]</td>
</tr>
<tr>
  <th>年齢</th>
  <td>[% user.age %]</td>
</tr>
<tr>
  <th>備考</th>
  <td>[% user.note %]</td>
</tr>
</table>
[% END %]
```
Rubyで前ゼロパディングされた文字列'01'をインクリメントして'02'にする

"01" という入力値をインクリメントした "02" という文字列を出したいといったケースがよくあります。

冗長な例

```rb
num = "01".to_i # => 1
num_str = num.to_s # => "1"
"0" * (2 - num_str.length) + num.succ.to_s
```

Rubyに慣れてくると String#% を知って、こういうコードを書いたりします。

```rb
"%02d" % "01".to_i.succ
```

ところがどっこい、succは元々デキる子でStringクラスにも存在するのでした。

```rb
> "01".succ #=> "02"
```

String#% を使う方が可読性高い気もしますが、 succ メソッドの方がメソッドチェーン書きやすそうです。
[Objective-C] UISplitViewControllerをコードから生成してiPad対応するまとめ


色々調べてみても、Storyboardを使って生成するサンプルが大半で、コードから生成する方法があまり見つからなかったので、コードで作る方法をメモしています。
[サンプルはGithubにあげている](https://github.com/edom18/SplitViewControllerSample)ので、よかったら参照ください。


## ビューの入れ子構造を作る

`UISplitViewController`はコンテナViewControllerです。
（コンテナViewControllerについては前に「[カスタムContainer View Controllerを作る](http://qiita.com/edo_m18/items/8b6b457f82b185ab1f6a)」に書いているので詳しくはそちら）

最初、左右にViewControllerを配置する方法が分からなかったんですが、単純に`viewControllers`の配列にふたつのViewControllerを入れてやればいいだけでした。
（サンプルでは`addChildViewController:`メソッドを使用）

```objc
// サンプルコード断片

// UISplitViewControllerを生成
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];

// 左右に配置するViewControllerを生成
UIViewController *viewController1 = [[UIViewController alloc] init];
UIViewController *viewController2 = [[UIViewController alloc] init];

// デリゲート先を設定する
splitViewController.delegate = viewController1;

// 入れ子にしたいViewControllerを追加
// 最初に追加したものが左、次が右に配置される
[splitViewController addChildViewController:viewController1];
[splitViewController addChildViewController:viewController2];
```


## UISplitViewControllerDelegate

どうやら、iPadを縦横にしたときの挙動はUISplitViewControllerが制御しているようです。
そして横向きから縦向きになる瞬間に、とあるデリゲートメソッドが呼ばれる仕組みみたいです。

それ以外の「ビューを隠したり表示したり」という操作は`UISplitViewController`クラスがすべてやってくれます。


### UISplitViewControllerDelegateプロトコル

さて、向きが変わる際に呼ばれるデリゲートメソッドは以下のふたつです。
（テンプレートプロジェクトからの引用です）

```objc
// 縦向きになるときに呼ばれる
- (void)splitViewController:(UISplitViewController *)splitController
     willHideViewController:(UIViewController *)viewController
          withBarButtonItem:(UIBarButtonItem *)barButtonItem
       forPopoverController:(UIPoopoverController *)popoverController
{
	barButtonItem.title = NSLocalizedString(@"Master", @"Master");
	[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
	self.masterPopoverController = popoverController;
}


// 横向きになるときに呼ばれる
- (void)splitViewController:(UISplitViewController *)splitController
     willShowViewController:(UIViewController *)viewController
  invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
	// Called when the view is shown again in the split view, invalidating the button and popover controller.
	[self.navigationItem setLeftBarButtonItem:nil animated:YES];
	self.masterPopoverController = nil;
}
```

[Githubのサンプル](https://github.com/edom18/SplitViewControllerSample)では、それぞれUIViewControllerを直接入れ子にせずに、さらにUINavigationViewControllerを間にはさんで、タイトルが表示できるようになっています。
[PHP] 文字列の1文字目を大文字にする

##追記
タイトルの処理がしたい時は、ucfirst関数を使いましょう！
http://www.php.net/manual/ja/function.ucfirst.php

しかも下の処理だと、参照されていないので
変更はされないし、新しい格納領域をつくったりしてしまうので
ちゃんと参照しましょう。
http://jp2.php.net/manual/ja/language.references.pass.php
**mpywさん、ありがとうございました！**


****
配列に文字列がおさまっていて、
1文字目に何らかの処理をしたい時。

```php:first_char.php
foreach ($ary as $val) {
    $val[0] = strtoupper($val[0]);
    ....
    }

```

配列から取り出した文字列の1文字目を参照するって、
すっごく無理があるというか、独特な感じがいたしました。
~~なんかとても気持ち悪い……~~
virtualboxの仮想ディスクをデフラグする


guest側はdebianを想定

2017-11-28 zerofreeより簡単な方法があったので追記

### 空いてるスペースに0を書く

```
dd if=/dev/zero of=/tmp/bigemptyfile bs=4096k
rm /tmp/bigemptyfile
```

### compaction

```
$ VBoxManage modifyhd /path/to/disk.vdi --compact
```

formatがvmdk等compact対応していないものの場合は、clonehdすればよい


## 古い方法

### 0. バックアップ

なくなったら困るファイルをバックアップしておく。
以下の作業は自己責任で


### 1. guest側でzerofreeをインストール

```
$ sudo apt-get install zerofree
```

### 2. guest側でzerofreeを実行

ファイルシステムをread onlyにしないと実行できないので、一旦reboot〜セーフモードで起動してremountしてから実行する

```
# mount -n -o remount,ro -t ext3 /dev/sda1 /
# zerofree /dev/sda1
```

`/dev/sda1`の部分は環境に応じて適宜変更。

busyと言われる場合は、`rsyslogd`とか`dhclient`が起動してる可能性がある。手動でkillすればよい。

zerofreeは結構時間かかるのでしばらく待つ。
終わったら一旦シャットダウンする。


### 3. host側でVBoxManageを実行

```
$ VBoxManage modifyhd /path/to/disk.vdi --compact
```


手元の環境では21Gのvdiが14Gになった。まあまあ効果ある。
MacにAnsibleをインストール


なんかMacをAnsibleのサーバーにした方がらくちんな気がしてきた今日この頃。
どうせ最初からPython入っているのでMacにAnsibleを入れてみた。

# Pythonのバージョン確認

とりあえずバージョン確認。

```bash
$ python --version
Python 2.7.5

```

Mervelicksは最初から2.7.5が入っているみたいなのでOK。

# pipのインストール

公式参照。
http://pip.readthedocs.org/en/latest/installing.html

```bash
$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo python get-pip.py
```

らくちん。

# Ansibleのインストール

先にAnsibleが依存しているものを入れておく。

なんか、Xcodeの5.1からclangの動作が変わったらしくて、下のような長ったらしいフラグつけないとうまくいかない模様。

```
ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future
```

参考：MacOSX10.9のRedmineを2.5.0に更新した - Basic
http://d.hatena.ne.jp/rabbit2go/20140316/1394946822

そんなわけで依存しているやつをインストール。

```bash
sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future pip install paramiko PyYAML jinja2 httplib2
```

そしてはりきってAnsibleをインストール。

```bash
sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future pip install ansible
```

すんなり終了。
clangの件が割とあっさり解決したので楽でした。
AdMobを組込む

1) AdMob SDKを落とす

https://developers.google.com/mobile-ads-sdk/download#downloadios

2) 解凍して得られるディレクトリをvendorディレクトリ(なければ作る)の下に入れる


```bash
$ mkdir vendor
$ unzip   ~/Downloads/googlemobileadssdkios.zip 
$ mv GoogleMobileAdsSdkiOS-6.9.2/ vendor/
```

3) Add-onsは消す

```bash
$ rm -r vendor/GoogleMobileAdsSdkiOS-6.9.2/Add-ons
```

4) Rakefileに次を書き加える

```rb
Motion::Project::App.setup do |app|
  # 略
  app.frameworks += ["AdSupport", "AudioToolbox", "AVFoundation", "CoreGraphics", "MessageUI", "StoreKit", "SystemConfiguration", "CoreTelephony"]

  app.vendor_project('vendor/GoogleMobileAdsSdkiOS-6.9.2/', :static)
end
```

5) 広告を組込みたいViewControllerにて下記を書き加える

```rb
    @banner = GADBannerView.alloc.initWithAdSize(KGADAdSizeBanner).tap do |b|
      b.adUnitID = '自分のユニットID'
      b.rootViewController = self
      b.frame = [[0, 0], [320, 50]]
      self.view.addSubview(b)
      b.loadRequest(GADRequest.request)
    end
```
初心者向けプログラミング学習サイト・スクール

# 初心者向けプログラミング学習

プログラミングをしたことがないけどサイトを立ち上げてみたい初心者、学生さん・社会人向けに提供されているサービス

## 動画で学習

---

* ドットインストール - 3分動画でマスターする初心者向けプログラミング学習サイト
 * http://dotinstall.com/
 * ３分の動画を見ながら学習できる
 * HTML/CSS/JavaScript から PHP/Ruby/Python などのサーバサイドまで幅広い

---

* schoo（スクー） WEB-campus
 * https://schoo.jp/
 * プログラミング専門ではなく色々な内容を放送しています
 * １～２時間程度の生放送で質問なども可、録画もあり

---

## Webで学習

しっくりくるサイトがあまりない（海外が多い）ので出てきたら増やします

---

* CodeStudy
 * http://jeek.jp/study
 * JavaScript/jQuery の基本的な関数を入力しながら学習できます

---

* Codecademy
 * http://www.codecademy.com/
 * チュートリアルを見ながら実際に入力して学習できます
 * 英語

---

## 通学して学習

---

* TechAcademy [テックアカデミー] | ITに特化したスクール
 * http://techacademy.jp/
 * はじめてのプログラミング講座からデザイン/Android/iPhoneなど多岐にわたる
 * 受けたい講座ごとに申し込みができる（１講座２万円程度）
 * 平日夜か土曜などに実施されており、社会人でも通える

---

* プログラミング学習ならオンライン個別指導のプログラミングスクール [CodeCamp]
 * https://codecamp.jp/
 * １回４０分、Google ハングアウトを利用して講師とマンツーマンで指導を受けられる

---

* TECH GARDEN SCHOOL「超初心者」専門ITスクール
 * http://techgardenschool.com/
 * 受けたい講座ごとに申し込みができる
 * 土曜日に実施されている

---

随時更新します
[ビットコインの技術] マルチシグネチャの技術的説明

以下に移行しました<br><a href="http://block-chain.jp/tech/bitcoin-multi-signature/" title="[ビットコインの技術] マルチシグネチャの技術的説明">[ビットコインの技術] マルチシグネチャの技術的説明</a>
Fluentdみたいなノリで、メッセージサービスをつくれないかなぁ


##背景
* __メッセージって、いろんな場所でいろんな人が好き勝手送ってくるよね__
  * Gmail, Facebook, LINE, Google+, SMS…
* __見逃したりすると、まじショックなものってあるよね__
  * 仕事のお誘い、元カノからの久々のメッセージ、同窓会．．

##Fluentdって知ってますか、知ってますよねすいません

![fluentd](http://docs.fluentd.org/images/fluentd-after.png)

* メッセージアプリ自体が一つに淘汰されること、
* なにかプロトコルレベルで策定されたものが浸透すること、

とかは起こりにくそうなので、fluentdくらいのレベル感で、統合して、好き勝手にメッセージの出力先をカスタマイズしてもらいたい。

返信は、元のサービスにログインしてからできる、でもまぁ良いんじゃないかな。
xcodebuildでコマンドラインからUT実行

Xcodeを起動しなくてもUTを実行したい。そんな場合向けのMakefile

```$BUILDACTIONS```, ```$DEST``` は適宜環境に合わせて。

xcpretty は ```gem install xcpretty``` とかでインストールしておく。

```mf:Makefile
XCODEBUILD = xcodebuild
DEST = 'platform=iOS Simulator,name=iPhone Retina (4-inch)'
WORKSPACE = APE.xcodeproj/project.xcworkspace
PROJECT = Project.xcodeproj
SCHEME = SchemeName
DEBUG = Debug
RELEASE = Release
BUILDACTIONS = clean test
PIPECMD = | xcpretty -c

all: test_release

test_release:
	$(XCODEBUILD) -scheme $(SCHEME) -destination $(DEST) -configuration $(RELEASE) $(BUILDACTIONS) $(PIPECMD)

test_debug:
	$(XCODEBUILD) -scheme $(SCHEME) -destination $(DEST) -configuration $(DEBUG) $(BUILDACTIONS) $(PIPECMD)
```

xcpretty のおかげで成功、失敗したテストが見やすくて便利。
Re: 私家版MVCべからず集

# はじめに

下記の記事を読んだので、せっかくなので私の考えも述べようかと思う。

- [私家版MVCべからず集](http://qiita.com/usopyon/items/6a19ee911682dc95a591)
- [RE: 私家版MVCべからず集](http://qiita.com/t_ishida/items/f6adc8de5f113c42ec85)

@t_ishida さんが書かれている

> 他の人の考える「ぼくのかんがえるMVCべからず集」も読んでみたいです。

には私も同意なのでもっと投稿が増えるとうれしい。
それとQiitaにはトラックバック機能を用意してほしい。

# 私流MVCの分け方

私のMVCの分け方はこんな風だ。

```text
if UIの仕事 || Webの仕事
  if HTMLの生成
    Viewに書く
  else
    Controllerに書く
  end
else
  Modelに書く
end
```

これに基づき、各項目について自分の意見を述べる。

# 回答

引用は、本投稿の先頭のリンク先のものです。
二つを分けるため後者からの記事にのみ @t_ishida さんの名前を書いておきます。

## Model

> DBにアクセスしていいのはModelだけ。

同意。正確に言えば「直接DBにアクセス」「SQLの生成」などはModelの仕事。

@t_ishida 

> 必要であればViewからも直接DBを見に行けるべきです。Viewが単純に表示したいだけの都合でModelやControllerが影響を受けるべきではない。

DBに触る場合はコネクションを張るなどの前準備が必要なので、そこらへんをモデルに書くとViewから直接ってのはあまり無いように思う。
Viewのこまごましたことにデータ用のインスタンスを作る必要はないという意味であれば同意。
Modelモジュール内にちょろっとしたstatic関数を用意してViewからそれを叩くのがよいと思う。

> 他のデータとの整合性など最終確認はModelで。

同意。

> テストファーストで書く

テストは当然書くべきだが、それはMVCとは別。
あと私はテストは後に書く派です。

> ここでprintとか絶対NG

このprintはどこへの出力だろうか。

- 標準出力へ書き込み
    - ダメ。リポジトリにコミットする前に必ず取り除くこと。
- logファイルへの書き込み。
    - 良いことだ。
- HTTPリクエストのレスポンスボディへの書き込み
    - 同意。Viewに全投げすべき。

> ここでWebサーバ由来の情報（SESSIONなど）があったら、何か間違ってる

同意。

## View

> ここでDBにアクセスしてたら何か間違ってる

同意。前述のとおり。

> ここでIF文とかあったら、Controller側ですべきか検討する

IFはそんな大きな機能じゃないので一概に言えるものではない。
ユーザ一覧を`<table>`で表示するViewが、ユーザがいないときは「ユーザは見つかりませんでした」と表示したいのであれば、IF文は必要だと思う。

## Controller

> ここでDBにアクセスしてたら何か間違ってる

同意。前述のとおり。

> ここでバリデーションとかしてたら、何か間違ってる

Modelの箇所に「最終確認はModelで」と書いてあるのに同意する。
データの整合性のバリデーションはModelに書くべきである。

しかしユーザビリティのため同じようなコードをControllerやViewに書いてしまうことも多々ある。最近のWebアプリだとJavascriptで入力検証したり`<input>`要素に`maxlength`や`required`属性をつけて検証していたりする。Controllerでするのが妥当なバリデーションもある。

Rails4では「Strong Parameters」という機能が入りまさにControllerで検証を行っている。
あるモデルのある個所を変更してよいかは「モデルの責務」ではなく「WebAPIの責務」だという考えかたのようだ。

# おわり

いろいろ書いたがこういうのは理想論に近いので、無理のない程度に自分の理想を追いかけるのが良いと思う。
aptitudeのイースターエッグ

## aptitude -v… moo

### イースターエッグとかマジねーから

```console
$ aptitude -v moo
There really are no Easter Eggs in this program.
```

### ないっつったよな？

```console
$ aptitude -vv moo
Didn't I already tell you that there are no Easter Eggs in this program?
```

### おいやめ

```console
$ aptitude -vvv moo
Stop it!
```

### はいはい。イースターエッグが欲しいなら、他をあたりな？

```console
$ aptitude -vvvv moo
Okay, okay, if I give you an Easter Egg, will you go away?
```

### そうだな、お前の勝ちだ

```console
$ aptitude -vvvvv moo
All right, you win.

                               /----\
                       -------/      \
                      /               \
                     /                |
   -----------------/                  --------\
   ----------------------------------------------
```

### これは何って？　蛇に飲み込まれた象だよ、わかるだろ

```console
$ aptitude -vvvvvv moo
What is it?  It's an elephant being eaten by a snake, of course.
```

### わかるだろ

```console
$ aptitude -vvvvvvv moo
What is it?  It's an elephant being eaten by a snake, of course.
```

### わかるだろ

```console
$ aptitude -vvvvvvvv moo
What is it?  It's an elephant being eaten by a snake, of course.
```

## 関連（？）

* [elephant being eaten by a snake - Google 検索](https://www.google.co.jp/search?q=elephant+being+eaten+by+a+snake&tbm=isch)

---

![ElephantInSnake.jpg](https://qiita-image-store.s3.amazonaws.com/0/10765/28fbe78d-724a-bc20-3e8f-4c6c394f819d.jpeg)

(via http://neonboy619.blogspot.jp/2010/02/little-prince-1974-lerner-and-lowe.html)

「星の王子さま」に出てくるやつが元ネタみたいです。
testlinkでステータスを追加する

Testlink Version 1.9.9使用。

基本的にはcustom_config.inc.phpに書いてあるとおり。

custom_config.inc.php
strings.txt
testlink.css
の３つを編集する。

custom_config.inc.phpは
not_available、unknown、allのコメントアウトを外すとうまくうごかなかった。
既存のステータスである、failed、blocked、passed、not_runの４つのコメントアウトを外して
かつ、追加したいmy_statusのコメントアウトをはずす。
WebViewのJavascriptInterfaceを使用したアプリのAPKファイルを作成する際の注意


WebViewのJavascriptInterfaceを使用してWebView内HTMLのjavascriptからアプリのメソッドをキックする処理を入れていたら、
APKファイルを作成してインストールした途端にそれが動かなくなる事態に。

デバッグしてみるとこんなメッセージが。

```
 [INFO:CONSOLE(37)] "Uncaught TypeError: Object [object Object] has no method 'kickFromJavaScript'", source: http://hogehoge.jp/ (37)
```

定義元はJavascriptInterface

```
@JavascriptInterface
public void kickFromJavaScript() { ... }
```

原因は、APKファイルを作成する際にProGuardをかけていたから。
ProGuardをかける場合はJavascriptInterfaceのアノテーションを明示的に宣言(?)しておく必要があるらしい。

参考) http://stackoverflow.com/questions/20549706/javascriptinterface-on-android-dont-work-with-apk-in-release-mode

```
-keep public class com.mypackage.MyClass$MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass$MyJavaScriptInterface
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface { 
    <methods>; 
}
-keepattributes JavascriptInterface
```
pod installが遅い


# ライブラリのバージョンアップはしない

```console
$ pod install --no-repo-update
```

# ライブラリのバージョンアップをしたい

基本的には諦めるしかない気がする…。

でも、cloneしてきたリポジトリで、`git gc`してあげると気持ちちょっと軽くなったような…。

```console
$ cd ~/.cocoapods/repos/master
$ git gc
```

の後に、

```console
$ pod install
```