OmniAICreator/Qiita-1.07M huggingface dataset:
LT資料 (第4回 コンテナ型仮想化の情報交換会＠東京)


* [第4回 コンテナ型仮想化の情報交換会＠東京](http://ct-study.connpass.com/event/7396/)
* 2014/09/06(土) 15時くらい

---

* @tukiyo3
* KVM
  * 主なサーバに使っています。パススルー機能に感動。
* docker
  * dockerhubにもりもりUPしてます。
* LXC
  * docker注目する前まで使っていました。
* vagrant
  * [Vagrantをvirtualboxからlxcに切り替えて超軽量仮想環境を手に入れよう](http://qiita.com/tukiyo3/items/16847c348f928fbf1654)

---

## Tips 1/5
## Vagrant

* 1.6.5 (2014/9/6)でCentOS7ゲストに対応されました。
  * それまではpluginを追加でインストールする必要があった。

---

## vagrant

* docker対応している様子
  * [providers](https://docs.vagrantup.com/v2/providers/)

---

## vagrantcloud

* `vagrant init chef/centos-7.0`
  * 従来はBOXのURLを指定する必要があった。
  * ダウンロードがはやくて良い。
  * イメージサイズがHPに載っていないのが欠点。

---

## Vagrant Share

* [boot2dockerでvagrant share使ってみた - Qiita](http://qiita.com/tukiyo3/items/bae62d1bd7cf3e973a49)

![docker.png](https://qiita-image-store.s3.amazonaws.com/0/25728/b0a295f0-8f1e-4c45-9574-e841db1b41be.png "docker.png")


---

## Tips 2/5 [Docker Hub](https://registry.hub.docker.com/repos/tukiyo3/)

* dockerhubにUPする手順
  * dockerhubにアカウント作成
  * docker login、docker pushするだけ
* docker login、docker pushするだけ
* 無料なのにプライバシーリポジトリがある(1つ)

---

* docker search tukiyo3

---

* 日本仕様にしたやつ
  * centos-ja
  * ubuntu-ja
  * ubuntu-debootstrap-ja
  * fedora-ja

* 作成時に使ったスクリプト
  * https://github.com/tukiyo/dockerimage-ja

---

* 最新版のdocker rpmを作れる
  * centos6-ja-rpmbuildenv
  * centos7-ja-rpmbuildenv

* Redmine的な
  * centos6-ja-alminium

* その他
  * asterisk11
  * centos7-ja-rails4-ruby2.0
  * centos6-ja-rails4-ruby2.1
  * owncloud7

---

## Tips 3/5 LXC

* virtmanager対応しているのでおすすめ。

---

## Tips 4.1/5 proxmox(OpenVz)

* proxmoxをここ2年間使ってきた。
* 別物理サーバに移動できるvzmigrateが便利。
  * 試しにwebサーバをproxmoxで動かしたがちょっとダメだった。
* debianにproxmoxインストール
* CentOS6にopenvzインストール

---

## Tips 5/5 proxmox(OpenVz)

* proxmoxを使うとそのままホストOS、ゲストOS間で通信ができます。

* 定時のバックアップが取れるのが便利。
  * 一時的にゲストOSをスリープさせて<br>再開させるときに失敗したことあり。
  * その場合、ゲストOSが停止したまま。

---

* [KVMゲストがホストのディレクトリをマウント - Qiita](http://qiita.com/tukiyo3/items/c72685b2a9c34442811e)
  * マウントタグを使ってホストのディレクトリを<br>ゲストからマウントできます。
  * イメージファイルのバックアップは<br>オンラインのままディスクイメージをコピーするだけ。

---

## docker tips 1
## centos7をdockerでsystemctlを動かす

    bash-4.2# systemctl
    Failed to get D-Bus connection: \
    No connection to service manager.

---

特権モードにする(--privileged)
コンテナで起動されるコマンドは/sbin/initにする

    sudo docker run --privileged -d -p 80:80 \
      --name httpd1 \
      tukiyo3/centos-ja:7.0 /sbin/init

nsenterを使用してコンテナに入る。

    sudo nsenter -t \
      $(sudo docker inspect \
        --format '{{.State.Pid}}' httpd1) \
       -m -u -i -n -p /bin/sh

これでsystemctlが使える。

---

## docker tips 2
## コンテナ起動で<br>サービス起動する

* 簡単な方法
* /.bashrc

---

## docker tips 3

dockerのデータ永続化はcronでcommitし続ければいい気がしてきた
コンテナを消さなければデータは消えないので

    docker commit -a "tukiyo3 <tukiyo3@gmail.com>" \
       e132e5667707 private/alminium

    docker export 13975 > alminium.tar

* 再起動後もコンテナを自動起動する

systemctlのservice書けば良い。

* [boot2dockerのデータ永続化まとめ - Qiita](http://qiita.com/tukiyo3/items/07f1eb77b5ffd9031e30)


---


ご清聴ありがとうございました。
SwiftでWKWebViewを使ってみた

# はじめに
iPhone6やiOS8の発表も目前に迫り、iPhoneユーザのみなさまにおかれましては胸躍る季節かと思います。
そういう僕もo(^-^)oワクワク・・・ こう言うときは勉強に意欲が出るものです。

今回はiOS8の新機能の一つとして、今までSafariに独占されていたWebkit Frameworkがアプリでも使えるようになったので本当に簡単ですがWebkit Framework呼び出してWebページを表示するまで試してみました。

ちなみに、初めてのSwiftです。…o(;-_-;)oドキドキ♪

# とにかく動かしてみる
今回は、Xcode6-Beta7を用いました、スクリーンショットはだめみたいなのでテキストだけでお届けします

## 手順
* Single View Applicationでプロジェクトを新規作成
* プロジェクト名は適当に決め、Languageは「swift」を選択
* ViewController.swiftにコードを書く

## ソース
僕が書いたコードは、番号が振ってあるコメント(「//1.WebKit Frameworkをimportする」など)部分のほんの数行です。というか・・・たったの７行ですね。。

```swift:ViewController.swift
import UIKit

//1.WebKit Frameworkをimportする
import WebKit 

class ViewController: UIViewController {

    //2.WKWebviewの宣言！
    var _webkitview: WKWebView? 
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //3.WebKitのインスタンス作成!
        self._webkitview = WKWebView()
        
        //4.ここでWebKitをviewに紐付け
        self.view = self._webkitview!

        //5.URL作って、表示させる！
        var url = NSURL(string:"http://www.yahoo.co.jp/")
        var req = NSURLRequest(URL:url)
        self._webkitview!.loadRequest(req)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
```
これで、ビルドして実行すると何もできませんがWebKitでWebページが表示されます！
変数宣言の"?"や、メソッド実行時の"!"などは、こちらのページで勉強させていただきました！

* [[Swift] Optional型についてのまとめ](http://qiita.com/cotrpepe/items/e30c7442733b93adf46a)

# 最後に
もちろんこのコードだけではアプリになりませんが、swift+Webkitでなんか楽しかったです。
iOS8が正式にリリースされたらベンチマークが公開されると思いますので楽しみにしています。
(個人的にはATOK for iOSが楽しみでなりません！)
【Rails】modelでboolean型の値をvalidationしたい。【ActiveRecord】

Ruby on Railsで開発していて、modelのバリデーションをする時に、

```rb
validates :hogehoge, presence: true
```

ってやると思うんだけど、それboolean型に対してやりたい時はどうするのって話。

例えば ```admin:boolean``` ってのがあるとして、

```rb
validates :admin, presence: true # コレだと admin == falseの時にエラーが出る。
```

コレだと admin == false の時にエラーを吐いてしまう。  



じゃあどうすればいいのかというと、 ```inclusion``` を使うらしい。

```rb
validates :admin, inclusion: {in: [true, false]}
```

これでOK！
EBSボリュームのフォーマットタイプを指定する(Opsworks)

今回は、OpsWorksのことをメモ代わりに書いていく。
OpsWorksでは、何も考えずStackを作成して、インスタンスを起動すると 追加したEBSボリュームは"XFS"でフォーマットを指定される。これをStackのCustom JSONを使うことで、任意のファイルシステムやRAIDを組むことができる。

[Custom JSON to Modify the Stack Configuration JSON](http://docs.aws.amazon.com/opsworks/latest/userguide/workingstacks-json.html)


DefaultでEBSボリュームを追加すると下記のように。
<em>
$df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/xvda1     ext4      7.8G  1.9G  5.8G  25% /
devtmpfs       devtmpfs  990M   60K  990M   1% /dev
tmpfs          tmpfs    1003M     0 1003M   0% /dev/shm
/dev/xvdi      xfs        10G   33M   10G   1% /root/volume
</em>

####Custom JSON を指定
```
{"ebs": {"devices": {"/dev/xvdi": {"fstype": "ext4"}}}}
```
<em>
$df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/xvda1     ext4      7.8G  1.9G  5.8G  25% /
devtmpfs       devtmpfs  990M   60K  990M   1% /dev
tmpfs          tmpfs    1003M     0 1003M   0% /dev/shm
/dev/xvdi      __ext4__       10G   35M   10G   1% /root/volume
</em>
また、RAIDを組むには

LayersでEBSボリュームをRAID構成にする。
例) DISK ×4 で RAID 10 を指定。
Mount point : /root/volume , RAID level : 10 , # Disks : 4 , Size total (GiB) : 40 , per disk (GiB) : 20.00 , Volume Type : standard

####Custom JSON を指定
```
{
  "ebs": {"raids": {
    "/dev/md0":{
      "fstype":"ext4",
      "mount_point":"/root/volume",
      "raid_level":10,
      "size":4,
      "disks":["/dev/xvdi","/dev/xvdj","/dev/xvdk","/dev/xvdl"]
      }
    }
  }
}
```
<em>
$df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/xvda1                    ext4      7.8G  1.9G  5.8G  25% /
devtmpfs                      devtmpfs  2.0G   84K  2.0G   1% /dev
tmpfs                         tmpfs     1.9G     0  1.9G   0% /dev/shm
__/dev/mapper/lvm--raid--0-lvm0__  ext4      40G   48M   38G   1% /root/volume
</em>

なお、現在のところOpsWorksではdevice point については /dev/xvdi,/dev/xvdj,/dev/xvdk ・・ /dev/xvdz と連番で自動的に振られるようだ。
そのため、たとえば最初から/dev/xvdzと指定するとそんなものないと怒られてエラーがでる。これは仕方ないのかな・・。
Atomのキーバインドを無効に(又は変更)する


# キーバインドを無効にする

パネルを移動する際にcmd-kとctrl-kを勘違いする癖が直らないんですが、勘違いしたままctrl-kを押すと気付かぬままにソースコードが消えていってしまいます。(実際は切り取りされているだけですが)

こういうキーバインドを無効にしたくなったときは、keymap.csonファイルを以下のように編集します。

```:keymap.cson
'editor':
	'ctrl-k': 'unset!'
```

# キーバインドを変更する
git-blameは、その名の通りAtom上でgit blameが表示できる素敵なパッケージです。

ただ、git-blameを使用するのにctrl-bを割り当てているため、カーソル移動のキーバインドが上書きされてしまっています。

カーソル移動は使いたいので、git-blameのキーバインドをalt-cmd-b変更しようというような時は以下のようにします。

```:keymap.cson
'.editor':
  'ctrl-b': 'unset!'
  'alt-cmd-b': 'git-blame:toggle'
```

`'alt-cmd-b': 'git-blame:toggle'`だけだと、alt-cmd-bのキーバインドが使えるようにはなりますが、ctrl-bのキーバインドは無効にならず、git-blameが実行されてしまいます。
はじめてのheroku

# heroku使ってみたけど結構めんどくさいのでメモ

## さいしょにやること

### ruby,rails,gitを入れる
バージョンはあとで書く

### Heroku Toolbeltを入れる
ターミナルでHerokuを扱うやつ
サイトにあるよ

```bash:login
$ heroku login
Enter your Heroku credentials.
Email:[Herokuに登録したメールアドレス]
Password:[Herokuのパスワード]
Could not find an existing public key.
Would you like to generate one? [Yn] Y
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
```

さいしょにやること ここまで

## アプリを作る
`rails new ` します

そのディレクトリに入り,

```bash
$ heroku create
$ git push heroku master
```
pushで結構長いのが出るけど`master -> master`って最後に書いてあれば成功.

**↑ここのやりかた違うかもしれない**

## アプリを確認する
ターミナルで

```bash
$ heroku open
```

でブラウザで開く.

データベースを使うとややこしいので今度書きます.
hubot cron設定


毎回忘れて調べるハメになるので備忘録的にメモ。

# 設定されているjobsを確認する
    hubot list jobs


# 不要なjobを削除する
    hubot remove job ID


# jobを作成する
## 前営業日の18:55に，明日の掃除当番はあなたですよ！と通知する
    hubot new job 55 18 * * 5 "月曜日の掃除当番は @foo @var です，よろしくお願いします(sun) "
    hubot new job 55 18 * * 1 "火曜日の掃除当番は @foo @var です，よろしくお願いします(sun) "
    hubot new job 55 18 * * 2 "水曜日の掃除当番は @foo @var です，よろしくお願いします(sun) "
    hubot new job 55 18 * * 3 "木曜日の掃除当番は @foo @var です，よろしくお願いします(sun) "
    hubot new job 55 18 * * 4 "金曜日の掃除当番は @foo @var です，よろしくお願いします(sun) "


## 水曜10時からのMTGをお知らせする
    hubot new job 59 9 * * 3 "@here Let's meeting!"
[メモ]node製REST APIモックツール

## 試してみたのは2つ

* [json-server](https://github.com/typicode/json-server "json-server")
* [node-easymock](https://github.com/CyberAgent/node-easymock "node-easymock")


## json-server

* json-serverの方がお手軽
* POSTしたデータはjsonファイルに追記される
* 好きなタイミングでjsonのスナップショットがとれる
* json-serverを利用したサービス、[JSONPlaceholder](http://jsonplaceholder.typicode.com/ "JSONPlaceholder") も便利
    * JSONPlaceholderは [Placehold.it](http://placehold.it/ "Placehold.it - Quick and simple image placeholders") 的な存在


## node-easymock

* node-easymockの方が高機能
* エラーのシミュレーション
* ログがとれる
* レスポンスヘッダが指定できる
* ドキュメントが出力できる
Githubにport:22 で push できなかった場合の対処法

VagrantのCentOS環境下で、originで指定したリモートへアクセスしようとしたところ、以下のようなエラーがでました。

```
$ git push -u origin master
ssh: connect to host github.com port 22: Connection timed out
fatal: The remote end hung up unexpectedly
```
<br />

そこで、公式のヘルプ
https://help.github.com/articles/using-ssh-over-the-https-port
にあるように Port:443 に接続してみます。

```
$ ssh -T -p 443 git@ssh.github.com
```

これだと接続できました。
次に、 Port:443 で接続するように設定ファイルを作ります。

```
$ vi ~/.ssh/config
```

```
Host github.com
    User git
    Hostname ssh.github.com
    Port 443
    IdentityFile ~/.ssh/id_rsa
```

identityFileはssh鍵のあるパスを指定します。そして、接続テストをします。

```
$ ssh -T git@github.com
```

ここで、接続できれば完了です。

<br />

もしかすると、こんなエラーが出るかもしれません。

```
Bad owner or permissions on /home/vagrant/.ssh/config
```

configファイルのアクセス権限に問題があるようなので、chmodコマンドを使って権限を書き換えます。

```
$ chmod 600 ~/.ssh/config
```

再度、接続テスト

```
$ ssh -T git@github.com
```

これで通りました。

<br /><br />

参考文献
https://help.github.com/articles/using-ssh-over-the-https-port
http://mattn.kaoriya.net/software/20081029172540.htm
http://futuremix.org/2005/10/openssh-config-permission
RSpecのfeature specにElasticseachを組み込む

Rails/RSpecでテストを書いていて、Elasticsearchを使った検索を盛り込んだテストを書く必要があったのでここにメモ。

動作環境:

- Ruby: 2.1.2p95
- Rails: 4.0.5
- RSpec: 3.0.4
- Elasticsearch: Version: 1.1.1

### 1) gem追加

これらのgemがないとそもそも無理っぽい

```rb
gem 'elasticsearch-rails'
gem 'elasticsearch-extensions'
```

### 2) spec_helper.rbにElasticsearchを使うときの処理を入れる

- Elasticsearchは（確か）デフォルトで9200のポートを使うので、テストでは別のポートを割り当ててテスト用のElasticsearchサーバを立てるようにする。

- 毎回Elasticsearchサーバが立ち上がるととても重たいので、`elasticsearch: true`のメタタグをつけたブロックのみで有効になるようにしている


/spec/spec_helper.rb

```rb
require 'elasticsearch/extensions/test/cluster'

Elasticsearch::Model.client = Elasticsearch::Client.new(host: "localhost:9250")

# other configs

# elasticsearch config
config.before(:each, elasticsearch: true) do
  unless Elasticsearch::Extensions::Test::Cluster.running?(on: 9250)
    Elasticsearch::Extensions::Test::Cluster.start port: 9250, nodes: 1
  end
  User.__elasticsearch__.create_index! force: true
  User.__elasticsearch__.refresh_index!
end
at_exit do
  if Elasticsearch::Extensions::Test::Cluster.running?(on: 9250)
    Elasticsearch::Extensions::Test::Cluster.stop port: 9250
  end
end
```

### 3) モデルスペックに検索のテストを追加

- あらかじめモデルのほうにはElasticsearchを使った検索時に:nameカラムがひっかかるようにしておく

- 以下のように、Userモデルでは:nameカラムでの検索が有効になることをテストする

/spec/models/user_spec.rb

```rb
let(:user) { create(:user) }

describe ':search_matching_user', elasticsearch: true do
  before do
    user.__elasticsearch__.index_document
    Elasticsearch::Model.client.indices.flush
  end

  context 'nameで検索できる' do
    let(:user) { create(:user, name: "John Doe") }
    subject { User.search_match_customer_organizations("John").records.to_a }

    it { is_expected.to eq [user] }
  end
end
```

こんな感じ。


これでElasticsearchを使った検索を含むfeatureテストも書けるようになる。
Elasticseachを噛ませたテストが走る際、テスト用のElasticsearchサーバが毎回立ち上がるので実行には多少時間がかかるで、多用するとテストが遅くなる。

```rb
it 'ユーザを登録してそのユーザを検索する', js: true, elasticsearch: true do
  visit new_user_path
  fill_in 'user_name', with: 'Foo Bar'
  fill_in 'user_email', with: 'foo@bar.com'
  click_button 'Submit'

  expect(page).to have_content('Foo Bar')
  expect(page).to have_content('foo@bar.com')

  fill_in 'input_search', with: 'Foo'
  find_button('Search').click

  expect(find(".user_name")).to have_content('Foo Bar')
  expect(find(".user_emai")).to have_content('foo@bar.com')
end
```


## ところで

[Repro株式会社](https://repro.io/)では一緒に切磋琢磨できる仲間を募集しています。 ぜひ[こちら](https://www.wantedly.com/companies/repro/projects)をごらんください！
rbenvで、-bash: rails: command not found


## はじめに

rbenvな環境で、「command not found」が発生したときの対応方法を記述します。

## 環境

* CentOS 7
* rbenv 0.4.0
* ruby 2.1.2p95
* rails 4.1.5

## rbenv rehashを実行する

```shell
$ rbenv rehash
```

__~/.rbenv/shims__ へrailsが作成され、railsコマンドが実行可能となる。

```shell
$ ls -l ~/.rbenv/shims/rails
-rwxrwxr-x. 1 admin admin 397 Sep  6 10:02 /home/admin/.rbenv/shims/rails
```

```shell
$ rails --version
Rails 4.1.5
```
## rbenvの仕組み

rubyなどのコマンドが実行されると、以下のような動作となります。

* 実行されたコマンドを環境変数PATHから検索する

* 環境変数PATHには、 __~/.rbenv/shims__が追加されているため、shims以下に作成されたコマンドと
同じ名前のスクリプトが実行される

```shell
echo $PATH
/path/to/user_home/.rbenv/shims:/path/to/user_home/.rbenv/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/path/to/user_home/bin
```

たとえば、rubyコマンドが実行された場合は、~/.rbenv/shims/rubyが実行されることになります。

```bash:~/.rbenv/shims/ruby
#!/usr/bin/env bash
set -e
[ -n "$RBENV_DEBUG" ] && set -x

program="${0##*/}"
if [ "$program" = "ruby" ]; then
  for arg; do
    case "$arg" in
    -e* | -- ) break ;;
    */* )
      if [ -f "$arg" ]; then
        export RBENV_DIR="${arg%/*}"
        break
      fi
      ;;
    esac
  done
fi

export RBENV_ROOT="/path/to/user_home/.rbenv"
exec "/path/to/user_home/.rbenv/libexec/rbenv" exec "$program" "$@"
```

* __~/.rbenv/shims/ruby__ からrbenvが実行される

* rbenvが、 __.ruby-version__ または __~/.rbenv/version__ により利用するRubyのバージョンを切替を行う

## まとめ

rbenvでは、gemを追加した場合は__rbenv shims__で、shims以下のスクリプトをメンテナンスする必要がある。

## 参考

* [`rbenv: rails: command not found`の対処方法](http://qiita.com/ikm/items/cdc7026059ed65fb109d)
* [rbenv rehashは何をやっているのか？](http://dqn.sakusakutto.jp/2014/02/rbenv_rehash_what_it_does.html)
* [rbenv](https://github.com/sstephenson/rbenv)
AnsibleのroleやTips

# 参考

* [Ansibleの事例とちょっとしたTips - Qiita](http://qiita.com/volanja/items/d38fe0678848bae6902f)
* [Ansibleちょっとしたメモ - Qiita](http://qiita.com/myaaaaa_chan/items/f3473ae27f8e1b2abcac)
* [ansible-playbook ワンライナー - Qiita](http://qiita.com/yamasaki-masahide/items/fa96225815869daa9e53)
* [ansibleで1ファイルのplaybookからroleに書き換える方法 - @znz blog](http://blog.n-z.jp/blog/2013-12-07-ansible-split-playbook.html)
* [Ansible 1.5リリース — そこはかとなく書くよん。](http://tdoc.info/blog/2014/03/01/ansible_1_5.html)

# sshのポートが22でない場合

* [Inventory — Ansible Documentation](http://docs.ansible.com/ansible/intro_inventory.html)

```bash:hosts
[web_all]
wwwsrv1 ansible_ssh_port=12345
```

# モジュール一覧表示

```bash:
ansible-doc -l
```

気になるモジュール

* locale_gen
* postgresql_db
* postgresql_privs
* postgresql_user


# serverの状態をチェック

```yml:書き方
- assert: { that: "ansible_os_family != 'RedHat'" }
```

```yml:書き方2
- assert: {
  that:
    "ansible_os_family != 'RedHat'"
  }
```

ansibleを実行すると、結果を`$?`で取得できる。
(正常終了: 0、異常終了: 1以上)


# role入門してみた

* run.sh
* main.yml
* vim/tasks/main.yml

というファイル構成の場合、

```yml:main.yml
---
- hosts: localhost
  sudo: yes
  roles:
    - role: vim
```

```yml:vim/tasks/main.yml
---
- name: install vim
  yum: name=vim state=latest
```

```bash:run.sh
test -z $(which ansible-playbook) && sudo yum install -y epel-release && sudo yum install -y ansible
ansible-playbook --diff -vv main.yml
```

# role入門2

* tasks,vars,handlersを使う

```yml:php/tasks/main.yml
---
- name: find {{ php_log }}
  stat: path={{ php_log }}
  register: result

- name: create {{ php_log }}
  file: path={{ php_log }} owner=apache group=apache mode=0644 state=touch
  when: not result.stat.exists

- name: install php5.6
  yum: pkg={{ item }} state=installed enablerepo=remi
  with_items:
    - php56
    - php56-php-devel
    - php56-php-mysqlnd
    - php56-php-mbstring
    - php56-php-gd
    - php56-php-cli
  notify:
    - restart httpd
```

```yml:php/handlers/main.yml
---
- name: restart httpd
  service: name=httpd state=restarted
```


```yml:php/vars/main.yml
---
php_log: /var/log/php.log
```

# role入門3 filesを使う

* php/files/php.ini を用意。

```yml:php/tasks/main.yml
- copy: >
    src=php.ini
    dest=/etc/php.ini
```

こういうふうに書ける。


# 行の追加(lineinfile)

```yml:os/tasks/main.yml
---
- name: CentOS6,7の名前解決高速化
  lineinfile: dest=/etc/resolv.conf line='options single-request-reopen'

- name: kernelが更新されてvirtualbox guest addinsが使えなくなることの対策
  lineinfile: dest=/etc/yum.conf line='exclude=kernel-[23]*'
```
ネットや書籍を使わずにjavascriptを学ぶ

この文章は、トロント行きの飛行機(フライト11時間)の中で、書籍もなくネットが一切使えなかった為、やむを得ずjavascriptの挙動を推測しながら書いてそれをまとめたものである。参考にしたのはcloneしてあったProtoBuf.jsやByteBuffer.js等の各種ライブラリのソースコード。

よって、間違っている部分が多々あるのでjavascriptについて知りたい人は参考にしないように。他の言語経験者がjavascriptを始めたとき、どういうミスを犯すか、思考過程を知る為のサンプルにはなるかもしれない。

javascriptについては、たまにjQueryを使ったりするくらいで言語そのものをちゃんと勉強した事は無かった。そろそろjavascirptを始めようとして、勉強をしようと思った次第である。クラスベースのオブジェクト指向言語は経験済み。

# javascriptにおけるオブジェクト #
よくあるクラスベースのオブジェクト指向では入れ物(クラス)をを作ってから、それをnewすることでインスタンスが作られる。ギークハウス新丸子のY氏が、「たい焼き機はクラスで、たいやきはインスタンスなんだよ」という説明してくれていたっけ。

一方、javascirptにクラスは無く、プロトタイプベースのオブジェクト指向と呼ばれている。プロトタイプが何か、というのは良くわかっていない。ただ、各コードを読んでみた結果、よくあるPersonクラス相当のものを以下のように定義出来る事が分かった。

```
var Person = function(name, age) {
	this.name = name;
	this.age = age;
};

var one = new Person("Mikami", 27);
var two = new Person("Hoge", 50);

console.log(one.name);
console.log(one.age);
console.log(two.name);
console.log(two.age);
```

結果:

```
Mikami
27
Hoge
50
```

おお、それっぽく動作しているぞ！しかし、new Person(...)を実行したときには何が返っているのだろう？そもそも、Personにバインドされている関数は何も返していないし、この関数に何かをreturnさせてみても結果は変わらない。ここで推測したのが「newキーワード付きでPerson関数を呼び出すと、呼び出した関数を最後まで実行させたクロージャが返る」というものである。

上記が正しいかどうかを探る為、Personにバインドしているfunctionにおけるthisオブジェクトと、new実行後に作られるオブジェクトが一致しているかどうかを調べる。

調べたかったのだが、調べ方が分からない。オブジェクトid等があるならそれを取って比較したいのだが、Chromeのデバッガを使ってもそれらしき物は保持していない。だが、少なくとも、ルックアップテーブルのようなものにoneやtwoと言った変数が登録されていて、それらが別々のオブジェクトであれば参照しているポインタが別になっているはずである。

わからん。諦めよう。とりあえずこの先はさっきの仮定が正しいものとして進める。

# クラス相当のものを定義する場所 #

```
(function(global) {
	var Fuga = {};
	...
	global['Fuga'] = Fuga
})(this);
```

なんだこれ？この書き方をしているライブラリが幾つかある。1つ1つ解明してみよう。

## thisは何を指している？ ##
関数を定義せずにjavascriptのファイルでthisを使用した場合、それがWindowオブジェクトになることをChromeのデバッガで確認した。
さっきの書き方の意図は、どこからでも見えるWindowオブジェクトに新たにオブジェクトを追加して、どこからでも呼び出せるようにしたいのだと思う。

しかし、わざわざ関数を作ってWindowオブジェクトを渡し、それを実行するようになっている。それだと以下のように書くのと同じではないか？と思い、それを実行してみるとやはり同じ結果になった。

```
var Fuga = {};
...
this['Fuga'] = Fuga
```

## 名前の重複 ##

何故このような面倒臭い書き方をしてるのだろう。同じならいちいち関数を作らなくてもいいのに、と考えた。ただ、推測するに「この空間内でのthisは単なるクロージャである為、名前が重複する心配が無い」のでは無いか。

例：

```
var Person = function(name, age) {
	this.name = name;
	this.age = age;
};

...

var Adult = {};
var Person = {};

...

this['Adult'] = Adult;
```


良い例がさっぱり思いつかないが、既にグローバルで定義されている変数(Person)をローカル変数として使いたいけど、どこかで既に定義されてしまっている場合。推測するに、グローバルのスコープが有効にならないのが関数の中だけである為、このような書き方が定着したのではないか。

## 最後に ##
途中だが、電池が無くなって来たので仕上げに入る。トロントまであと6時間もあるし作りたい物は全く作れていないのだが...。

ネットや本を一切使わずにプログラミング言語を学ぶというのは挙動を推測する訓練になって良い。あと単純に楽しかった。あとでネットで調べて答え合わせをすることにする。

なお、内容についてはおよそ間違っていると思うので参考にしないように(重要)。
TypeScriptでmongoose と戦う日記 #2 ジェネリッククラスを継承したい

# はじめに
mongooseは、pluginという形でモデルに機能を追加する事が出来ます。
例えば以下のように記述する事で、userModelに新しくfindOrCreateというメソッドが生えます。

```ts:test1.ts
import mongoose = require('mongoose');
import Schema = mongoose.Schema;
import Document = mongoose.Document;
import Model = mongoose.Model;

interface UserDocument extends Document{
  name:String;
  age:Number;
}

var userSchema:Schema = new Schema({name:String, age:Number});
//プラグインをモデルに突き刺す
userSchema.plugin(require('mongoose-findorcreate'));

var userModel:Model<UserDocument> = <Model<UserDocument>>mongoose.model('User', userSchema);

//プラグインでモデルに追加したメソッドを呼ぶ
userModel.findOrCreate({},function(){}); //The property 'findOrCreate' does not exist on value of type 'mongoose.Model<UserDocument>'

```

ところが、当然ながらmongoose.d.tsで定義されているModelにはfindOrCreateメソッドが生えていないため、userModelで呼び出す事が出来ません。

外部モジュールの中で定義されたinterfaceは外から拡張できないようなので、これを呼べるようにするにはanyでモデルを受け取るか、Modelを継承したUserModelを作ればいいと考えました。
某リポジトリのmongoose.d.tsでは、Modelは以下のように定義されています。

```ts
export interface Model<T extends Document> {
    new(doc: Object): T;
    //いろいろ続く
    //…
}
```

受け取れる型をDocumentを継承した型に限定しています。なので継承してやればいいと思い以下のコードを書いてみたのですが、コンパイルエラーになりました。

```ts

interface UserModel<T extends Document> Model<T extends Document> {//'{' expected. ';' expected.
  findOrCreate(opt:{}, callback:Function):void;
}

```

# ジェネリッククラスの継承
先ほどの例ではどうやら構文解析に失敗しているようです。いろいろ調べてみたところ、ジェネリッククラスの継承には以下のような条件がある事が分かりました。

 * `interface B<T> extends A<T>`　のように、Tが何も継承していない時
 * `interface B<String> extends A<String>`　のように、型が定まっている時
     * この場合、`interface B extends A<String>`　というように継承する側の型は省略してよさげ

**Tが何かを継承しているとコンパイルにミスするみたい** です。理由はわからんです。

# いったん解決
で、今回の例ですが、UserModelはDocumentを継承したUserDocumentだけを受け取る事にしたいため、そのようにインターフェースを定義したうえで、以下のコードになりました。

```ts:test2.ts
//importやUserDocumentの宣言はtest1.tsと同じなので省略

interface UserModel extends Model<UserDocument> {
  findOrCreate(opt:{}, callback:Function):void;
}

mongoose.connect('localhost');

var userSchema:Schema = new Schema({name:String, age:Number});
userSchema.plugin(require('mongoose-findorcreate'));

var userModel:UserModel = <UserModel>mongoose.model('User', userSchema);

//モデルを新たに作る
userModel.findOrCreate({name: 'ORZNGO', age:17}, (err:any, doc:UserDocument, created:Boolean):void => {
  console.log(created);//true（作られた）
  userModel.findOrCreate({name: 'ORZNGO', age:17}, (err:any, doc:UserDocument, created:Boolean):void => {
    console.log(created);//false（既にあるので作られない）
  });
});

```

コンパイルとおりました。 **UserModelが複数の型を受け取れるようにする方法が未だに分かっていない気がします**が、いったん目的は果たせました。
既にドキュメントが存在する場合には作らない、というメソッドの挙動も確認できました。
補完にもきちんと出ています。やったぜ。
![スクリーンショット 2014-09-06 01.42.34.png](https://qiita-image-store.s3.amazonaws.com/0/40020/755e5d0b-808f-cb69-7543-11a275687208.png)
【感想】Androidアプリ開発パーフェクトマスター (Perfect master) 

まずここのサイトに記載に不適切かもしれないのと
タイトルに誤りをもたらしてしまうかもしれません。

まだ未発売ですが、何となくサイトをみた感じで書きます。
9/9発売なので、大きな書店では既に販売されているところもあるかもしれません。
技術書を中見ないで買う人は少ないと考えていますが、最近ネットやぱっと見て買う人もいると思うので書いてみました。

多分購入してもいいと感じる人は
* Android Studioをさわって開発したい
* 逆引きが欲しい
* イメージから入ると理解しやすい(コンソールとかの画面でなく、画面の挙動を見ていると楽しい人)
と考えます。

[Androidアプリ開発 パーフェクトマスター](http://www.shuwasystem.co.jp/products/7980html/4161.html)

著書のサイトで確認すると

>概要
>Androidスマホのアプリを開発したい。アプリを販売して儲けたい。アプリ開発を経験して将来プログラマになりたい。でも、プログラミングの知識はまったくない。そんなあなたでも大丈夫です。本書は、Androidアプリ開発に必要な「AndroidStudio」の使い方から、JavaやXMLの仕組み、アプリ開発の実際、アプリをストアに登録するまでをフルカラーの紙面でわかりやすく完全解説しています。あなたのひらめきを実装しましょう！

なんて素晴らしい謳い文句ですが、ここのサイトを利用しているようでしたらAndroidの開発にはある程度のJavaなどのオブジェクト指向のプログラミング知識が必要というのはわかると感じます。

>ページ数 992P

ページ数は大容量なのですが、目次を拝見させて頂くとそんな感じがしません。
Javaがコラムのような感じがします。
後、著書　金城俊哉さんのAmazonでの評価を確認すると逆引きのイメージが強い感じがしました。

そのため、初心者さんもプログラマーとかで勧める人もぜひ目次とか中が見られるなら確認してからのほうがいいかもしれません。

念のためですが、あくまで購入を否定する内容の意図ではありません。
きちんと吟味して購入しようという自分への意味もこめて書いておきます。
マルチタッチ

マルチタッチイベントを処理するには、onTouchesBegan(), onTouchesMoved(), onTouchesEnded() をオーバライドし、setTouchEnabled(true); でタッチイベントを有効にします。

ヘッダファイル：
> void onTouchesBegan(const std::vector &lt;cocos2d::Touch*&gt;& touches, cocos2d::Event  *event);
> 	void onTouchesMoved(const std::vector&lt;cocos2d::Touch**&gt;& touches, cocos2d::Event  *event);
> void onTouchesEnded(const std::vector&lt;cocos2d::Touch**&gt;& touches, cocos2d::Event  *event);

実装ファイル：
> bool GameLayer::init()
> {
> ：
> 　　setTouchEnabled(true);
> ：
> }
> void GameLayer::onTouchesBegan(const std::vector&lt;cocos2d::Touch*&gt;& touches, cocos2d::Event  *event)
> {
> ：
> }
> ：


サンプルのコードを読むと、タッチイベントリスナーを作り、それをディスパッチャーに登録していますが、単に setTouchEnabled(true); をコールするだけでも大丈夫のようです。

■ 追記

上記コードは 3.2 で動作することを確認しましたが、非推奨とのコメントを頂きましたので、タッチイベントリスナーを作りそれをディスパッチャーに登録するコードも以下に記述しておきます。

> bool GameLayer::init()
> {
> 　：
> 　//setTouchEnabled(true);  非推奨
> 　//	タッチイベントリスナー
> 　auto listener = EventListenerTouchAllAtOnce::create();
> 　listener->onTouchesBegan = CC_CALLBACK_2(GameLayer::onTouchesBegan, this);
> 　listener->onTouchesMoved = CC_CALLBACK_2(GameLayer::onTouchesMoved, this);
> 　listener->onTouchesEnded = CC_CALLBACK_2(GameLayer::onTouchesEnded, this);
> 　this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
　：
> }
VMWare Fusionにおける各ネットワークアダプタの挙動の違い



仮想化ソフトウェアによって差異がありそうだし、なにが正しいのか不明だけど、とりあえず確認できたことを記録しておく。以下は、VMWare Fusionで確認。

### 参考

* [ネットワーク設定 | VirtualBox Mania](http://vboxmania.net/content/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E8%A8%AD%E5%AE%9A)
* [[Vagrant] Vagrant で複数のVM を立ち上げて、お互いに通信できるようにするには [VirtualBox] - Qiita](http://qiita.com/sho7650/items/cf5a586713f0aec86dc0)
* [Vagrantのネットワーク周りのあれこれ | Septeni Engineers' Blog | セプテーニ エンジニアブログ](http://labs.septeni.co.jp/?p=966)

### NAT

* `ゲスト -> インターネット`のアクセスは可能
* ゲスト間の相互通信は不可
* `ホストからゲスト`は通常は不可
  * ポートフォワーディングを設定すれば可能
* `ゲストからホスト`は不可と思っていたけど、可能だった
  * 仮想化ソフトウェアがルーターの役割になり、ゲストとホストは同じ仮想ネットワークに所属するためみたい


### ホストオンリー

* `ゲスト -> インターネット`のアクセスは不可
* ゲスト間の相互通信は可能
* `ホストからゲスト`は未確認
* `ゲストからホスト`は可能と思っていたけど、不可だった

### ブリッジ

* ホストと同一のネットワークに参加する
  * なので、相互通信は通常のネットワークと同じように行う

### 以下、メモ

Vmwareの場合、vmnetという仮想NICが追加されており、vmnet1がホストオンリー用、vmnet8がNAT用として働く。
VirtualBoxの場合はvboxnetという名前で仮想NICがある。

例えば、HOSTマシンでifconfigを実行して以下になると、

>
vboxnet0: flags=8842&lt;BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        ether 0a:00:27:00:00:00 
vboxnet1: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        ether 0a:00:27:00:00:01 
        inet 192.168.33.1 netmask 0xffffff00 broadcast 192.168.33.255
vmnet1: flags=8863&lt;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        ether 00:50:56:c0:00:01 
        inet 172.16.127.1 netmask 0xffffff00 broadcast 172.16.127.255
vmnet8: flags=8863&lt;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
        ether 00:50:56:c0:00:08 
        inet 172.16.238.1 netmask 0xffffff00 broadcast 172.16.238.255

NATのインタフェースを持ったVMからは172.16.238.1でホストにアクセスできた。
新しいiTunes connectでのバイナリの提出方法

※修正
同じバージョンのバイナリをiTunesConnectに送信できない問題は、
バンドルバージョンだけ変更すればアップロードできました。
-修正ここまで-

iTunes connectのデザインが変わりました。
それにともなって、バイナリの提出方法も変わったようです。
少しハマったので共有します。


ちなみに僕の場合は、既存のアプリに新しいバージョンを登録して、
バイナリは未送信の状態の時に、iTunes connectのサイトが更新されました。
なので、新しいバージョンの文字情報は登録済でバイナリ提出直前です。

まず、Xcodeから、通常通りバイナリをOganaizerで送信します。

新しいiTunes connectのサイトで、
「Appの管理」→「該当のアプリ」と選択します。
ページの真ん中あたりに「ビルド」という項目があります。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/20605/d7384901-8bb6-29ba-0487-0d97c5069d1b.png)


左上に＋ボタンがあるので、クリックすると、先ほど提出したバイナリがでます。
（表示されるまでにしばらく時間がかかるみたいです）
該当のバイナリを選択します。
複数のバイナリを登録して、その中から一つ選択できます。
その際は、バージョンの数字を変える必要があるみたいです。
すでに送信済みのバージョンと同じバージョンでビルドして、
Oganaizerで送信するとエラーになりました。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/20605/a0d8f73a-a260-c6b6-22b4-33510a3214b6.png)


該当のバージョンを選択して、画面右上の「保存」ボタンをクリック。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/20605/62cd1fe4-4d01-b78b-bc8c-28604bcb2a6b.png)

保存すると、その隣の「レビュー審査のため〜」ボタンが有効になるのでクリック。
このあとは、以前のフローと同じでした。
pecoを使ったディレクトリ移動が思った以上に便利だった件


```bash:~/.zshrc
# C-jで下のディレクトリに移動する
function cddown_dir(){
com='$SHELL -c "ls -AF . | grep / "'
while [ $? = 0 ]
do
    cdir=`eval $com | peco`
    if [ $? = 0 ];then
        cd $cdir
        eval $com
    else
        break
    fi
done
zle reset-prompt
}
zle -N cddown_dir
bindkey '^j' cddown_dir
```
IntelチップでopenFrameworksのアドオンofxMltMapping2Dを使ったときのメモ

ノートPC(Mobile Intel 4 Series Express Chipset Family)でofxMltMapping2Dを使ったプロジェクションマッピングプのサンプルを作成したときのメモです。
※ ハマった所が中心です。

そもそもopenFrameworksを動かす人はちゃんとグラボの入ったPCを使うと思うので、このメモはほとんど役に立ちません(笑)


## 環境

以下の環境で動かしています。

- PC：Acer Aspire 1410

- GPU：Mobile Intel 4 Series Express Chipset Family

- OS：Windows 7 SP1 64bit

- 開発環境：Microsoft Visual Studio Express 2012


## ハマった所

##### FBOが作れない


ofFboのallocate関数でExceptionが発生し、プログラムが落ちてました。glGenFramebuffersを実行する時です。
いろいろと調べた結果、IntelチップではFramebuffer ObjectのExtentionの名前がGL_EXT_framebuffer_objectになっているということが分かりました。
ちなみに、NVIDIA系のグラボだとFramebuffer ObjectのExtention名はGL_ARB_framebuffer_objectです。
※ OpenGL周りのドライバ実装が古いんですかね？


これがどのような影響を及ぼすのかというと、ドライバからロードするFBO関連の関数名が変わってしまいます。具体的には、末尾に"EXT"が付きます。


glew.hにはEXTが付いている関数ポインタも宣言されているので問題ないのですが、ofFbo.cpp内のコードはすべてEXTが付いていないものになっています。
ですので、ビルドが通っていざ実行、、というときに関数がロードできなくてエラーになるわけです。



ということで、力技で関数名を変える修正を行いました(だって時間がなかったんだもの…)。

- glGenFramebuffers -> glGenFramebuffersEXT

- glBindFramebuffer -> glBindFramebufferEXT

- glGenRenderbuffers -> glGenRenderbuffersEXT

- glBindRenderbuffer -> glBindRenderbufferEXT

- glRenderbufferStorage -> glRenderbufferStorageEXT

- glFramebufferRenderbuffer -> glFramebufferRenderbufferEXT

- glFramebufferTexture2D -> glFramebufferTexture2DEXT

- glCheckFramebufferStatus -> glCheckFramebufferStatusEXT

- glDeleteFramebuffers -> glDeleteFramebuffersEXT



##### VBOでも似たような問題が発生


以下の修正を行いました。


- glewIsSupported("GL_ARB_vertex_array_object") -> glewIsSupported("GL_EXT_vertex_array_object")


##### マッピング用のポリゴンを生成する際、ポイント数を変えるとプログラムが落ちる


いきなりofxMltMapping2Dの話になります。
無事にビルドが通ってプログラムを実行し、マッピング用の2Dポリゴン(ポイント数を増やせるもの)を生成->ポイント数を変更とするとプログラムが落ちました。

落ちた箇所はshapes\ofxMtlMapping2DPolygon.cppの以下の部分です。

```ofxMltMapping2DPolygon.cpp

        for (int i=2; i <= 3; i++) {
            for (it=vertices.end(); it!=vertices.begin(); it--) {
                ofxMtlMapping2DVertex* vertex = *it;
                
                if (vertex->bIsOnAnEdge && vertex->edgeIndex == i) {
                    // We check this for the grids, so that we don't add the vertices forming the interior of the grid
                    polyline->addVertex(vertex->center.x, vertex->center.y);
                }
            }
        }
```

イテレータitをvertices.endから始めているため、最初の*itへの参照時にアクセスエラーとなります。なので、取り合えず

```ofxMltMapping2DPolygon.cpp(修正)
for (it=vertices.end(), it--; it!=vertices.begin(); it--) {
```
として回避しました。やっつけですが、落ちなくはなりました。
※ バグならちゃんとした修正入れてプルリクしろって話になりますが。。


## おわり

他はすんなり行けましたー
struct と enum で ビットフラグ管理 コピペ用


俺用コピペコードです。

``` c++:flag_copiper.h

using ub4 = unsigned long  int  ;
#define bit_set(target,mask)    ((target) |=  (mask))
#define bit_clear(target,mask)  ((target) &= ~(mask))
#define bit_check(target,mask)  ((target) &   (mask))

struct copipe_flag_t
{
    ub4 md;

    copipe_flag_t() :
        md( 0 ) // 必要に応じて初期設定
    {}

    enum : ub4
    {
        view_on         = 1 <<  0, // 可視、非表示フラグ
        Reserved_01_bit = 1 <<  1,
        Reserved_02_bit = 1 <<  2,
        Reserved_03_bit = 1 <<  3,
        Reserved_04_bit = 1 <<  4,
        Reserved_05_bit = 1 <<  5,
        Reserved_06_bit = 1 <<  6,
        Reserved_07_bit = 1 <<  7,

        Reserved_08_bit = 1 <<  8,
        Reserved_09_bit = 1 <<  9,
        Reserved_10_bit = 1 << 10,
        Reserved_11_bit = 1 << 11,
        Reserved_12_bit = 1 << 12,
        Reserved_13_bit = 1 << 13,
        Reserved_14_bit = 1 << 14,
        Reserved_15_bit = 1 << 15,

        Reserved_16_bit = 1 << 16,
        Reserved_17_bit = 1 << 17,
        Reserved_18_bit = 1 << 18,
        Reserved_19_bit = 1 << 19,
        Reserved_20_bit = 1 << 20,
        Reserved_21_bit = 1 << 21,
        Reserved_22_bit = 1 << 22,
        Reserved_23_bit = 1 << 23,

        Reserved_24_bit = 1 << 24,
        Reserved_25_bit = 1 << 25,
        Reserved_26_bit = 1 << 26,
        Reserved_27_bit = 1 << 27,
        Reserved_28_bit = 1 << 28,
        Reserved_29_bit = 1 << 29,
        Reserved_30_bit = 1 << 30,
        Reserved_31_bit = 1 << 31,
    };
    
    // 必要に応じて追加
    inline bool check_view_on () { return !!bit_check ( md, view_on ); }
    inline void clear_view_on () {          bit_clear ( md, view_on ); }
    inline void   set_view_on () {          bit_set   ( md, view_on ); }
};

```
[毒]めんどくさいのはだいきらいだ。


いやー、さすがにdelegate書くのにtypoとかしないよね、コード補完使わない人は別としてさ。閑話休題。

ちょっと定数のこと検索してたら、いろいろ微妙だった。

##定数をconstで記述するのに、hファイルとmファイルの両方に書くとかね

「なんで、ふたつもファイルをメンテせにゃならんのか」
「ひとつでじゅうぶんですよ」

よく理由として、defineマクロを使うとー誤って再定義しちゃうーとか、ガイドラインではそうなってないよーという御仁もいらっしゃるが、

「えっとー、ローカル定数ならー、どっかに別の定義があるかもしれないけどー、近場で再定義できたほうが実は便利なんじゃね？」

ローカル定数はmファイルにdefineマクロで十分かなー？
もっとも、ローカルなら、mファイルだけに定義と宣言と両方書いちゃえばいいのかもねー。（それでも2箇所メンテしたくない）


##で、グローバル定数がまためんどい
まー、そもそもグローバルな定数がたくさん必要とされるところは、大規模開発でー拝承でーウォーターフォールでー共通ヘッダいぱーいな感じのとか。　※個人の偏見です

そもそもグローバル変数で定数をつくると、いくらがんばってプレフィックスをつけたとしても、他とかぶっちゃうケースを避ける物理的拘束力がどこにもないんだよねー。
そもそも、名前が被ったとき、コンパイルとおらない問題になるわけで、ライブラリの場合、なおそうにも手が届かないとか。という感じで色々と問題はありーの。

結局、共通ヘッダにdefineしたほうが、総コスト的に無駄がない気がしますな。プリコンパイルヘッダで強制してやれば、個々にimport書かなくていいし。

#enumとかそのた
まあ、数値定数も文字列定数もconstとかenumとか、やたら記述が複雑で、いやになりませんか？そうですか。全部手に覚えさせますか。snippetがあるからいいんだ。そうですか。

まー、なんだ。こういうめんどくささは、ジョブズ的なシンプルの杖をふるう場合、駆逐されるべきだと思いませんか。

#「書き方はひとつ。そうdefineならね」
[ObjC]文字列だらけでも別にいいんじゃない？



少なくとも文字列は、共通ヘッダにdefineで定義してやるのが前提。プリコンパイルヘッダにその共通ヘッダを書いておけば、全体でサジェスト機能が使えるし、少なくとも打ち間違いのミスは、ほぼ無くなるだろう。

ただ、それでもリファクタは動かないんだよなー（仕様に基いてヘッダを作っているウォーターフォールなプロジェクトであれば、その辺の問題は出ようがないでしょうが、あいぽんの開発現場はもっとアジャイルなんじゃろかね）。

まあ、Objective-Cでは、文字列によるリフレクションが有るってことで、疎結合にしたければ、文字列使ってやっといてよ、ってことなんだろうな、と思います、ハイ。

まあ、そうは言ってもその恩恵に預かるほどの大規模開発ってあるんだろうか……
【ObjC】インスタンス変数をどう記述するか

個人的なメモです。

##結論
・プロパティにインスタンス変数が必要な場合（セッタ、ゲッタを自分で記述する場合）、そのプレフィックスにはアンダースコアを使う。
・通常利用するインスタンス変数は外部からの隠蔽するため、実装ファイルで宣言すると良い（ヘッダ記述は非トレンドである）。

##理由
1.アップルのCocoaコーディングガイドライン（2012改訂）に、前アンスコを使いなさいよと書かれている。基本的にはこれでFA。
（荻原OBJ-C本では逆のことが書いてあるが、ここは素直にAppleに従う）

2.個別にセッタ/ゲッタを記述する際に、`インスタンス変数を直接返したり変更したりする`場合があり、プロパティとは明示的に記述が異なっていたほうが、ソース上で判別しやすい。

3.KVC整合性がある。一貫性大事。

##その他
セッタ、ゲッタを自作しない場合、インスタンス変数自体記述不要。すべてプロパティアクセスでよしとす。ｶﾞｶﾞﾝﾄｽ

ローカル変数まで長ったらしくすると、却って「これプロパティなの？メソッドなの？ローカル変数なの？」っていうのが瞬時に判りにくくなるので、ローカル変数はめっちゃショートハンドで別にいいんじゃないかなって思う。

いじょ。
[iOS]ストーリーボードでマルチタップの優先度を設定したい



このメソッド、UIViewControllerのカテゴリに仕込むと幸せになれます。要するに「数の多いタップジェスチャを先に処理する」ように設定するものです。
この処理が必要なストーリーボードのviewDidLoadメソッドで`[self tapPriolityChange];`のように呼んでおけばオシマイ。

Objective-Cの良さって、Objectのpropertyの値でソートします、みたいなのがまあまあ簡単に書けちゃうところにあるんだよね、的な。それにしても、この書き方、色々なところで応用できそうですね。

//ストーリーボードで生成したtapジェスチャで複数回タップを優先処理させるための設定を行うための初期化メソッド

```objectivec:code

-(void)tapPriolityChange
{
    NSMutableArray *sorting = [NSMutableArray new];
    NSSortDescriptor *tapsSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self.numberOfTapsRequired" ascending:YES];
    NSArray *grs = [[self view]gestureRecognizers];//viewに設定されているジェスチャーレコグナイザの配列を取り出す。
    if (!sorting || !tapsSortDescriptor || !grs)//データが揃ってなければ終了
    {
        sorting = nil; tapsSortDescriptor = nil; grs = nil;
        return;
    }
    for ( id gr in  grs )//高速列挙にて、UITapGestureRecognizerのみを取り出す
    {
        if([gr isMemberOfClass:[UITapGestureRecognizer class]])
        {
            [sorting addObject:(UITapGestureRecognizer*)gr];
        }
    }
    NSArray *sortedGrs = [sorting sortedArrayUsingDescriptors:@[tapsSortDescriptor]];//Tap数でascendソートした結果をsortedGrsへ
    if (sortedGrs && sortedGrs.count > 1)//タップジェスチャーが複数ある場合だけ優先度を付ける。ascendソート済みなので、後ろのものが優先されるように設定する
    {
        for (int i = 1; i < sortedGrs.count; i++)
        {
            [(UITapGestureRecognizer*)sortedGrs[i-1] requireGestureRecognizerToFail:(UIGestureRecognizer *)sortedGrs[i]];
        }
    }
    sorting =nil; tapsSortDescriptor = nil; grs = nil; sortedGrs = nil;
    return;
}
```
[iOS]ローカライズで重要な、複数の単語の順序を入れ替える方法


NSLocalizedStringはC関数なので大括弧不要

```Source.m
msg = [NSString stringWithFormat:NSLocalizedString(@"%@ is deleted by %@", @"") , var1, var2];

//var1は削除対象、var2は削除者を指す
```


```localized.String

"%@ is deleted by %@" = "%2$@ によって %1$@ が削除されました";
```

のようにすると、変数も正しく置換される。
appledocのインストール、わりと最新



`git clone git://github.com/tomaz/appledoc.git `

`sudo sh install-appledoc.sh -b /usr/bin -t default`

(/usr/local/bin がないのじゃ。Suck。)


インストールオプションには、テンプレートがどうとか、以下のような指定もあるが、よくわからないのでデフォルト。

`-t ~/Library/Application\ Support/appledoc`

OSX 10.9.4
Xcode5.1.1
appledoc version: 2.2 (build 963)

以上。っと思ったら、XCodeがGC非対応化になるので、製作者のバイナリを持ってきてインストールしてみた。

```
cd ~/Downloads/appledoc  (ex. ダウンロードして展開したappledoc.zipのパス)
cp appledoc /usr/bin
cp -Rf Templates/ ~/.appledoc

```

参照
http://qiita.com/kaz3439/items/21bd7dc60fb271b36fa3

https://github.com/tomaz/appledoc/releases/tag/v2.2-963
[iOS]ロケールを考慮した年月表示


```
    formatter.dateFormat = [NSDateFormatter dateFormatFromTemplate:@"yMMMM" options:0 locale:[NSLocale autoupdatingCurrentLocale]];
```

少なくともダイレクトにこれをラベル表示する場合これでFA。
和暦でも西暦でも、英語版もそのままでオーケー。
MMMMdにすれば月日もオーケー。
[iOS]Unwindの基本手順


1.以下のシグネチャを持つアクションメソッド
-(IBAction)nameUnwindActionForSegue:(UIStoryboardSegue*)segue;
を遷移先に記述する（このメソッドの引数segueは、遷移元のビューコントローラを持っているので、結果データ等を引き継げる。また、戻り値は設定する必要は無い）

2.ストーリーボードエディタ上で、遷移元のシーンのEXITを選択して、Connectionインスペクタにリスティングされた1.のアクションメソッドと、senderになるボタンやセル等をCtrl+ドラッグで結びつける（Actionと結びつける）。

ここまでで、任意のビューコントローラに戻っていくという遷移が実行される。

なお、遷移先にデータを渡したい場合、
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
が呼ばれ、segueからControllerが渡るので、そこで処理する。


もう一つの方法は、1.は同じ。
2’.遷移元シーンのExitを選択して、Connectionインスペクタにリスティングされた
1の遷移先アクションメソッドと、遷移元ビューコントローラを結びつける（Manual）。
3.遷移元シーンにUnwindセグエが表示されるので、IDを設定する。IDは遷移先を表現するものにしておく。
4.遷移元にセグエのトリガメソッドを設定する（面倒）その際、performSegueWithIdentifierメソッドには3のIDを記述する。
スニペット
- (IBAction)<#controllName#>Did<#Action#>:(id)sender
{
//    NSLog(@"%s %@",__func__, [sender description]);
    [self performSegueWithIdentifier:@"<#Identifier#>" sender:self];
}

Unwindセグエを使う際の一番の課題は、画面間のデータの受け渡しをどうするかとカスタムセグエが使いたい場合（表示面での）。
データについては個人的には、ユーザーデフォルトを用いて、辞書で渡しあうのが、おそらく、キー値コーディングらしく、もっとも疎結合になって、よろしいのではないかと考える次第だが（逆にID文字列の検索しづらさみたいなものもあるが…）、
そうでないのであれば、ViewController同士で受け渡しをしないといけないため、参照し合うめんどくささもある。

canPerformUnwindSegueActionは、遷移可能かどうかを返却するが特殊ケースでないと使わないかも。
[iOS]ストーリーボードとUIの色々メモ


やりたいことはすぐできるようにしたいっぽい。ぽいぽい。

##xcode5 ios7で全画面表示する

1.プロジェクトファイルのTARGETSのinfoタブからCustom iOS TargetPropertiesを開き、

`view controller-based status bar appearance キーにNOを設定`
RAWプロパティとしては以下。
`UIViewControllerBasedStatusBarAppearance`

2.プロジェクトファイルのTARGETSのGeneralタブからDeployment Infoを開き、
`Hide during application launchのチェックマークをONに設定`

これで没入も快適。

3.ストーリーボード上のルートビューコントローラのAttributeインスペクタで`Status Bar`と`Top Bar`を`None`に設定


* * *

##ナビゲーションバーは表示したくないが、pushセグエの動作は使いたい

ストーリーボードでナビゲーションコントローラを配置すると、まあなぜかテーブルビューコントローラもセットで付いてくる（テンプレだから仕方ないかもしれないが、ウザい）。しかしそれは削除して、ただのビューコントローラを遷移先に差し替えてもそれは全く問題ない。

なので、ナビゲーションバーを表示したくない場合でも、pushセグエを使いたければ、ここは黙してナビゲーションコントローラを使うのが良い。
**で、邪魔なナビゲーションバーを（非表示に）消してしまえば良い。ﾅﾝﾀﾞｯﾃｰ**
**これはストーリーボード上のナビゲーションビューコントローラのAttributeインスペクタで`Status Bar`と`Top Bar`を`None`に設定すれば良いだけで簡単。**

で、スワイプジェスチャとpushセグエ、Unwindセグエを結びつける。Unwindもそのまま使える。わざわざカスタムセグエを作ったりする必要も無く、某ニュースアプリみたいな動きができる、とてもナイスな感じで。
***
##ストーリーボードを、AppDelegateのコードでAddする
作成したストーリーボードは、コードで読み込んで生成することができる。生成するにはstoryboardWithName:bundleメソッドを使う。Nameについては、ストーリーボードのファイル名（.storyboardを含まない）を指定すれば良い（bundleの指定が必要なのは、通常とファイルの位置が違う場合。通常はnilでOK）

```Objective-C

- (BOOL)application:(UIApplication *)application
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UIStoryboard *sb =
        [UIStoryboard storyboardWithName:@"StoryboardName" bundle:nil];
    //ストーリーボードに設定されたイニシャルビューコントローラを取り出す。
    UIViewController *vc =
        [sb instantiateInitialViewController];
    //rootViewControllerをwindowに設定
    self.window.rootViewController = vc;
    //windowを表示
    [self.window makeKeyAndVisible];
    return YES;
}
```

分割した複数のストーリーボードをマージして使いたいときや、ストーリーボードを場合で使い分けたい等の場合、状況に応じたコードでストーリーボードを生成する。その際ビューコントローラも一緒に生成されるので、それを取り出してナビゲーションコントローラやタブビューコントローラ等にaddChildViewControllerしてやればよい。また、状況に応じて、生成するものを変えるとハッピー。

***

##UIPageViewControllerで、ページコントロールを表示する

Page-Based Applicationのテンプレートを使い、ModelContorllerに以下のコードを追加する。（UIPageViewControllerDataSourceプロトコルのデリゲートメソッド2つ）
たったこれだけで、iOSのアプリ選択画面のように、ページ遷移とページコントロールのドットが表示されるようになる。ﾅﾝﾀﾞｯﾃｰ

```Objective-C
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    return [self.pageData count];
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
    return 0;
}
```
***
Java 8 Lambda 性能測定

# 2014/09/07追伸

この記事は適切な記事ではありません。
詳細は、「[Java 8 Lambda 性能測定の再検証](http://qiita.com/sipadan2003/items/2104cfa796bf3501cbe5)」を参照してください。

# はじめに
巷ではJava 8のStream APIの性能測定で盛り上がっています。
でも、Stream APIの性能云々の前に、Lambdaの使用有無で性能がどのように異なるかを検証します。

# 性能測定

1～1,000,000の総和($\sum_{i=1}^n i$)を求めます（総和がオーバーフローしますが）。

1. 単純なfor文で総和を計算
2. 1をLambda経由で呼び出す

##プログラム

```java:Lambda1.java
public class Lambda1 {
    private static final int SIZE = 1_000_000;
 
    void process() {
        final IntConsumer c = i -> sum();
        //warming up
        for(int i=10000; i>0; i--){
            c.accept(0);
            sum();
        }
        //Call via lambda
        long start = System.nanoTime();
        for(int i=100; i>0; i--){
            c.accept(0);
        }
        long end = System.nanoTime();
        printResult("000", end - start);
        //Call directly
        start = System.nanoTime();
        for(int i=100; i>0; i--){
            sum();
        }
        end = System.nanoTime();
        printResult("001", end - start);
    }
 
    private int sum() {
        int sum = 0;
        for (int i = 0; i <= SIZE; i++) {
            sum += i;
        }
        return sum;
    }

    private void printResult(String prefix, long time) {
        System.err.println(prefix + ": elapsed=" + time / 1_000);
    }
 
    public static void main(String[] args) {
        new Lambda1().process();
    }
}
```

## 測定環境

| Key  | Value                                |
|:-----|:-------------------------------------|
| CPU  | Intel Core i7-2670QM CPU @ 2.20GHz コア数4 スレッド数8   |
| RAM  | 8GB                                  |
| OS   | Windows 7 Home Premium SP1 64ビット版|
| Java | Java SE 8 Update 20                  |

## ウォーミングアップありの測定結果

```
000: elapsed=9
001: elapsed=93259
```

## ウォーミングアップなしの測定結果

上のプログラムで、次のようにコメントを付けて、再度実行します。

```java:
        //warming up
//        for(int i=10000; i>0; i--){
//            c.accept(0);
//            sum();
//        }
```

結果は次のようになりました。

```
000: elapsed=149481
001: elapsed=113041
```

#まとめ
Lambdaをウォーミングアップすると、直接メソッドを呼び出すよりも、非常（異常）に高速になるようです。
vagrant upでconfigure_networks_default: wrong number of argumentsエラー

vagrant1.6.4でvagrant upしたらこんなエラーが出ました。

```
"configure_networks_default': wrong number of arguments (1 for 2)"
```

vagrant本体のバグだそうです。ver1.6.5で修正済みﾄﾉｺﾄ
https://github.com/mitchellh/vagrant/issues/4458
YAPC::Asia Tokyo 2014初参加の感想とメモ


# 初参加の感想

YAPCを知ったのは「半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情（5.6対応）」がはてブで話題になっていたこと。
参加を後押ししたのはRebuild.fmですね。perl以外の話も多い、miyagawaさんやnaoyaさんを見ることができそうだったので。Rebuild.fmの影響で参加した人は少なくないのでは？

どの発表も準備に時間がかかっている内容で、技術的に濃いもの、技術的戦略な話、エンジニアのキャリアについてなど様々でした。
特に印象的だったのはtypestarさんのキーノート。「自分が困っていることは、他人も困ってることがわりと多い」自分も欲しいなと思ったことが案外他人も同じ事を感じていることがあって、それに気づいたときモチベーションが一気に上がった経験があります。ものづくりを楽しく思えるときですね。「技術で人を幸せにしたい」これも共感。
エンジニアとして挑戦を続けながら今の生き方を見つけたtypestarさんは私のロールモデルの1人です。

次のYAPCも参加したい。

# 設備面で良かった点

無限コーヒー、ランチセッションの無料ランチ(1日目いただきました)、DMMかき氷ありがとうございました。

カンファレンス用に設立された無線LANはとても快適。また、どの部屋にも電源が完備されていたので、念のため買っておいたMBA用のモバイルバッテリーは不要でした。

# 気になった点

初日、初セッションから立ち見だったので、完全に会場のキャパオーバー。
あと多目的ホールはスクリーンが右側にあるため、左側にいる人はとても見えにくかったと思います。
会場を替えるか、サテライト中継で他の場所でも見られるようにすると良さそうですね。
必ず聴きたいセッションは1つ前のセッションから部屋に入って調整しました（笑）
IPython notebook サーバーを立ち上げる

[IPython notebook](http://ipython.org/ipython-doc/dev/notebook/index.html) を利用すると Web アプリケーションとして動作しブラウザのみで IPython の対話環境を使うことができるようになります。

サーバーサイドで IPython を起動しておけば良いだけなので、いくつかのメリットがあります。

* クライアントとなる計算機にブラウザ以外の特別なソフトウェアをインストールする必要がない
* (特に matplotlib で) 描画した図や表がインラインで表示される
* セッションを保存し、たとえばプレゼンテーションなどに利用することができる

このあたりは以前に書いた [IPython Notebook の使いどころ](http://qiita.com/ynakayama/items/72d744554f0454139c0f)の通りです。

IPython notebook では以下の画像のようにプロットした画像がすぐに表示されます。このため探索的にデータを分析していくような作業に向いています。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/38501/7ae3fbc5-133d-2da4-76f7-4d420b00598b.png)

## IPython notebook のサーバーを用意する

あらかじめサーバーサイドに[データ分析用のプログラミング言語環境を用意する](http://qiita.com/ynakayama/items/2a4d4802c93eb5c40eab)のが済んでいることを想定します。

### サーバー用のプロファイルを生成する

まずは次のコマンドを発行します。これによりホームディレクトリの .ipython ディレクトリに default とは別に nbserver というプロファイルが生成されます。

```bash
ipython profile create nbserver
```

こちらをサーバー用のプロファイルとしてカスタマイズしていきます。プロファイルは ~/.ipython/profile_[プロファイル名]/ ディレクトリの下に生成されます。ここの環境設定ファイルを編集することになります。

まず ipython_notebook_config.py に以下の設定を記述しておくと良いでしょう。

```py3
c.IPKernelApp.pylab = 'inline'
c.NotebookApp.ip = '*' # ローカルホスト以外からもアクセス可能にする
c.NotebookApp.open_browser = False # ブラウザが自動で開かないようにする
c.NotebookApp.port = 9999 # サーバーのポートを指定する
```

### IPython notebook サーバーを起動する

次のように IPython notebook サーバーを起動します。

```bash
ipython notebook --pylab inline --profile=nbserver &
```

サーバーの環境設定ファイルで指定したアドレスとポート番号にブラウザでアクセスすると IPython notebook の画面が開きます。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/38501/fdef8b0d-5149-4abc-bb91-d0d90464bf53.png)

### 初期化スクリプトを設定する

[IPython の豊富な機能を使いこなす](http://qiita.com/ynakayama/items/a159544f9d4c83d52cee)話で IPython のデフォルトの初期化スクリプトを作成しました。プロファイルが異なるので ~/.ipython/profile_nbserver/startup/ に初期化スクリプトを置きます。とはいえ基本的には同じ初期化スクリプトで良いでしょう。単純にコピーして適宜必要な設定を追記します。

### パスワードを設定してアクセス制限をする

このままですとどこからでも IPython notebook を利用できますが、アクセス制限をしたい場合も多いかと思います。そこでひとまずパスワードを設定しておきましょう。

IPython notebook の新規ノートから次のようにコードを叩きます。

```py3
from IPython.lib import passwd
passwd()
```

するとサーバーサイドのターミナル上にパスワードプロンプトが表示されますのでここで希望する新しいパスワードを入力します。結果はブラウザ上に sha1 暗号化されて表示されます。

あとは上の暗号化されたパスワードハッシュを環境設定ファイルに記載すればオッケーです。

```py3
c.NotebookApp.password = u'sha1:yourhashedpassword'
```

このあと IPython notebook を再起動すると次のようにパスワード入力画面が表示されます。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/38501/8cde0909-e4a9-d459-a340-1ad7fa9b7a21.png)

## まとめ

IPython notebook を使えばどこからでもブラウザで IPython が利用できるようになります。とはいえマジックコマンドを利用すれば OS にコマンドを発行出来てしまいますし、上記のパスワードによる保護も強固なものとは言えませんので、インターネットで不用意にサーバーを公開するのは危険が伴うことも忘れないようにしましょう。