OmniAICreator/Qiita-1.07M huggingface dataset:
CentOSにRuby on Railsの環境構築とか

CentOSにRailsの環境を構築したので，そのメモです．zshを使っています．

<dl>
 <dt>ruby</dt>
  <dd>本体．デフォだと1.8とか(古い)</dd>
 <dt>rbenv</dt>
  <dd>rubyのバージョンを管理してくれる</dd>
 <dt>gem</dt>
  <dd>rubyのライブラリを管理してくれる</dd>
 <dt>npm</dt>
  <dd>node.jsのパッケージを管理してくれる</dd>
</dl>

#とりあえずダウンロードするもの

```zsh
$ sudo yum install zlib zlib-devel openssl-devel sqlite-devel gcc-c++ glibc-headers libyaml-devel readline readline-devel zlib-devel
```

#rbenvインストール
gitからrbenv関連をcloneする

```zsh
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

.zshrcに以下を追加

```zsh:.zshrc
export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init - zsh)"
```
.zshrcを再読み込み

```zsh
$ source .zshrc
```

念のためバージョン確認

```zsh
$ rbenv -v
rbenv 0.4.0-98-g13a474c
```

#Rubyのアップデート
インストールできる一覧を出す

```zsh
$ rbenv install --list
```
2.1.3が安定版との事なので，これをインストールします

```zsh
$ rbenv install 2.1.3
```
再読み込み

```zsh
$ rbenv rehash
```
インストールされてるバージョンを表示.なんか選択されてるのに＊とかついてるはず．

```zsh
$ rbenv version
```
環境全体で使うRubyのバージョンを指定する．
細かく設定する事もできますが，めんどうなのでglobalで

```zsh
$ rbenv global 2.1.3
```

バージョンが選択されたか確認

```zsh
$ rbenv version
2.1.3 (set by /home/****/.rbenv/version)
$ ruby -v
ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-linux]
```

これでRubyは入りました．
新しいバージョンが出た時にはrbenvで新しいのに切り替えれば良いので，
とても便利みたいです．

#gemをインストール,アップデート
いろいろライブラリがあるので，それを入れるマネージャです．

確か，デフォルトでも入ってたような気がしなくもないけど，新しバージョンにする為にも
アップデートもします．

```zsh
$ sudo yum install gem
$ sudo gem install rubygems-update
$ sudo update_rubygems
```

年の為，gemのバージョンを確認

```zsh
$ gem -v
2.2.2
```

#JavaScriptのランタイムのインストール
Ruby on RailsではJavaScriptのランタイムが必要なようです．
幾つかあるようですが，流行ってるらしいnode.jsをインストールします
npmはnode.jsのパッケージを管理するやつらしいです．

```zsh
$ yum install nodejs npm –enablerepo=epel
```

#Ruby on Railsのインストール

```zsh
$ gem install rails
```
バージョンの確認

```zsh
$ rails -v
Rails 4.1.6
```

これでRailsの環境は入ったはずです．
あとはポートの設定とかちょっとすれば良いのかな

#「このウェブページにアクセスできません」の解決
デフォルトでは3000番ポートが指定されています．
自分のVPSのiptablesでちゃんと設定されて，反映されているのかを確認．

別のportから接続する場合にはとりあえず

```zsh
$ rails s -p ****
```
みたいな感じで設定したport番号を指定してやれば良いです．

また，selinuxが悪さをする場合もあるっぽい?(ConoHaはデフォルトでDISABLEDになってる気がするから気にしなくて良い?)

そもそも自分の繋がってるネットはポートを使わせてくれてる？？？？
(僕は，学内のネットが22と80くらいしか許してなくて，これで躓いてました)

VPSとかrailsの設定だけでなく，そもそもの自分のネット環境で躓く事もある．

#terminalでのホスト名を変更する
デフォルトだとConoHaのプロンプトには

```zsh
ayihis@v1XX-X-XXX-XXX.XXXX.static.cnode.jp
```
みたいに表示されます．
これを例えば"ConoHa"に変更するには

```zsh
$ sudo hostname ConoHa
```
とします

#その他
##Ubuntu14.10に入れるとき

rbenv install 2.*.*みたいにやる前に

```zsh
$ sudo apt-get install libssl-dev
```

これを入れとかないと

```
BUILD FAILED (Ubuntu 14.10 using ruby-build 20141028-5-gd22a320)

Inspect or clean up the working tree at /tmp/ruby-build.20141104132027.14612
Results logged to /tmp/ruby-build.20141104132027.14612.log
```

みたいな感じでビルド失敗しました．入れましょう
[Unity] Shaderでライトと影（Shadow）を制御するレンダリングパス


![cap.jpg](https://qiita-image-store.s3.amazonaws.com/0/5616/623bc618-bc08-d742-6d2e-a6c8bde661b0.jpeg "cap.jpg")
[自作のファーシェーダ](https://www.assetstore.unity3d.com/jp/#!/content/22226)をアップデートすべく、色々と調べています。
調べていく中で、だいぶ自分の中でレンダリングパスについて整理できてきたのでまとめたいと思います。

[詳細はこちら（Forward Renderingパスの詳細 / Forward Rendering Path Details - Unity Manual）](http://docs-jp.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html)


## Unityでライトと影（Shadow）を制御する

Unityでは、ライトと影のレンダリングはいくつかの[レンダリングパス](http://docs-jp.unity3d.com/Documentation/Manual/RenderingPaths.html)を用いて行います。
レンダリングパスには以下のものがあります。（Unity Manualから引用）

>
**Deferred Lighting**
Deferred Lighting はライトと影が最も厳密にレンダリングされます。もし多くのリアルタイムライトを使いたいのであれば最適でしょう。ただ、これはハードウェアがある一定のレベルが必要なので、Unity Pro 専用で、 Mobile Devices ではサポートされていません。
>
さらに詳しくは [Deferred Lighting page](http://docs-jp.unity3d.com/Documentation/Components/RenderTech-DeferredLighting.html) を参照して下さい。
>
**Forward Rendering**
Forward Rendering はシェーダーベースのRendering Pathsです。 これはパーピクセルライト（ノーマルマップやlight Cookiesが含まれます）をサポートし、１個のディレクショナル（一方方向）ライトからのリアルタイムシャドウをサポートします。 デフォルト設定では、パーピクセルライトモードでは最小の数のライトでレンダリングされます。 残りのライトは頂点で計算されます。
>
さらに詳しくは [Forward Rendering page](http://docs-jp.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html) を参照して下さい。
>
**Vertex Lit**
Vertex Lit は一番軽いRendering Pathsで、リアルタイム影もサポートされていません。古いマシンでは最も使われるでしょうし、モバイルプラットフォーム限定利用されるかもしれません。


## ForwardBaseレンダリング

（Unity Manualから引用）
>Base Passは一つのピクセルごとの指向性ライトおよび全ての頂点ごと／SHライトを適用します。


指向性ライト（平行光源、ディレクショナルライト）によるライティングが可能なレンダリングです。
それ以外のライトについては球面調和としてライトが計算され、それを適用します。

マニュアルによれば、このモード（タグに`"LightMode"="ForwardBase"`を指定したパス）は、ひとつの指向性ライトによるピクセルライトと、影のサポートがあるようです。
つまり、 **ForwardBaseではポイントライトやスポットライトなどはサポートされません**。


## ForwardAddレンダリング

指向性ライト以外のライトについて計算が可能なレンダリングです。（指向性ライトも含まれます）
しかし、こちらのモードでは、いわゆる **影（Shadow）をレンダリングすることができません**。
影を適用する（Receive Shadow）場合は上記のForwardBaseレンダリングでレンダリングしなければなりません。

これはつまり、影のレンダリングは指向性ライトのみが適用できる(※1)、ということです。
実際にシェーダを書いてみると、シャドウマップなどのテクスチャ情報が定義されておらず、利用できなくなります。

※1 ... Unity Pro版であれば[遅延ライティング](http://docs-jp.unity3d.com/Documentation/Components/RenderTech-DeferredLighting.html)により、その他の影も適用できるようです。


### 分かりやすいレンダリングの例

LightModeの違いによるレンダリングの結果は、以下のキャプチャが分かりやすいでしょう。

![cap.jpg](https://qiita-image-store.s3.amazonaws.com/0/5616/a6c2933c-b713-c399-b995-cd48c6228b5e.jpeg "cap.jpg")
*左の球体がサンプル。右は以前作った自作のファーシェーダ*

上側にあるライト（太陽みたいなアイコンのほう）が指向性ライト、左端にあるのが **スポットライト** です。

上記サンプルは、シェーダに少し細工をしてレンダリングした結果です。
ForwardBaseで一回（若干小さい、正常な球体）、ForwardAddでもう一回（若干大きい、上下が欠けた球体）レンダリングされているのが分かると思います。
ForwardAddでレンダリングする際に、 **モデルを法線方向に少しだけふくらませる処理** を入れています。

結果、スポットライトを使用したレンダリング（つまりForwardAdd）の場合は、光が当たっているところだけ、少しだけ膨らんだモデルがレンダリングされているのが分かると思います。

ドキュメントによると、ライトの数だけ`ForwardAdd`パスがレンダリングされるようです。
それを合成し、最終的なシーンをレンダリングしている、というわけですね。
なので、複数ライトを適用する場合は、シェーダ内で複数ライトを直接取得して合成するのではなく、各々のライト用のレンダリングが走るので、基本的にはひとつのライトだけを考慮してレンダリングすればいいわけです。
（これを理解するまでだいぶ色々悩んだ( ;´Д`)）

実際にこの状態でライトを増やしていくと、その分、照らされている領域がしっかりと明るくなるのが確認できます。
簡単に画像Aに画像Bを上書きする方法

画像Aに画像Bを上書きする方法についてです。
色んな方法がありますが、私が好きな方法を紹介します。


```html:hoge.html
<div class="relative">
  <img src="A.jpg">
  <img src="B.jpg" id="uwagaki">
</div>
```

画像Aと画像Bをdivでくるみます。

```css:hoge.css
#uwagaki {
	position: absolute;
	top:0;
	left:0;
}
.relative {
	position: relative;
}
```
次にcssでpositionをうまく使って、画像を重ねます。
画像Aと画像Bのサイズが同じ場合, これだけでピッタリと上書きさせることができます.


画像Bで**position:relative;**を使うと画像の分のスペースが空いてしまうので注意.

この方法は**bootstrap**で書いている場合でもちゃんと上書きしてくれます.
GoのTips4選

# mapやsliceはnilで返すと空だとみなされる
http://play.golang.org/p/veOWHGDdcn

# ローカル変数でimportしたパッケージを上書きできる
http://play.golang.org/p/SpwdLMan9P

これをうまくやっているのが[Testify](https://github.com/stretchr/testify#assert-package)


# 構造体を埋め込む場合、同じ名前のフィールドを定義すると上書きできる

http://play.golang.org/p/_ZCEUQGgrN


# golintでは引数でチェックするレベルを変えられる
```
package main

type Session struct {
	Url string
}

func (s *Session) Open() bool {
	return true
}

func main() {
	s := Session{"https://github.com/"}
	s.Open()
}
```

http://oinume.hatenablog.com/entry/golint-min-confidence
Rubyでミリ秒表記のUNIXTIMEを日付表記に変換する

timestampがms表記となっているものを、通常の時刻表記にRubyで変換したいときのTipsです。

ミリ秒は1000ミリ秒が1秒ですので、1000で割れば求められますね。
しかし整数演算とすると、ミリ秒が落ちてしまうため、1000.0で割ります。

```bash
$ pry
[1] pry(main)> time = 1412915400300
=> 1412915400300
[2] pry(main)> Time.at(time / 1000.0)
=> 2014-10-10 13:30:00 +0900
```

Time.at(time / 1000.0).strftime('%Y/%m/%d %H:%M:%S.%3N')
=> "2014/10/10 13:30:00.299"

任意のフォーマットで日時を求めるには次のコードが使えます。

```bash
$ pry
[1] pry(main)> time = 1412915400300
=> 1412915400300
[2] pry(main)> Time.at(time / 1000.0).strftime('%Y/%m/%d %H:%M:%S')
=> "2014/10/10 13:30:00"
[3] pry(main)> Time.at(time / 1000.0).strftime('%Y/%m/%d %H:%M:%S.%3N')
=> "2014/10/10 13:30:00.299"
```

> 参考情報
> %N: 秒の小数点以下。桁の指定がない場合は9桁 (ナノ秒)、%6N: マイクロ秒 (6桁)、%3N: ミリ秒 (3桁)


先ほどのコードでミリ秒精度でのフォーマットを指定すると.300ではなくが.299が返るため、次のコードを用いると良いでしょう。

```bash
$ pry
[1] pry(main)> time = 1412915400300
=> 1412915400300
[2] pry(main)> Time.at(time / 1000.0).instance_eval { '%s.%03d' % [strftime('%Y/%m/%d %H:%M:%S'), (usec / 1000.0).round] }
=> "2014/10/10 13:30:00.300"
```

ref. http://d.hatena.ne.jp/tetsuyai/20101029/1288354522
ビットコイン2.0 とは? Bitcoin 2.0 資料まとめ

以下に移行しました<br><a href="http://block-chain.jp/tech/bitcoin-2-0/" title="ビットコイン2.0 とは? Bitcoin 2.0 資料まとめ">ビットコイン2.0 とは? Bitcoin 2.0 資料まとめ</a>
NFSをマウントするとnobodyになる

NFSをマウントしたのだがownerがnobodyになる問題

/var/log/messages見るとこんなログが

```/var/log/messages
nfsidmap[18544]: nss_getpwnam: name 'webuser' not found in domain 'hogehoge'
```

nfsidmapのキャッシュをクリアすればいいらしい

```bash:
nfsidmap -v -c
```
Kobito の markdown データをコマンドラインからダンプする


Kobito（とりあえずバージョン 1.9.2）は、データを ~/Library/Kobito/Kobito.db にある Sqlite3 のデータベースに格納しています。スキーマが今後変わる可能性もありますが、とりあえず現バージョンで、有効な（削除されていない）markdown データを単純にカレントディレクトリにダンプしてみます。

~~~~bash:-
db=~/Library/Kobito/Kobito.db
echo "SELECT zkey FROM zitem WHERE zin_trash IS NULL;" |
  sqlite3 $db |
  while read key
  do
    echo "SELECT zraw_body FROM zitem WHERE zkey = '$key';" |
      sqlite3 $db > $key.md
  done
~~~~

記事ごとのデータは zitem テーブルに入っています。書き出しのファイル名には `zkey` フィールドを用いています。`zuuid` は UUID なので ID としてはこちらの方が良いかと思ったのですが、これ、公開された記事に対してサーバが振るもののようで、非公開の記事では NULL なんですよね。公開されたデータのみのダンプであれば、こちらでも良いかも。

何となく、現時点のテーブル定義を載せておきます。

~~~~sql:-
/* 記事を格納するテーブル */
CREATE TABLE ZITEM (
  Z_PK INTEGER PRIMARY KEY, /* DB 内での一意な ID */
  Z_ENT INTEGER,
  Z_OPT INTEGER,
  ZIN_TRASH INTEGER, /* 有効なデータは NULL, 捨てると 1 */
  ZPRIVATE INTEGER, /* ？ */
  ZTEAM INTEGER,
  ZCREATED_AT TIMESTAMP,
  ZPOSTED_AT TIMESTAMP,
  ZUPDATED_AT TIMESTAMP, /* ローカルでの更新日時？ */
  ZUPDATED_AT_ON_QIITA TIMESTAMP, /* QIITA 上での */
  ZBODY VARCHAR, /* HTML 化された body */
  ZKEY VARCHAR, /* 何か、ユニークそうなキー */
  ZLINKED_FILE VARCHAR,
  ZRAW_BODY VARCHAR, /* markdown の body */
  ZTITLE VARCHAR, /* タイトル */
  ZURL VARCHAR, /* 公開 URL */
  ZUUID VARCHAR /* 公開された記事に振られる UUID */
);
~~~~

では。

# 追記

Kobito 2.0 で、データベースファイルは ~/Library/Containers/com.qiita.Kobito//Data/Library/Kobito/Kobito.db へ移された模様。
Finderの英語フォルダを日本語で表示する方法


参考URL
http://hotolab.net/blog/mac_localize/

-

`/System/Library/CoreServices/SystemFolderLocalizations/Japanese.lproj/
`の中にある、`SystemFolderLocalizations.strings `を編集します。

ただ、`SystemFolderLocalizations.strings `は、plistというバイナリ形式で保存されているため、一旦xml形式に変換してからでないと編集ができないようです。

変換するには、ターミナルで`plutil `のコマンドを使います。
このコマンドは、Xcode を入れていると使えるコマンドになるようです。

```Terminal
$ which plutil
/usr/bin/plutil
```

-

変換 → 編集の手順になります。

まずは、対象ファイルまでの移動です。

```Terminal
$ cd /System/Library/CoreServices/SystemFolderLocalizations/ja.lproj/
```
Macのバージョンによっては、`ja.lproj`の所が、`Japanese.lproj`だったりするかもしれません。

xmlへの変換処理をしてVimで開きます。

```Terminal
$ sudo plutil -convert xml1 SystemFolderLocalizations.strings
$ sudo vi SystemFolderLocalizations.strings
```

```xml:Terminal
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Applications</key>
        <string>アプリケーション</string>
        <key>Compositions</key>
        <string>Compositions</string>

```
な感じの内容が表示されますので、

```Terminal
<key>Applications</key>
```
の所が、英語のフォルダ名

```Terminal
<string>Applications</string>
```
の所が、Finderに表示させる日本語名になります。

変更、又は追記をしましたら保存をして閉じます。

その後、plist形式に戻します。

```Terminal
$ sudo plutil -convert binary1 SystemFolderLocalizations.strings
```

最後に、日本語表示にさせたいフォルダまで移動して、フォルダ内に`.localized`というファイルを作ります。

ファイルの中身は何も記載しないで大丈夫です。

```Terminal
$ cd /日本語表示させたいフォルダ名/
$ touch .localized
```

これで、Finderを再起動させれば英語だったフォルダ名が日本語になっているとおもいます。
perl で ParseExcel を使うまで


cpanminusをインストール

```
$ brew install cpanminus
```

cpanm で Spreadsheet::ParseExcel をインストール

```
$ cpanm --sudo Spreadsheet::ParseExcel
```

CPANからのモジュールと聞いてて敬遠してたけど、インストールがかなり簡単になっててびっくりした。
文字列を簡単に base64 エンコードする

`openssl` コマンドを使用すれば、コマンドラインで簡単に base64 エンコード可能

```bash
echo -n "XXX" | openssl enc -e -base64
```

> 実行結果
> eHh4Cg==

**-d** でデコードも可能

```bash
echo 'eHh4Cg==' | openssl enc -d -base64
```

> 実行結果
> xxx
Windows で Vagrant の box の解凍に失敗する

こんな感じのメッセージが出てきて失敗する。
検証環境は Vagrant 1.6.5。

```
The box failed to unpackage properly. Please verify that the box
file you're trying to add is not corrupted and try again. The
output from attempting to unpackage (if any):
```

bsdtar.EXE が対応していない形式が多すぎるので、bsdtar で box を作り直したら成功するようにはなった。
コマンドプロンプトで metadata.json があるフォルダに移動して、以下のコマンドで作成。

```
C:\Temp\sample> PATH=C:\HashiCorp\Vagrant\embedded\bin;%PATH%
C:\Temp\sample> C:\HashiCorp\Vagrant\embedded\gnuwin32\bin\bsdtar.exe -cvzf ..\sample.box .
```

後は、出来上がった sample.box を vagrant add するといけるはず。
KVM上のWindowsとホストOSでフォルダを共有する。


[前回](http://qiita.com/knqyf263/items/d9576651bb9f84530351)でvagrant-kvmを使ってWindowsをセットアップしましたが、起動しただけでは共有フォルダが使えなかったので、Sambaでマウントするようにしました。
他にいい方法がある気がするので、誰か知ってる人教えてください。


#環境
- ホストOS
 - Ubuntu 14.04
- ゲストOS
 - Windows 7
- KVM
 - virsh 1.2.2
- Vagrant 1.6.5 
- vagrant-kvm 0.1.9
- Samba 4.1.6-Ubuntu

#前提条件
- 上記環境（他の環境では試してません）
- ホスト上でKVMのセットアップは完了している
- vagrant-kvmのセットアップは完了している。
- Windowsのセットアップは完了している。

#参考

- http://www.server-world.info/query?os=Ubuntu_14.04&p=samba
- [kvm qemuにて ゲストwindowsから　ホストsambaをマウントする](http://d.hatena.ne.jp/n9d/20110327/p1)

#構築方法
##Sambaの設定
Sambaをインストールします。

```console
$ sudo apt-get install samba
```

次に`smb.conf`の設定を行います。
許可するネットワークを追加します。
vagrantネットワークを使っている場合は192.168.123.0/24が割り当てられているのでそれを追加します。
最後の行に共有したいディレクトリの設定を書きます。
ディレクトリは環境に応じて変更して下さい。

```console:smb.conf
$ sudo vim /etc/samba/smb.conf
# 50行目：コメント解除しIPアドレスを追加
interfaces = 127.0.0.0/8 eth0 192.168.123.0/24

# 最終行：以下の設定を追加
[windows7]
   comment = windows7 sp1
   path = /home/hoge/Vagrant/Windows7
   guest ok = yes
   writeable = yes
```

##Windowsの設定
「Computer」を開いて「Map network drive」を選択します。
![kobito.1412930021.729449.png](https://qiita-image-store.s3.amazonaws.com/0/56222/52ea9d45-c1e5-6abd-11e1-189bc7c4782a.png "kobito.1412930021.729449.png")

そこでホストOSのIPアドレスと（今回は192.168.123.1）、先ほど指定した共有フォルダ名（windows7）を合わせてパスとします（¥¥192.168.123.1¥windows7）。
図では¥¥192.168.123.1¥win7sp1になっていますが気にしないでください。

![kobito.1412930669.997133.png](https://qiita-image-store.s3.amazonaws.com/0/56222/3020d1be-a229-109f-3165-eee27bf08403.png "kobito.1412930669.997133.png")

これで「Finish」を押せばマウントされます。


![kobito.1412931443.202001.png](https://qiita-image-store.s3.amazonaws.com/0/56222/29d8b16b-f699-8006-30ec-7ebdb21ac995.png "kobito.1412931443.202001.png")

今回はVagrantのディレクトリを指定したので、Vagrantfileが見えていればOKです。
Railsでhas_and_belongs_to_manyを利用したUIを作成する

昨日、[has_and_belongs_to_many を利用したモデルを作成](http://qiita.com/gotohiro55/items/6d075fd40058e7b56752)しました。
モデルを作ったはいいものの、ビュー／コントローラからの利用方法が分からず、またいろいろと調べたのでメモ。

## 画面

グループにユーザーを追加するUIを作ってみたので、その手順です。

![hbtm_group_edit.PNG](https://qiita-image-store.s3.amazonaws.com/0/45172/4505296e-6591-5972-56a7-ab130aa31d1f.png)

ひな形はscaffold_controllerで作成。

```
$ rails generate scaffold_controller user
$ rails generate scaffold_controller group
```

scaffold_controllerではモデルの項目がビューに反映されないので、そこは付け足しました。
以下、この状態からの変更点をメモ。

## ビュー

```erb:app/views/groups/_form.html.erb
  <div class="field">
    <strong>Users</strong>
    <ul>
    <% @users.each do |user| %>
      <li>
        <label>
          <% checked = user.groups.exists?(@group.id) ? true : false %>
          <%= f.check_box 'user_ids', { :name => 'group[user_ids][]', :checked => checked }, user.id, nil %>
          <%= user.name %>
        </label>
      </li>
    <% end %>
    </ul>
  </div>
```

入力フォームにユーザー選択のチェックボックスを追加。
`:name => 'group[user_ids][]'`としてユーザIDを配列で渡します。

## コントローラー

```rb:app/controllers/groups_controller.rb
  before_action :set_users, only: [:new, :edit]

  private 
    def set_users
      @users = User.all
    end

    def group_params
      p = params.require(:group).permit(:name, :description, :user_ids => [])
      p[:user_ids] = [] if p[:user_ids].nil?
      p
    end
```

パラメータ取得のメソッドを変更してuser_idsを受け取るようにします。
`p[:user_ids] = [] if p[:user_ids].nil?`の部分は、チェックボックスがひとつも選択されなかった場合に、すべてのユーザーをグループから削除するために追加してます。


以上。
これだけのことを調べるのに結構かかってしまった・・・


## 追記

後日試してみたところ、上記の方法は has_many :through のアソシエーションでも使えました。
`collection_singular_ids=ids` のメソッドが定義されるアソシエーションで使えるのかな？と思います。

[Active Recordの関連付け(アソシエーション)](https://github.com/hachi8833/docrails/blob/develop/guides/source/ja-JP/association_basics.md)
VirtualBox を Homebrew でインストールし直す


普通にインストールしていた VirtualBox を homebrew でインストールし直したくなったので、その手順を書いておきます。

## １．取っておいたパッケージファイルを使ってアンインストールします。

### 1-1. インストールしたパッケージファイルを ~/installed_packege ディレクトリにおいていましたので、それを使ってアンインストールします。

VirtualBox-4.3.10-93012-OSX.dmg をダブルクッリクして起動します。

![VirtualBox_ReInstall01.png](https://qiita-image-store.s3.amazonaws.com/0/46049/e405ebae-8c21-bdbd-df87-148bdee9c31d.png "VirtualBox_ReInstall01.png")


### 1-2. VirtualBox_uninstall.tool を使ってアンインストールします。

![VirtualBox_ReInstall02.png](https://qiita-image-store.s3.amazonaws.com/0/46049/2b705482-c1d7-040d-5c2f-83d7f0f9a77d.png "VirtualBox_ReInstall02.png")



### 1-3. しかし、そのまま実行しようとしても、「開発元が未確認のため開けません」と言われて、アンインストールできません。
![VirtualBox_ReInstall03.png](https://qiita-image-store.s3.amazonaws.com/0/46049/9f37cc63-4636-5923-ecf6-6869cc5c580e.png "VirtualBox_ReInstall03.png")





### 1-4. 右クリック --> 開く　を選択すると、アンインストールツールを実行できます。
WindowsからMacに移行してきて、間もないので、ここで少しつまりました。
分かると簡単ですね。

![VirtualBox_ReInstall04.png](https://qiita-image-store.s3.amazonaws.com/0/46049/5316c5e5-a2d5-2880-31d0-9d3b9ae8ae0a.png "VirtualBox_ReInstall04.png")




開くをクリックして、アンインストールします。

![VirtualBox_ReInstall04-01.png](https://qiita-image-store.s3.amazonaws.com/0/46049/9845b8bc-99b9-6e90-002c-675473967d56.png "VirtualBox_ReInstall04-01.png")



### 1-5. アンインストールしてもいいかを２回聞かれますので、Yes と入力
パスワードを聞かれるのでパスワードを入力すると、アンインストールされます。

![VirtualBox_ReInstall05.png](https://qiita-image-store.s3.amazonaws.com/0/46049/1bbaa3cd-122c-1af5-a0d6-e1c4f3f121d2.png "VirtualBox_ReInstall05.png")



![VirtualBox_ReInstall06.png](https://qiita-image-store.s3.amazonaws.com/0/46049/bdfe3af0-b39e-db7e-9f81-7e8f2e572bef.png "VirtualBox_ReInstall06.png")


ちゃんと「Yes」と入力せずに、「y」とか、「yes」と入力したら、アンインストールが中断されるので注意。

![VirtualBox_ReInstall07.png](https://qiita-image-store.s3.amazonaws.com/0/46049/ce05fff5-7c22-1022-bdd2-aafc41d61f76.png "VirtualBox_ReInstall07.png")

アンインストール完了です。
再起動すると完璧！


## 2. brew cask でインストールする

brew cask だとコマンド一発でインストールできるので楽ちんです。

```
$ brew cask install virtualbox
==> Downloading http://download.virtualbox.org/virtualbox/4.3.16/VirtualBox-4.3.16-95972-OSX.dmg
Already downloaded: /Library/Caches/Homebrew/virtualbox-4.3.16-95972.dmg
==> Running installer for virtualbox; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are ignored.
Password:
==> installer: Package name is Oracle VM VirtualBox
==> installer: Upgrading at base path /
==> installer: The upgrade was successful.
?  virtualbox installed to '/opt/homebrew-cask/Caskroom/virtualbox/4.3.16-95972' (4 files, 110M)
```

インストール途中で止まるときは、VirtualBoxの残骸がまだ残っている（一部のプロセスが動いている??)ので、再起動すると問題なくインストール出来ました。
GraphAPIをv1.0とv2.1で叩いて比較してみた

## 背景

GraphAPI2.0が2014/04/30に発表された（既にアプリ作ったらv2.1になるけど)。
GraphAPIのエンドポイントが変わるとアナウンスされているので、既存のAPIを叩いたときとの違いを見てみることにした。

GraphAPIのレスポンスヘッダに処理バージョンが載るので、これで確認する。
以下、httpclientでGraphAPI叩いた時の一例

```
#<HTTP::Message:0x00000002a30fa0
 @http_header=
  #<HTTP::Message::Headers:0x00000002a30f28
   ...
   @header_item=
    [["Facebook-API-Version", "v1.0"],

 以下略

```


## やったこと

rubyの[httpclient](https://github.com/nahi/httpclient)でエンドポイントを指定してGraphAPIを叩いた。
その時に使ったアクセストークンは以下。

 * v1.0の時に作成したアプリでOAuthして得たアクセストークン
 * v2.1で作成したアプリでOAuthして得たアクセストークン

叩いたAPIは、以下の2つ。

 * GET /me
 * POST /me/feed

## 結果

/meも/me/feedもレスポンスの違いはなかったので、/meだけについて記載。

##### v1.0の時に作成したアプリでOAuthして得たアクセストークンでAPIアクセス

| エンドポイント | 実際に叩かれたAPIバージョン | エンドポイント指定なしとの比較 |
|:--------:|:----:|:----:|
| /me      | v1.0 | ---- |
| /v1.0/me | v1.0 | なし |
| /v2.0/me | v2.0 | なし |
| /v2.1/me | v2.1 | なし |

##### v2.1で作成したアプリでOAuthして得たアクセストークンでAPIアクセス

| エンドポイント | 実際に叩かれたAPIバージョン | エンドポイント指定なしとの比較 |
|:--------:|:----:|:----:|
| /me      | v2.1 | ---- |
| /v1.0/me | v2.1 | なし |
| /v2.0/me | v2.1 | なし |
| /v2.1/me | v2.1 | なし |

## まとめ

* v1.0のアプリからAPIアクセスすると、指定したエンドポイントのAPIで処理される
* v2.1のアプリからAPIアクセスすると、指定したエンドポイントは無視されて、v2.1で処理される

アプリで上記2つのAPI使ってても、2015/04/30の切り変えで影響はなさそう。
他のAPIはぼちぼち見ていく。

## 参考
* [Facebook Graph API 2.0について#基本的な確認項目](http://qiita.com/hilotter/items/b88402505faeebbbce89#3-1)
[WIP] Work In Progress Pull Requestを簡単に進めるための npm module

# gitwip
[WIP PR の説明](http://qiita.com/a-suenami/items/129e09f8550f31e4c2da)
Work In Progress Pull Requestを進める上でコマンドいいソフトウェアがなかったので、自作した（空コミットをどれも扱っていない）。

## インストール方法

```
npm install -g gitwip
```

## 使い方

### git wip

`git wip -m "WIP" --fb feature-func` は下のコマンドと同じ

```
git checkout -b feature-func
git commit --allow-empty -m "WIP"
```

#### Help
```
% git-wip --help
Usage: git wip [options]

Options:
  -m, --message           commit message                [default: "wip"]
  --fb, --feature-branch  feature function branch name  [default: "wip"]
```

#### Example

```
% git wip --fb test
[test 8c0bbfc] wip
```

### git unwip

`git unwip --mb master --fb feature-func` は下のコマンドと同じ

```
git checkout master
git branch -D feature-func
```

#### Example

```
% git unwip --fb test
Your branch is up-to-date with 'origin/master'.
Deleted branch test (was 8c0bbfc).
```

#### Help
```
% git-unwip --help
Usage: git unwip [options]

Options:
  --fb, --feature-branch  feature function branch to be deleted  [default: "wip"]
  --mb, --merge-branch    branch to be merged                    [default: "master"]
```

## URL

- github : https://github.com/tamanyan/gitwip
- npm : https://www.npmjs.org/package/gitwip
要約：知らないと損するアプリ開発におけるStateMachineの活用法


はじめに
=========


「[知らないと損するアプリ開発におけるStateMachineの活用法](http://www.slideshare.net/mokemokechicken/statemachinefull)(SlideShare full版)」

![知らないと損するアプリ開発におけるStateMachineの活用法（full版）.png](https://qiita-image-store.s3.amazonaws.com/0/11124/080482f5-d60e-38f3-4ab1-6d6b02829bd1.png "知らないと損するアプリ開発におけるStateMachineの活用法（full版）.png")

という内容で[クラスメソッド & ゆめみ 合同勉強会 Developers.IO Meetup 09](http://dev.classmethod.jp/event/cm-and-yumemi-developers-io-meetup-09-report/)で発表させて頂きました。

これについての要点をまとめます。

内容
=====

StateMachineとは何か？
--------

StateMachineは簡単に言うとUMLの「状態図（ステートチャート）」の実装です。
状態図による分析・設計は、実は色々な分野で活用されていて、iOS/Android/WebApp などのクライアントアプリでは実は非常に有用なものなのです。

ただ、StateMachineの実装は真面目にやると大変です。

例えば、こんな単純な状態図でも

![知らないと損するアプリ開発におけるStateMachineの活用法_のコピー_pptx.png](https://qiita-image-store.s3.amazonaws.com/0/11124/15950b4b-f12a-e838-ed8a-63cfc64244b7.png "知らないと損するアプリ開発におけるStateMachineの活用法_のコピー_pptx.png")

真面目にJavaで実装すると300行以上になります。
https://gist.github.com/mokemokechicken/9eb89e3c69d7e97800ea
まあもちろん、実装方針とか言語的な行数傾向はありますが、意外と大変であると言えると思います。

StateMachine Generator
--------


そこで [State Machine Compiler(SMC)](http://smc.sourceforge.net/) というOSSを活用します。
これは、SMC用のDSLから状態図、StateMachineコードを生成してくれます。そして、この状態図とコードは意味的に同じであることが保証されます。従って **状態図を見れば**、 **StateMachineの膨大なコードを見る必要が無くなります**。

StateMachineのメリット
--------


このStateMachine Generatorのおかげで次のようなメリットが生まれます。

* ModelやViewControllerから複雑な非同期遷移ロジックはStateMachineに移せる。
* StateMachineは状態図と同じなので状態図を見ればコードを読む必要はない。ModelやViewControllerは単純なアクションのみ実装すればよいので、「状態図＋アクションコード」のみ人間は理解すれば良い。これは非常に可読性が高い。
* 状態遷移の変更にも非常に強く、コードの修正は局所的なもので済む。

この辺の詳細はスライドの方を参照してもらえればと思います。

SMCのWeb実行環境
--------


SMCは便利なのですが、Setupが少し面倒です(要Java, Graphviz）。
また、生成したコードとDSLの結びつきの管理が少し面倒です。

そこで、SMCの実行をWebから行えるようにして、更にソースコードにDSLが再現されたSMCのWebのURLを埋め込んでおくことでこれらの問題を解消できます。

この仕組みをDockerに詰め込んだものを配布しています。詳しくは下記の投稿を参考にしてください。
[State Machine CompilerのWebUI付きDockerコンテナの使い方](http://qiita.com/mokemokechicken/items/9f59bbb11eec2f30b524)

設計Tips
-------
StateMachineの設計時の注意事項です。

* 状態名は名詞にする（動詞にしない）
* 複合状態はなるべく作らない（状態数が爆発するので）
* １つのStateMachineは複数スレッドにまたがらない

などがあります。

さいごに
=====

以前作ったスライドとあわせてアプリ設計の3部作みたいになりました。
一つ目で言いたかったことの細かいことを２，３で書いたような感じです。

* [iOS/Androidアプリの３つの大事な設計方針](http://www.slideshare.net/mokemokechicken/iosandroid-32804491)
* [iOS/Androidアプリエンジニアが理解すべき「Model」の振る舞い](http://www.slideshare.net/mokemokechicken/iosandroidmodel)
* [知らないと損するアプリ開発におけるStateMachineの活用法](http://www.slideshare.net/mokemokechicken/statemachinefull)


興味のある方は時間のある時にでも見てみてください！
[MongoDB] HerokuでのRails4のプロジェクトで、MongoDB(MongoLab)を使う準備

# 事前に
[mongodbのインストールについてはこちら](http://qiita.com/tsumekoara/items/5c3596872c9578e760ea)

## 今回は
Rails4のプロジェクトにMongoDBを使いたい時の設定についてです。
mongoidを使います。

最終的にはHerokuに上げたいので、HerokuではMongoLabを使います。他にもMongoHQとかがあります。
HerokuでMongoを使うには、クレジットカードなどのアカウント認証が必要になりますが、概ね無料で使えます。
MongoLabでは約500MBが無料で使えます。


# Gemfile

```rb:Gemfile
# Mongo on Heroku
gem 'mongoid', '4.0.0.beta1'
gem "bson"
gem "moped", github: "mongoid/moped"
```

# config/mongoid.yml

```shell-session
$ rails generate mongoid:config
```

上記コマンドにより、config/mongoid.ymlが生成されます。
development, testの設定があるので、それをいじったりstagingやproductionの設定を追加します。


```rb:config/mongoid.yml
・
・
production:
  sessions:
    default:
      uri: <%= ENV['MONGOLAB_URI'] %>
・
・
```

# Railsプロジェクト

このままだと、ActiveRecordのmodelを作るとき、active_record:とprefixをつける必要がある。
Railsのデフォルト設定がmongodbを使う様になってしまっている。

```shell-session

$ rails generate acrive_record:model

(mongoの方は、rails g model hoge:integer でいける)
```

これだとActiveRecordを基本的に使いたい場合には不自由なので、
config/application.rbに

```rb

config.generators do |g|
  g.orm :active_record
end
```


このときmongoを使うモデルを作るときは

```shell-session

$ rails generate mongoid:model MODEL_NAME column_name:column_type
```

でOK。プレフィックスが要る。

# Modelの設定

MongoDBを使いたいモデルに書き書き

```rb:app/models/hoge.rb

class hoge
  include Mongoid::Document
  field :fuga_id, type: Integer
  field :time, type: Time
end
```

ダメな例

```rb:app/models/hoge.rb

class hoge
  include Mongoid::Document
  field :fuga_id, type: Integer,
  field :time, type: Time
end
end 
```

こんな感じでカンマがあるとエラります。syntax error

rails g mongoid:model user_id:integer とかやってくとカンマが入っちゃうので、属性の指定はコマンドではせず、あとからモデルに書き込むといいかも。（あいまいです）


# 参考



   * http://stackoverflow.com/questions/6372626/using-active-record-generators-after-mongoid-installation
   * http://mongoid.org/en/mongoid/
   * https://devcenter.heroku.com/articles/mongohq
[MongoDB] MongoDBを、Vagrant上のCentOS6.4にインストールして起動させる

# 10genリポジトリの追加

```vim:/etc/yum.repos.d/10gen.repo
[10gen]
name=10gen Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=0
```

# yumでインストール

```vim
$ yum install mongo-10gen-server.x86_64 mongo-10gen.x86_64 --enablerepo=10gen
---
・
・
・
Installed:
  mongo-10gen.x86_64 0:2.2.3-mongodb_1
  mongo-10gen-server.x86_64 0:2.2.3-mongodb_1         

Complete!
```

# mongodbの起動

```vim

$ /etc/init.d/mongod (もしくは service mongod start)

startStarting mongod: forked process: 13622
all output going to: /var/log/mongo/mongod.log
child process started successfully, parent exiting             [  OK  ]
```

## ログ出力先の設定がいる場合

以下のパラメーターをつける。

```
--dbpath /var/lib/mongodb
--logpath /var/log/mongodb.log
```

## 停止と再起動
```vim
$ service mongod stop
$ service mongod restart
```

# 自動起動の設定

```vim
$ sudo chkconfig mongod on
```

# よくあるエラー

## /var/log/mongodd.logがない場合

作ります。

```vim

$ sudo touch /var/log/mongodb.log

```

## /var/lib/mongodbがない場合

作ります。

```vim

$ sudo mkdir /var/lib/mongodb
```

## Failed global initialization: BadValue Invalid or no user locale set. Please ensure LANG and/or LC_* environment variables are set correctly.

一旦以下のコマンドで対応。

```rb
$ export LC_ALL=C
```



# Railsでの使い方

[Rails4のプロジェクトでMongoDB(MongoLab)を使う準備](http://qiita.com/tsumekoara/items/bdec6b22acf120c13b3b)
C# で型クラスもどき 習作

型クラスをインスタンスで表す「貧者の型クラス」方式だが、インスタンスを受け渡しする代わりに```new```で生成する。

C#は高階型が使えないので、実装型を型引数で渡しているが、すごく面倒なことになっている。

```csharp
public abstract class TypeClass<TC>
    where TC : TypeClass<TC>
{
}

public interface IValue<out TC, T>
    where TC : TypeClass<TC>
{
}

public abstract class Functor<TC> : TypeClass<TC>
    where TC : Functor<TC>
{
    public abstract IValue<TC, TOut> Map<TIn, TOut>(IValue<TC, TIn> m, Func<TIn, TOut> f);
}

public abstract class Monad<TC> : Functor<TC>
    where TC : Monad<TC>, new()
{
    public abstract IValue<TC, TOut> Unit<TOut>(TOut value);
    public abstract IValue<TC, TOut> Bind<TIn, TOut>(IValue<TC, TIn> m, Func<TIn, IValue<TC, TOut>> f);
    public override IValue<TC, TOut> Map<TIn, TOut>(IValue<TC, TIn> m, Func<TIn, TOut> f)
    {
        return Bind(m, x => Unit(f(x)));
    }

    public static MT Unit<T, MT>(T value)
        where MT : IValue<TC, T>
    {
        var instance = new TC();
        return (MT)instance.Unit(value);
    }

    public static MTOut Bind<T, TOut, MT, MTOut>(MT m, Func<T, MTOut> f)
        where MT : IValue<TC, T>
        where MTOut : IValue<TC, TOut>
    {
        var instance = new TC();
        return (MTOut)instance.Bind(m, x => f(x));
    }
}

public class Maybe<T> : IValue<Maybe, T>
{
    private readonly bool hasValue;
    private readonly T value;

    private Maybe()
    {
    }

    public Maybe(T value)
    {
        this.hasValue = true;
        this.value = value;
    }

    public bool HasValue { get { return hasValue; } }

    public T Value
    {
        get
        {
            if (!hasValue) throw new InvalidOperationException();
            return value;
        }
    }

    public static readonly Maybe<T> Nothing = new Maybe<T>();
}

public sealed class Maybe : Monad<Maybe>
{
    public static readonly Maybe Monad = new Maybe();

    public override IValue<Maybe, TOut> Unit<TOut>(TOut value)
    {
        return new Maybe<TOut>(value);
    }

    public override IValue<Maybe, TOut> Bind<TIn, TOut>(IValue<Maybe, TIn> m, Func<TIn, IValue<Maybe, TOut>> f)
    {
        var maybe = m as Maybe<TIn>;
        return (maybe.HasValue)
            ? f(maybe.Value)
            : Maybe<TOut>.Nothing;
    }
}
```
SwiftでUIBlurEffect、曇りガラスエフェクト実装してみた

SwiftでUIBlurEffectを実装してみた。

iOS7の登場と共に複数のライブラリが出現した。

* [iOS-blur](https://github.com/JagCesar/iOS-blur)
* [FXBlurView](https://github.com/nicklockwood/FXBlurView)
* [ios-realtimeblur](https://github.com/alexdrone/ios-realtimeblur)

iOS8では、動的にぼかしエフェクトを生成できるUIBlurEffectが追加されたため、今後はこれが主流になってくるだろう。

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/j/jeffsuke/20140714/20140714093118.png" alt="f:id:jeffsuke:20140714093118p:plain" title="f:id:jeffsuke:20140714093118p:plain" class="hatena-fotolife" itemprop="image"></span></p>


```objective-c:BlurEffectViewController.m
import UIKit

class BlurEffectViewController: UIViewController {

    @IBOutlet var image: UIImageView
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        addBlurEffect()
    }


    func addBlurEffect() {
        var effect = UIBlurEffect(style: UIBlurEffectStyle.Light);
        var effectView = UIVisualEffectView(effect: effect);
        let rect = UIScreen.mainScreen().applicationFrame
        effectView.frame = CGRectMake(0, 0, rect.width, rect.height / 3)
        
        view.addSubview(effectView);
    }
}
```
iOSの、画面遷移時のメモリリークが止まらなかった話

先日、画面遷移時にメモリが開放されず、徐々にメモリ利用率が上昇する現象に苦しまされた。
Instrumentsで調べてみても、リークは見られなかった。何が問題だったのか。それは`dispatch_after`を用いたループするアニメーションだった。

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/j/jeffsuke/20141002/20141002085323.png" alt="f:id:jeffsuke:20141002085323p:plain" title="f:id:jeffsuke:20141002085323p:plain" class="hatena-fotolife" itemprop="image"></span></p>

`dispatch_after`や、`NSRunLoop`、`NSTimer`等を用いてループ処理を実行していると、ownerとなるオブジェクトが解放されようとしても、これらのオブジェクトが強参照するために、解放されないようだ。

## 今回実装していた物
`UIImageView`のカスタムクラスの上に、`UIImage`が乗っており、`animationImages`と`NSTimer`によって、フェードイン・アウトするアニメーションの挙動を実装した。
参考：[iphone fading of images](http://stackoverflow.com/questions/5618964/iphone-fading-of-images)

<p><span itemscope itemtype="http://schema.org/Photograph"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/j/jeffsuke/20141002/20141002085957.gif" alt="f:id:jeffsuke:20141002085957g:plain" title="f:id:jeffsuke:20141002085957g:plain" class="hatena-fotolife" itemprop="image"></span></p>


## 元々の実装
これだと、ループが回り続け、ownerのオブジェクトは永遠に開放されない

```objc

NSTimer *timer = [NSTimer timerWithTimeInterval:4.0 
                                              target:self 
                                            selector:@selector(onTimer) 
                                            userInfo:nil 
                                             repeats:YES];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [timer fire];

```

## 対策後
NSTimerをpropertyとして持ち、Viewが消える時に、`invalidate`し、解放する必要がある。

```objc
@interface JSKSwipeViewController ()
@property (nonatomic) NSTimer *timer;
@end

@implementation JSKSwipeViewController
- (void)startAnimation
{
    _timer = [NSTimer timerWithTimeInterval:4.0
                                     target:self
                                   selector:@selector(onTimer)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    
    // stop animation and release
    [self.timer invalidate];
    self.timer = nil;
    
}
```
shell スクリプト自身の絶対パスや格納ディレクトリを求める（OS X でも）


この話題はさんざん出尽くしている感もありますが、自分用にワンライナー的にコピペできるものを模索していたので、備忘的にメモを残します。ターゲットは Bash です。

さて、まさるさんが「[Bashシェルスクリプトで自分の絶対パスを取得 | #eight](http://jinim.jp/archives/571)」において、readlink(1) の「-f, --canonicalize」オプションや「-e, --canonicalize-existing」オプションを使うと良いと言っているのでいきなり結論が出て話が終わってしまいそうなのですが、いかんせん Mac OS X の readlink(1) はショボくて「-f」「-e」オプションがありません。Python でも使えば簡単ですが、シェルで完結させたいですし、それでいて相対リンクにも対応させたいのです。さて困った。

仕方がないので、ショボい readlink(1) と dirname(1) を使いながらチマチマとリンクを辿って、本体が格納されているディレクトリを求めます。

~~~~bash:-
path="$0"
while true
do
	target="$(readlink "$path")"
	cd "$(dirname "$path")"
	if test -z "$target" # リンクが尽きたら終わり
	then
		break
	fi
	path="$target"
done
pwd --physical
~~~~

"cd" せずに辿る方が正しいのでしょうが、煩雑になってしまいワンライナーにならなさそうなのでやめました。これを一行につぶすと、以下のような感じでしょうか。

~~~~bash:-
p="$0";while true;do t="$(readlink "$p")";cd "$(dirname "$p")";test -z "$t"&&break||p="$t";done;pwd -P
~~~~

これを用いて、「シンボリックリンクから実行されるスクリプトの本体が存在するディレクトリを $PATH に含める」ことで機能をサブコマンドへ分割したいのであれば、以下のような記述ができるかと思います（今回は、実際にはこれがやりたかった）。

~~~~bash:-
export PATH="$(p="$0";while true;do t="$(readlink "$p")";cd "$(dirname "$p")";test -z "$t"&&break||p="$t";done;pwd -P)":"$PATH"
~~~~

スクリプトファイルの絶対パスを求めるのであれば、以下のようになります。

~~~~bash:-
self="$(p="$0";while true;do t="$(readlink "$p")";cd "$(dirname "$p")";test -z "$t"&&break||p="$t";done;echo "$(pwd -P)/$(basename "$p")")"
~~~~

ではまた。
Key-Valueデータをresourceで定義する

Androidアプリの初期データとして、Key-Value型で値を持ちたいというのはよくある事だと思います。

単純な文字列や配列であれば`Context#getString`や`Resources#getStringArray`などで取得すれば良い話ですが、Key-Value形式は中々良いやり方がなく以下の様にシングルトンなMapを作ってメモリに展開している実装をよく見ます。

```java
public final class DatatMap {
    private DataMap() {
    }

    public static final Map<String, Integer> ICON_MAP = new HashMap<String, Integer>() {
        {
            put("100", R.drawable.icon_100);
            put("200", R.drawable.icon_200);
            put("300", R.drawable.icon_300);
            put("400", R.drawable.icon_400);
        }
    };
}
```

特に問題はなさそうに見えますが、コードとデータはなるべくなら分離したい所です。
調べた所、以下の様にすれば簡単に実装する事ができます。

1. `res/raw/`に以下のフォーマットでデータを作成します。

```xml
<?xml version="1.0" encoding="utf-8"?>
<extras xmlns:android="http://schemas.android.com/apk/res/android">

    <extra
        android:name="mega"
        android:value="1000000" />

    <extra
        android:name="kilo"
        android:value="1000" />

</extras>
```

2. 以下のクラスを実装し`ResourcesAdditions.getResourcesExtras(getResources(), R.raw.extras)`といった形で使用します。

```java
public final class ResourcesAdditions {
 
    public static final String TAG_EXTRAS = "extras";
 
    private ResourcesAdditions() {
        // No instance
    }
 
    public static Bundle getResourcesExtras(Resources res, int resId) throws Resources.NotFoundException {
        return getResourcesExtras(res, TAG_EXTRAS, resId);
    }
 
    public static Bundle getResourcesExtras(Resources res, String rootTag,
                                            int resId) throws Resources.NotFoundException {
        XmlResourceParser parser = res.getXml(resId);
 
        int type;
        try {
            while ((type = parser.next()) != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT) {
                // Empty loop
            }
            if (type != XmlPullParser.START_TAG) {
                throw new XmlPullParserException("No start tag found");
            }
            if (!parser.getName().equals(rootTag)) {
                throw new XmlPullParserException("Unknown start tag. Should be '" + rootTag + "'");
            }
 
            final Bundle extras = new Bundle();
            res.parseBundleExtras(parser, extras);
 
            return extras;
 
        } catch (Exception e) {
            final Resources.NotFoundException nfe = new Resources.NotFoundException();
            nfe.initCause(e);
            throw nfe;
        }
    }
 
}
```

使い方は以下の様になります。

```java
Bundle bundle = ResourcesAdditions.getResourcesExtras(mResources, R.xml.extras);
assertEquals(4, bundle.size());
assertEquals(10, bundle.getInt("deca"));
assertEquals(100, bundle.getInt("hecto"));
assertEquals(1000, bundle.getInt("kilo"));
assertEquals(1000000, bundle.getInt("mega"));
```

この実装のメリットは読み込みの実装がAndroidに依存した形になっているので軽量な事、デメリットは大きなデータになるとGsonのdeserialization程には効率的に処理できないという点です。
軽量なデータセットであれば上記実装を検討しても良さそうな気がします。

### 参考

偉そうに書きましたが以下の記事の和訳となります。

[Lightweight key-value pairs for Android bundled reso...](https://plus.google.com/+CyrilMottier/posts/BktFSPadV15)
vagrant-kvmのセットアップ方法


Vagrantを便利に使っているのですが、VirtualBoxだけではなくてKVMでも利用したいと思ったらvagrant-kvmを見つけたので、セットアップ方法のメモ。
基本は以下のvagrant-kvmのページのREADME通りにやればよいのですが、よく読まずにやったら少しはまったので。

#環境
- ホストOS
 - Ubuntu 14.04
- KVM
 - virsh 1.2.2
- Vagrant 1.6.5 

#前提条件
- 上記環境
- ホスト上でKVMのセットアップは完了している

#参考にしたサイト
- [adrahon/vagrant-kvm](https://github.com/adrahon/vagrant-kvm)
- [KVM用仮想マシンをVagrantで手軽に作る](http://knowledge.sakura.ad.jp/tech/2535/)

#構築方法
##Vagrantのセットアップ
ホストOS上にVagrantをセットアップします。
Vagrantのサイトからダウンロードします。
https://www.vagrantup.com/downloads.html
今回はUbuntu14.04なので、LINUXのdebパッケージを落とします。

```shell-session
$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_x86_64.deb
$ sudo dpkg -i vagrant_1.6.5_x86_64.deb
Selecting previously unselected package vagrant.
(Reading database ... 60945 files and directories currently installed.)
Preparing to unpack vagrant_1.6.5_x86_64.deb ...
Unpacking vagrant (1:1.6.5) ...
Setting up vagrant (1:1.6.5) ...
$ vagrant version
Installed Version: 1.6.5
Latest Version: 1.6.5

You're running an up-to-date version of Vagrant!
```

##vagrant-kvmのセットアップ
INSTALL.mdに書いてあるように、vagrant-kvmはruby-libvirtを利用しているので、以下のパッケージを入れて上げる必要があります。
さらに、Ubuntuのバージョンの幾つかはAppArmorのカーネルにバグがあるので、`vagrant up`の時にpermission errorが発生してしまうそうです。
AppArmorはアプリごとにルールが設定できるセキュリティツールですが、今回はlibvirtに関してそれを無効にするように、とマニュアルに書いてありました。
私の環境下では`aa-complain`コマンドがなかったので不要かとは思ったのですが、一応入れた上で無効にしておきました（マニュアルでは無効とありますが、実際はcomplainは学習モードのようです）。

```shell-session
$ sudo apt-get install build-essential ruby2.0-dev libvirt-dev libxslt1-dev libxml2-dev
$ sudo apt-get install apparmor-profiles apparmor-utils
$ sudo aa-complain /usr/lib/libvirt/virt-aa-helper
```

あとはvagrant-kvmをvagrantコマンドからインストールすれば良いです。

```console
$ vagrant plugin install vagrant-kvm
（中略）
Installed the plugin 'vagrant-kvm (0.1.9)'!
```
Installedと出ていれば成功しています。

##vagrant-mutateのセットアップ
基本的にVirtualBoxのイメージでboxが配布されているので、そのままではkvmで起動できません。
そこで、vagrant-mutateを使うと楽に変換できます。

```console
$ vagrant plugin install vagrant-mutate
```

あとはmutateコマンドでboxをkvm用に変換することが出来ます。

```console
$ vagrant mutate [Box名] kvm
```

次回は実際にvagrant-kvmを使ってVMを起動してみたいと思います。
git branch一覧(remote含む)からhash値のみ抜き出す



``````bash
$ git branch -avv | grep -v HEAD | sed -e 's/.* \([0-9a-z]\{7\}\) .*/\1/g'
fc8ce46
892dc61
ab84992
8ba0bf7
94a397e
033c3f5
dad066e
3abfe58
`````
パーマカルチャーとプログラミング


先日パーマカルチャーというモノのお話を聞いた。
http://ja.wikipedia.org/wiki/%E3%83%91%E3%83%BC%E3%83%9E%E3%82%AB%E3%83%AB%E3%83%81%E3%83%A3%E3%83%BC
> エコロジカルデザイン・環境デザイン分野の用語であり、自然のエコシステムを参考にし、持続可能な建築や自己維持型の農業システムを取り入れ、社会や暮らしを変化させる総合的なデザイン科学概念[1][2]。
> ...
> 最初その言葉はパーマネント(permanent)とアグリカルチャー(agriculture)を組み合わせ「永続する農業」という意味が込められていた。
> ...
> パーマカルチャー、３つの倫理
> 地球に配慮する(Care for the earth) - 全ての生命システムが持続し繁栄できる状態を維持する。人間は地球の健康なしに繁栄できないのであり、これが最も基本の倫理である。
人びとに配慮する（Care for the people) - 人々が存続するために必要な資源を供給する。
余剰は分かち合い、消費と再生産には限度を設けよ（Set limits to consumption and reproduction, and redistribute surplus）- 健康な自然システムは、それぞれ生存に必要な要素を互いに供給しあっている。人類も同様のことができる。我々が各々らに必要なものを供給しあうことで、我々は上記の方針に必要な資源を確保する事ができる。
> ...

一つのものを特化させて価値を生産するのでは無くて、
それぞれの特性の把握、効率的な利用法、総合的なバランスや調和を見直すこと
が重要になっているというような感じの話だと思う。
パーマは永続化というような意味のパーマネントが語源っぽいけど、
パーマカルチャーはもうちょっと広い意味合いみたい。

リソース資源の節約については、プログラミングでは概念化されていて発展もしているので、
ある程度相補的に考えられるんじゃないかなと思った、
パターンとかを現実に適応する方法とか少し想像してみる。

・シングルトン（難しい公的手続などの最初の一歩を学習した人の成果を使い回すための免許制講師的な軽度の講座システム）
・イテレータ（誰かの散歩コースとタイミングを把握して連絡可能にしておき、タスク依頼の請負システム）

現実のリソースとプログラミング上のリソースはアクセスについてのコストが異なる。

・あえてプログラミングのオブジェクトにアクセスの制限を課してパターン化する
・プログラミングでリソースへのアクセスコストを計測する手法を作ってパターンを適用する
・現実でリソースのアクセス効率を改善する
・現実でリソースの効率を計測する、実例を分析（地域密着の意義・創造的リソースアクセス手法）

また、私的範囲ではプログラミングでパラメータがそこまで多くないことが多い。
多様なパラメータのバランスをとるとか特性を活かすみたいな設計についてはあまり考える機会が無い。

・総合的なデザインの設計を必要なモデルを組み合わせて設計するような設計の練習を考える（パーマカルチャーの建築は近いのかね）

間をとるとシミュレーションのプログラミングってコトなのかね。
プログラミングの話とするのは強引なのかな。
DataGridViewでデータ変更する際に特定の条件で確認ダイアログを表示し値を元に戻せるようにする

## やりたいこと
1. Flag1 が true → false に変更される場合に確認ダイアログを表示し、キャンセルならば Flag1 を true に戻したい。
2. 別のセルにフォーカスが移らなくても、チェックボックスのチェックが外された直後に確認ダイアログを表示したい。

## 概要
1. DataGridViewとデータクラスの間にUndo機能を提供するクラスを挟む。
2. CurrentCellDirtyStateChangedイベントで、CommitEditを呼ぶ。

## 実装
### データクラス
```csharp
public class Row
{
    public string Name { get; set; }
    public bool Flag1 { get; set; }
    public bool Flag2 { get; set; }
}
```

### Undo機能を提供するクラス
```csharp
public class RowViewModel
{
    Row raw;
    bool previousFlag1;

    public RowViewModel(Row raw)
    {
        this.raw = raw;
        this.previousFlag1 = this.raw.Flag1;
    }

    public string Name
    {
        get { return raw.Name;  }
        set { raw.Name = value; }
    }

    public bool Flag1
    {
        get { return raw.Flag1; }
        set
        {
            previousFlag1 = raw.Flag1;
            raw.Flag1 = value;
        }
    }

    public bool Flag2
    {
        get { return raw.Flag2; }
        set { raw.Flag2 = value; }
    }

    public bool Flag1_CanUndo()
    {
        return previousFlag1 && !raw.Flag1;
    }

    public void UndoFlag1()
    {
        raw.Flag1 = previousFlag1;
    }
}
```

### ヘルパー
```csharp
public class PocoHelper<T>
{
    // プロパティからプロパティ名を取得
    public static string GetName<TKey>(System.Linq.Expressions.Expression<Func<T, TKey>> e)
    {
        var member = (System.Linq.Expressions.MemberExpression)e.Body;
        return member.Member.Name;
    }
}
```

### フォーム
```csharp
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.AutoGenerateColumns = false;
        rowViewModelBindingSource.DataSource = Enumerable.Range(1, 5)
            .Select(i => new Row() { Name = "row" + i })
            .Select(x => new RowViewModel(x))
            .ToArray();
    }

    private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex < 0) return;

        var dgv = (DataGridView)sender;
        if (dgv.Columns[e.ColumnIndex].DataPropertyName == PocoHelper<RowViewModel>.GetName(x => x.Flag1))
        {
            var row = (RowViewModel)dgv.Rows[e.RowIndex].DataBoundItem;
            if (row.Flag1_CanUndo())
            {
                var msg = "Flag1 を true → false に変更して構いませんか？";
                if (MessageBox.Show(msg, "確認", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                {
                    row.UndoFlag1();
                    dgv.RefreshEdit();
                }
            }
        }
    }

    private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        var dgv = (DataGridView)sender;
        if (dgv.CurrentCell.OwningColumn.DataPropertyName == PocoHelper<RowViewModel>.GetName(x => x.Flag1))
        {
            dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }
}
```
もしUnityを学ぶためのスターターキットを作るとしたら

ゲームを作るためじゃなくてUnityの特性や操作を覚えるための（ド初心者に対してのハンズオンでも使える）スターターキット

案募集中

## スケール

これを回避するためのスケール小さくしたPrefab

<blockquote class="twitter-tweet" lang="ja"><p>Unityのrigidbodyの動きが何かモッサリしてると思ったら全体の大きさを調整しようの例 <a href="http://t.co/WRrVEwRG07">http://t.co/WRrVEwRG07</a></p>&mdash; 椿 (@tsubaki_t1) <a href="https://twitter.com/tsubaki_t1/status/519888645847650305">2014, 10月 8</a></blockquote>

## シーンオートセーブ

私もこの人種

<blockquote class="twitter-tweet" lang="ja"><p>IntelliJのオートセーブやGoogle Drive上のドキュメントオートセーブに慣れすぎて「変更したファイルをセーブする」という基本技能が退化したエンジニアの皆様</p>&mdash; 捨てられ艦 (@dolpen) <a href="https://twitter.com/dolpen/status/520449981988102144">2014, 10月 10</a></blockquote>

候補
[自動保存機能を少し改修、バックアップを半自動に](http://tsubakit1.hateblo.jp/entry/20140208/1391842215)

## スナップ

スナップ、頂点スナップなどをうまく活かせるような、シーンを作成。そのシーンを実際に操作してカスタマイズし操作感を覚える。
（つみきを積み上げていくような...）
Vimのカーソルの形状を変更したい

覚書きにまで

## Insertモードに変更した時、カーソルの形状を変更したい。
![0Kr5BHOf1n.gif](http://gifzo.net/0Kr5BHOf1n.gif)
こんな感じ

## 記述内容
```
" Insertモードのときカーソルの形状を変更
let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"
inoremap <Esc> <Esc>
```
Security and Design（for Google Play In-app Billing） の概要

# Security and Design

Google Play In-app Billing の Security and Design の概要を自分の理解のために日本語でまとめてみました。

http://developer.android.com/intl/ja/google/play/billing/billing_best_practices.html

## SSL署名チェックをサーバーでやる

[Android in-app-billing のデータが改ざんされていないかの検証](http://qiita.com/irxground/items/906593e03ff03f7f9c62)

[java - How do I verify Android In-app Billing with a server with Ruby? - Stack Overflow](http://stackoverflow.com/questions/5971031/how-do-i-verify-android-in-app-billing-with-a-server-with-ruby)

## 購入されたコンテンツを守る

* コンテンツフィードのような、real-time serviceを使うべき。そうすれば常に最新の状態に保てる。
* サーバーを使って購入されたコンテンツを配信すべき。

上記をやってるなら端末（のメモリやSDカード）に保存してもいいが、保存するなら暗号化すべき

## コードを難読化する

Proguardとか使って難読化すべき。
他にも以下のような対処もできる。

* 他のメソッドの中にメソッドを入れる
* StringをConstantsとしてまとめて定義せずにその時々で作成する
* Javaリフレクションでメソッドを実行する（メソッドの文字列実行）

[Javaリフレクションメモ(Hishidama's Java Reflection Memo)](http://www.ne.jp/asahi/hishidama/home/tech/java/reflection.html)

Proguardを使ってる場合は、以下の設定を追加しなければならない。
`-keep class com.android.vending.billing.**`

## サンプルコードは全て変更する

サンプルコードまんまだと攻撃者に見破られやすいので変更すべき。（処理の開始地点と終了地点とかね！）

## セキュアでランダムなワンタイムトークンを使う

セキュアでランダムなワンタイムトークンを使うことでリプレイ攻撃を防げる。
サーバーでワンタイムトークンの検証をするならサーバーでワンタイムトークンを生成して使うべき。

[第3回 悪意のある攻撃から身を守るには？ | Think IT（シンクイット）](http://thinkit.co.jp/article/839/1)

## developer payloadをセットする

ランダムでユニークなトークンをセットしてリクエストし、レスポンスで返ってきたトークンを検証すべき。またさらに用心するなら、そのトークンをセキュアなサーバーでも検証すべき。

## 商標や著作権違反に対抗する

[Trademark infringement - Android Developer Help](https://support.google.com/googleplay/android-developer/answer/141511?hl=en)
[Trademark infringement - Android Developer Help](https://support.google.com/googleplay/android-developer/answer/141511?hl=en)

## 購入コンテンツの取り消しを実装する

不正購入が判明した場合に購入コンテンツを取り消しできるようにすべき。

## Google Play Public Key を守る

悪意のあるユーザーから守るために、PublickKeyを素のままコードに記載すべきではない。
その変わり分割したりXOR暗号化とかして実際のキーを隠すべき。

[Javaで文字列の暗号化／複合化（※外部ライブラリを使わずに） - on the center line.](http://d.hatena.ne.jp/kenpoco/20080717/1216291915)

パブリックキー自体は秘匿情報を持ってないが、ハッカーによって簡単に他のキーに置き換えられたりしたら困るでしょ？（悪意のある開発者のパブリックキーに置き換えたアプリを不正に配布して売上をそいつに奪われたりするのを防ぐことができる）
AppleID-クレジットカードなし設定でAppStoreを利用する方法

##問題
AppStoreから通常のサインインをするとクレジットカード情報の入力が必須となってしまう。
これを回避したい場合に以下の方法が利用できる。

##方法

1.ブラウザからApple公式サイトにアクセスし、AppleIDを作成
2.AppStoreにiTunes Card/コードを使うからAppleIDにサインイン
3.その際、AppStore利用のための追加情報を入力を求められるが、
　クレジットカード情報なしが選べる。また、iTunesカードの情報は入力しなくてもよい。

2014/8/26 AppStore:バージョン 1.3 (201.7)で確認