OmniAICreator/Qiita-1.07M huggingface dataset:
PHPアプリのユーザIDをnginxのアクセスログに記録する方法

自分への備忘録を兼ねて。


# はじめに

ユーザに関する様々なデータを分析してサービス改善に役立てるというのは、サービスを提供する上でよくある方法です。
Webシステムの場合、いわゆるアクセスログを元にして改善点やユーザ動向を見つけることもあるでしょう。

ユーザ動向を把握するという意味では、サービスが管理するユーザIDをログに記録することで、どのユーザがどんな動き方をしたかを残しておくことができます。
Apache + mod_phpの環境であれば[apache_note](http://php.net/manual/ja/function.apache-note.php)を使ってPHPアプリケーションが管理するユーザIDをアクセスログに記録することができますが、nginx + php-fpm環境の場合はHTTPレスポンスヘッダを利用することで、比較的簡単にアクセスログに記録することができるようになります。
nginxでは特定のレスポンスヘッダをクライアントに送出しないようにすることもできますので、ユーザには見せたくない情報であってもログに残すことができます。


# PHPアプリケーションの実装

PHPアプリケーションでは、ログに残したい情報を普通にレスポンスヘッダとして送出するだけです。

### 例

```
$userId = 'アプリケーションが管理するユーザID';
header('X-APP-USER-ID: ' .$userId);
```


# nginxの設定

## ログフォーマットの設定

アクセスログに残したいレスポンスヘッダを変数としてログフォーマットに含めます。
この際、変数名に変換するには

* "upstream_http_"を接頭辞として付ける
* 大文字 -> 小文字に変換する
* ハイフンはアンダースコアに変換する

のルールで変換する必要があります。

### 例（送出したヘッダが"X-APP-USER-ID"の場合）

```
'$upstream_http_x_app_user_id'
```


## ユーザIDをクライアントに送出しない設定

送出したくないレスポンスヘッダのキーを以下の方法で指定します。

### fastcgiとして実行している場合

```
fastcgi_hide_header "X-APP-USER-ID";
```

### リバースプロキシを利用して実行している場合

```
proxy_hide_header X-APP-USER-ID;
```


# まとめ

PHPに限らず、システムが管理する情報をあまり手間を掛けずにアクセスログに残すことができれば、fluentdなどと組み合わせることで色々な形で情報を活用することができると思います。
ユーザIDだけでなく色々と応用できると思いますので、覚えておいて損はないと思います。


# 参考

* [nginxのアクセスログにユーザーIDを記録する方法](http://blog.howtelevision.co.jp/entry/2014/09/05/170917)
mbedでSDカード操作


mbedでFlashAir操作を行う練習として、mbedでSDカード操作の実験。

とりあえず、以下のパーツを準備。

```
 ・ｍｂｅｄ　ＮＸＰ　ＬＰＣ１７６８
 ・ＳＤカードスロットＤＩＰ化モジュール
 ・FlashAir 16GB CLASS10
```
ＳＤカードスロットＤＩＰ化モジュールは秋月で売ってる[これ](http://akizukidenshi.com/catalog/g/gK-05818/)を利用
 ![K-05818.JPG](https://qiita-image-store.s3.amazonaws.com/0/52867/45d1bb65-fe1a-807f-4846-bc2257b387d0.jpeg "K-05818.JPG")


##1.配線

モジュールについては[ここ](http://akizukidenshi.com/download/ds/cixiborui/SD%E3%82%AB%E3%83%BC%E3%83%89%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB.pdf)を参考に配線する

```接続
  VCC <-->  Vout
  GND <-->  GND
  SDI <-->  P5
  SDO <-->  P6
  CLK <-->  P7
  CS  <-->  P8
```

![IMG_0563.JPG](https://qiita-image-store.s3.amazonaws.com/0/52867/ab6a82d5-e725-b352-e3e6-c5112fd83926.jpeg "IMG_0563.JPG")

意外にシンプルな配線で済む

##2.プログラム
１.SDカード用のライブラリ：[SDFileSystem](http://developer.mbed.org/users/mbed_official/code/SDFileSystem/)をインポートする。

２.次にmain.cppの作成

```c++
#include "mbed.h"
#include "SDFileSystem.h"
 
SDFileSystem sd(p5, p6, p7, p8, "sd"); 
 
int main() {
    printf("START!\n");   
 
    mkdir("/sd/example", 0777);
    
    FILE *fp = fopen("/sd/example/test.txt", "w");
    if(fp == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fp, "Hello World!");
    fclose(fp);
    printf("END\n");
}
```

##3.実行
mbedにプログラムを配置して実行すれば、ファイルができていることが確認できると思います。


FlashAirなので、次はiSDIOを拡張してSDカードでインターネット接続に挑戦します。
Sublime Text3の個人的設定


またまたSublime Text3に手を出し始めました。  
キーマクロに文字検索が使えないっていうところで基本的に常用出来ないのは確定的なんだけれど、たまに思い出したように使ってしまうのはなにかしら惹かれる要素があるからなのでしょうね。
ということで、たまに使うたびに設定をゼロから作っているのも鬱陶しいいので、とりあえず個人的なまとめとして記録することにしました。

まず基本的なキーバインド。長らく使い続けてるEmacsの手癖から抜け出られそうな気がしないので、cmd+vはpage upにしている。

```json:sublime-keymap
[
	{ "keys": ["super+v"], "command": "move", "args": {"by": "pages", "forward": false}}
]
```

続いてパッケージ。

* [Alignment](http://wbond.net/sublime_packages/alignment)  
ctrl+cmd+'a'最高。
* [All Autocomplete](https://github.com/alienhard/SublimeAllAutocomplete)  
別ファイルからも拾ってくれなきゃね、
* [Git](https://github.com/kemayo/sublime-text-git)  
実はSublime Text上でgitコマンドは便利につかってない。キーバインドを設定すれば便利になるかも。
* [SideBarEnhancements](https://github.com/titoBouzout/SideBarEnhancements)  
入れたばかり。標準の機能だとサイドバーでのファイル操作がちょっと不便なので。
* [Flatland](https://github.com/thinkpixellab/flatland)  
見た目重要。カラースキームは"Flatland Dark"を指定してます。Flatland Darkは落ち着いた配色で地味目好みの自分には良い感じなんですけれど、良い感じだからこそ細かいところが気になることがある。ホントどうでもいいことなんですけど、惜しい分気になってしまう。
	* ハードタブの色はもう少しだけ控えめになってほしい
	* サイドバーの青いバーはもう少しだけ控えめになってほしい
	* "highlight_line"をtrueにしているとき、背景が真っ黒って…

というのを踏まえて、Settings - Userは、

```json:sublime-setting
{
	"color_scheme": "Packages/Theme - Flatland/Flatland Dark.tmTheme",
	"draw_white_space": "all",
	"ensure_newline_at_eof_on_save": true,
	"flatland_sidebar_tree_xsmall": true,
	"flatland_square_tabs": true,
	"font_size": 11,
	"highlight_line": true,
	"ignored_packages":
	[
		"Vintage"
	],
	"tab_size": 4,
	"theme": "Flatland Dark.sublime-theme"
}
```
比較的アッサリした設定になっています。
ということで、以上の設定をしたSublime Text3は、

![sublimetext3.jpg](https://qiita-image-store.s3.amazonaws.com/0/2681/3663c132-1745-7a56-a5c6-907046e60095.jpeg)

こんな画面です。おっ…UNREGISTEREDなのモロバレですね(笑)。

使い続けていけばそれなりにボリュームを増してくるのでしょうか。
他の方の設定とか参考にしてみようかな。

GitHubのatomエディタも興味ありありなのですが、cmd+vを上書きできないので(ですよね？)、Emacsに身も心も注いでいる人間としては「使えない」と言わざるをえない…。
Debian7.8でのIPの設定

##/etc/network/interfacesファイルに書いちゃダメなの？
[第５章 ネットワークの設定](https://www.debian.org/doc/manuals/debian-reference/ch05.ja.html#_the_low_level_network_configuration)を読む限り、
コマンドを打つような低レベルなIP設定は、iproute2を使って設定したほうがいいようです。
そのうち、切り捨てられそうなので今のうちに覚えておいたほうがよさそうです。

固定IP設定

```shell-session
# ip addr add xxx.xxx.xxx.xxx/24 dev eth0
```

Default Gatewayは

```shell-session
# ip route add default via xxx.xxx.xxx.xxx
```

とルーティングテーブルに追加するみたい

インターフェイス指定はサーバーのLANポートが2つあるの場合に
設定すると思われる。

```shell-session

# ip route add default dev [interface]
```


DNSは、
/etc/resolv.conf
に書いちゃっていいみたいだけど、
ただ、NetworkManagerなどが勝手にDNSを書き換えることがあるので、
その場合には何か手を打つ必要がある。

いろいろ手立てはあるようだが、一番手っ取り早いのは
/etc/resolv.confに書込み保護を掛けてしまう。

```shell-session

# chattr +i /etc/resolv.conf
```
Lotusを使った日本で初めてのアプリケーション(Part1)

#lotusについて
<a href="http://lotusrb.org/">lotus</a>とはrubyの最新フレームワークであり、1ファイル構成の簡易な構成から、複数のルートを持つ大規模なアプリケーション開発まで出来る、自由度の高いフレームワークです。

日本では、少なくとも私が知る限りlotusを使った実践的なアプリケーションは無いので、lotusを使い、簡単なアプリケーションを開発したという話をしていこうと思います。
（情報が少なく、手探りな感じで作ってみた部分が多いので、議論等できればいいかなって思っています）

なお、この記事を書いた時点で、まだリファクタリングが済んでいないため、コードの可読性については一度目をつぶっていただけると嬉しいです。

##概要
lotusをベースに、下記のフレームワーク・技術を使った、簡単なブログシステムを作ったので、システムの概要について書いていこうと思います。
・lotus
・sqlite3
・sass
・Vue.js
・grunt
・typescript
・Ajax
![サンプル画像](https://qiita-image-store.s3.amazonaws.com/0/69406/0ede087f-445d-aad3-e29e-845c211eeaa6.png)



##Part1（とりあえず、動かしてみる）
Part1では、まずlotusを導入し、Lotusを使った日本で初めてのアプリケーションを動かすことまでを書いていきます。

- 開発環境
 - vagrant : [環境整備用chefコード](https://github.com/yamadagenki/ubuntu_server)
 - lotus 0.3.0
 - ruby 2.1.5

###lotusの導入
[lotus](http://lotusrb.org/)の本家ページを見ると、下記のように載っているので、その通り実行し導入

```shell-session
$ gem install lotusrb
```

###コードを落としてきて準備
とりあえず、コードを落としてきて、bundle installする。

```shell-session
$ git clone https://github.com/yamadagenki/lotus_blog
$ cd lotus_blog
$ bundle install
```

###dbセットアップ
あとは、dbをセットアップ（今回はsqlite3を使っている）

```shell-session
$ cd db
$ ruby blog_migrate.rb
```

これで準備完了。
あとは、hostとかportとか指定してあげれば動く。

###動かしてみる
lotus_blog/の下で

```shell-session
$ lotus server -p 2300 --host=0.0.0.0
```

を打ち、http://192.168.33.10:2300/にアクセスすれば、とりあえず動くはず。
(Vagrantfileのコメントアウトを忘れずに)

###記事を書く
ブログ記事の編集は
http://192.168.33.10:2300/edit/user=yamadagenki&pass=lotusblog
より行う。（Enterを押すと、apiと通信し、勝手に保存される）
ユーザ名とパスワードはconfig/environment.rbにある、

```rb
NAME = "yamadagenki"
PASS = "lotusblog"
```
より編集ができる。

###記事を編集する
記事を作成後、編集したかったら
http://192.168.33.10:2300/edit/user=yamadagenki&pass=lotusblog&id=1
などとしてidを指定して編集する。
デバイスの認識が遅くてnetwork.serviceがfailedになる問題

自宅鯖にCentOS7を入れたんだけど起動時にネットワークデバイスの初期化(link up?)が終わる前に、`systemctl network.service start` が行われてしまって、network.service が failed になってしまう問題が起きて困っていた。

# 症状

１. 現象としてはまず以下の様なログが出てる。

> Mar 30 05:39:22 r16 NetworkManager[829]: <warn> Failed to activate 'enp3s0': Connection 'enp3s0' is not available on the device enp3s0 at this time.
> Mar 30 05:39:22 r16 network: インターフェース enp3s0 を活性化中:  エラー: 接続のアクティベーションに失敗: Connection 'enp3s0' is not available on the device enp3s0 at this time.
> Mar 30 05:39:22 r16 NetworkManager[829]: <info> NetworkManager state is now DISCONNECTING
> Mar 30 05:39:22 r16 NetworkManager[829]: <info> NetworkManager state is now DISCONNECTED
> Mar 30 05:39:22 r16 network: [失敗]
> Mar 30 05:39:22 r16 systemd: network.service: control process exited, code=exited status=1
> Mar 30 05:39:22 r16 systemd: Failed to start LSB: Bring up/down networking.
> Mar 30 05:39:22 r16 systemd: Unit network.service entered failed state.

２. でもこの後すぐに sshd とか firewalld とかが起動し始めちゃってる。でも firewalld が起動した時にはネットワークインターフェースがまだ無いので sshd の __TCP22番ポートのルールが iptables に上手く追加できなくて有効になってくれくれない。__

３. しかしその数秒送れで更に以下の様なログが出ていてNICの link up は果たされる。そしてこの時点で ping は通るようになっているのだ。

> Mar 30 05:39:24 r16 kernel: r8169 0000:03:00.0 enp3s0: link up
> Mar 30 05:39:24 r16 kernel: IPv6: ADDRCONF(NETDEV_CHANGE): enp3s0: link becomes ready
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> (enp3s0): link connected
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> (enp3s0): device state change: unavailable -> disconnected (reason 'carrier-changed') [20 30 40]
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> Auto-activating connection 'enp3s0'.
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> Activation (enp3s0) starting connection 'enp3s0'
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> Activation (enp3s0) Stage 1 of 5 (Device Prepare) scheduled...
> Mar 30 05:39:24 r16 NetworkManager[829]: <info> Activation (enp3s0) Stage 1 of 5 (Device Prepare) started...

４. だがfirewalldは既に起動を終えており、肝心のsshポートは開かないまま。起動シーケンスは最後まで実行されて終了…。

５. 仕方ないのでコンソールからログインして `systemctl restart firewalld.service` を手で実行してやることでsshは一応出来るようになると言う状態だ。

# 解決策

## ダメな奴（一応解決はするんだけどね…）

とりあえず、/etc/rc.local に

```bash:
sleep 5; systemctl restart network.service; systemctl restart firewalld.service
```
とか書いとけば一応繋げれるようになる。だが如何にもダメな奴だｗ

## 本解決

色々試しつつ、ふと `systemctl list-unit-files` を見てたら __NetworkManager-wait-online.service__ なんて名前のサービスがあるじゃない！？デフォルトではdisabledらしいが、いかにも僕の問題を解決してくれそうなサービス名である。おもむろに有効化。

```bash:
systemctl enable NetworkManager-wait-online.service
```

再起動してみる。…やったー、無事SSH入れたよ！network.service のステータス見ても failed しなくなってる！
gox して ghr するツール ggallin 作った

# ggallin の機能

[ggallin](https://github.com/yuya-takeyama/ggallin) (ジージーアリン) は Go 用のクロスコンパイルツール [gox](https://github.com/mitchellh/gox) と GitHub Releases へのリリースを行う [ghr](https://github.com/tcnksm/ghr) をラップしてコマンド一発でビルド・リリースを行ってくれるツールです。

より詳細には、`ggallin release` を実行すると以下の流れで各種コマンドが実行されます。

1. `gox` によるクロスコンパイルで各種 OS 向けのバイナリがビルドされる
2. ビルドされたバイナリを全て `.zip` に圧縮
3. `git push origin master`
4. `ghr` により、`version.go` に指定されたバージョンとしてリリースされる

# ggallin の使い方

## セットアップ

ggallin 自体は `go get github.com/yuya-takeyama/ggallin` なり [GitHub Releases](https://github.com/yuya-takeyama/ggallin/releases) からバイナリをインストールするなりして入れられます。
(Homebrew に対応させられれば Mac でのインストールが楽になるのでそのうちやりたい)

gox と ghr は予めインストールしておく必要があります。
この辺りも ggallin の機能として提供できると便利そうですが、今の所実装できてません。

また、環境変数 `GITHUB_TOKEN` に GitHub API のトークンをセットしておく必要があります。
これは ghr が要求するものなので、詳しくは[そちらの README.md](https://github.com/tcnksm/ghr#usage) を参照してください。

あとは go と git もインストールしている前提ですが、Go でツールを書いて GitHub に置いている人であればまぁ問題ないでしょう。

## version.go の用意

バージョンを記入するファイルとして、`version.go` というファイルを作っておく必要があります。

中身は以下のような感じにします。

```go:version.go
package main

const Version string = "0.0.1"

var GitCommit = ""
```

変数名もこれに合わせる必要があります。
定数 `Version` はリリース時に手動で書き換えておきます。

空の変数 `GitCommit` はビルド時に `-ldflags` オプションで動的にセットされます。

## ビルド & リリース

基本的には以下のコマンドだけでリリースが実行できます。

```
$ ggallin release -u yuya-takeyama
```

`-u` オプションは GitHub ユーザ名を指定します。
`ghr` はデフォルトでは `.gitconfig` の `user.name` を GitHub ユーザ名として使用するようになっておりますが、そこが一致している人はあんまりいないように思うので、指定するのが無難でしょう。

なお、`ghr` の 2015/03/29 の現在のプレリリース版だと `.gitconfig` の `github.user` を使用するようになっているので、そっちを設定しておくのもよいでしょう。

また、コンパイル対象の OS やアーキテクチャを使用するときは `--arch`, `--os`, `--osarch` というオプションを使うと、gox にそのまま渡されます。
例えば Linux と Mac (Darwin) だけを対象にするときは以下のようにします。

```
$ ggallin release -u yuya-takeyama --os="darwin linux"
```

`ggallin` は今の所設定ファイルには対応していないので、とりあえずは上記のようなコマンドを `release.sh` などとしてリポジトリにコミットしておけばよいでしょう。
とりあえずビルド・リリースをコマンド一発でできるようになりました。

# ggallin の実装について

`ggallin` のクロスコンパイル・Zip 化の流れは `ghr` プロジェクト内のシェルスクリプトを参考にしています。
また、プロジェクトの初期化は `cli-init` により行われております。
両方の作者である deeeet さん (tcnksm さん) に感謝します :bow:

# 名前について

`gox` と `ghr` を組み合わせて All-in-One のツールとして提供する、というのと、パンクロックアーティスト G.G. Allin にちなみます。
(G.G. Allin はすごくエキセントリックなミュージシャンなので、ググるときはグロ注意)

# ggallin を作るモチベーション

以前は、コマンドラインツールは基本的に Ruby で作ってきましたが、クロスコンパイル・デプロイの容易さから、最近はもっぱら Go で開発するようになりました。

そんな Go ですが、作ったツールをビルド・リリースするまでの流れを一気通貫で行ってくれるツールはなかなか見つかりません。
個人的にはこれまでツール開発は Ruby で行っており、Bundler を使えば `rake build` や `rake release` といったコマンドで簡単に gem をリリースすることができたので、その体験を Go にもそのまま持って来たいと思いました。

これでますます Go によるツール開発が楽になったので、これまでシェルスクリプトや Ruby で書いてきたものもどんどん Go にしていくつもりです。

# まとめ

お前も Go 実装にしてやろうか！
Alchemyを使って画像ファイルから自動的にタグ付けするWordPressプラグイン

Alchemyという画像からタグを取得できるAPIがあります。
http://www.alchemyapi.com/api/image-tagging/urls.html

これを使ってWordPressに画像を投稿したら自動的にタグ付けできるプラグインを書いてみました。他のプラグインと同様に/wp-contents/plugins配下に置いて有効化すれば動くと思います。（あんまり試してません）

Alchemyの開発者キーは、ご自身で取得くださいな。

```php
<?php
/*
Plugin Name: add tag with alchemy
Plugin URI: http://barcelona-prototype.com/wordpress
Description: add tag with alchemy
Author: t.uehara
Version: 0.0.1
*/

add_filter('post_updated','add_tag_with_alchemy');

function add_tag_with_alchemy($id){
    $key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    $base = "http://access.alchemyapi.com/calls/url/URLGetRankedImageKeywords?apikey=".$key."&forceShowAll=1&outputMode=json&url=";
    $text = get_post($id,'ARRAY_A')['post_content'];
    $preg = '(https?://[-_.!~*\'()a-zA-Z0-9;/?:@&=+$,%#]+)';
    if(preg_match_all($preg, $text, $result) !== false){
        foreach($result[0] as $value){
            if(preg_match("/jpg/",$value)){
                $json = file_get_contents($base.$value);
                $imageKeywords = json_decode($json)->imageKeywords[0]->text;
                wp_set_post_tags($id,$imageKeywords);
            }
        }
    }
    return null;
}
```
IFTTTを使ってTwitterやFacebookに投稿された画像を片っ端からタギングするのも面白いんじゃないかと思います。
オブジェクト指向にまつわる嘘と真実

# 概要
オブジェクト指向という言葉はもうすっかりIT業界に馴染んでしまいました
一方で、これほど人によって解釈がばらついている概念もなかなか無いと思います
ここでは実際にオブジェクト指向開発を行ってきた中で、入門書や専門書に書かれている言葉と現実との食い違いについて感じていることを書いてみたいと思います
ただし、あくまでも私がどう感じているかであり、他の方の考えを否定するものではないことを最初に述べておきます


## オブジェクト指向技術を使えば、現実の世界をそのままシステム化できる
これもオブジェクト指向が流行り始めた当初からずっと言われ続けてきた言葉だと思いますが、これは現実から大きく離れており、理解の妨げになっています
実際には、現実にある業務や概念をそのままシステムに落とし込むと却って不自然になることの方が多いです

例えば給与計算について考えてみます
現実には経理社員が居て、タイムカードや経費報告書があり、個々の社員が居ます
そして経理社員は社員が提出したタイムカードや経費報告書に従って、個々の社員の給与を計算します
しかしながらこの関係をモデル化していくと、タイムカードや経費報告書といったものは個々の社員が集約する形になると思います。つまり情報エキスパートパターンに照らして言うと、その社員の給与計算に関して、本人（社員）こそが情報エキスパートということになります
にも関わらず経理社員を実装して個々の社員の給与計算を行わせれば、その設計は非常に不自然なものになってしまいます
このように、現実の業務の形をそのままシステムに落とし込むことは必ずしも正しくないことがあるのです
参考までにモデル図とコードサンプルを示します

![クラス図0.jpg](https://qiita-image-store.s3.amazonaws.com/0/72322/710ba2e2-2add-ff6e-8a26-bcc8dc83e7c8.jpeg)

```java:現実をそのまま落とし込むと（経理社員#給与計算）
int salary = emproyee.getSalary();
salary += emproyee.getOvertimePayment() * emproyee.getTimeCard().getOvertime();
salary += emproyee.getExpenseReport().getExpenses();
```

![クラス図1.jpg](https://qiita-image-store.s3.amazonaws.com/0/72322/a2e51f0c-c62b-fdd6-0259-279a1d8435e5.jpeg)

```java:自然な設計（社員#給与計算）
int salary = salary;
salary += overtimePayment * timeCard.getOvertime();
salary += expenseReport.getExpenses();
```


## オブジェクト指向の本質はオブジェクトにある
私はこれは違うと思います
オブジェクト指向の本質はメッセージングであり、それによって織り成されるオブジェクト間のコラボレーションだと思っています
ここで言うメッセージングとは、相手オブジェクトにしてほしいことを伝えれば相手オブジェクトは自らの責務に従って結果を返してくれる。伝える側が相手オブジェクトがどういう風に仕事を進めたかを気にする必要は一切ない、というものです
また、コラボレーションとは、お互いが意味のある仕事をし、協調して目的を果たす、ということです
そしてオブジェクトという属性と振る舞いの入れ物は、これを実現するための1つの手段でしかないと思います

※蛇足ですがオブジェクト指向の生みの親と言われるアラン・ケイ博士もオブジェクト指向というネーミングは失敗だったと語っています。オブジェクトという単語ばかりが注目を集めてしまい、より注目されるべきメッセージングが軽視されてしまうからです
もしも私が今改めて名前を付け直すならば、コラボレーション指向などという名前が良いのではないかと勝手に思っています


## getterとsetterはオブジェクト指向の基本であり、必ず利用すべきである
これもあまりよろしくないと思います
確かにgetterとsetterという皮を1枚被せることでフィールドに直接アクセスしなくて済むかもしれません
しかし考えてみてほしいのですが、皆さんの周りにあるコードのgetterやsetterというのは単純に値を取得/設定するものがほとんどではありませんか？
（あるいはsetterならば引数のnullチェックくらいはしているかもしれませんが）
だとすれば、一体何が隠蔽されているというのでしょうか。ほとんどのgetter, setterはオブジェクトの中身を覆い隠す皮としては薄すぎるように思います
getterやsetterよりももっと意味のある処理をそのオブジェクトに任せられるのではないでしょうか？
一方がただデータの管理だけをさせられるような関係は隷属的であり、コラボレーション（協調）とは言えないと思うのです


## 蛇足：開発者の取るべきスタンス
「オブジェクト指向とは思想である」という言葉を時折耳にします。また、「これはオブジェクト指向っぽくないからダメだね」という言葉を聞くこともあります
果たして技術者にとってオブジェクト指向は思想であり、正義であるべきでしょうか？
私はオブジェクト指向もその他多くの技術と同じく、「顧客の満足いくシステムを作るための手段の1つ」であると思っています。それは部品のように、よりよいものが見つかれば取り換えられるべきものです
オブジェクトが状態を持つものとして作られてきた一方で、近年状態によって結果が左右されない関数型プログラミングが注目を集めました
これもそうしたオブジェクト指向では果たせない目的を果たすための流れの1つではないかと思います
願わくば技術者がうわべの聞こえの良いバズワードに流されることなく、技術の1つとして冷静な目でオブジェクト指向を取り込んでいくことを願います
Docker + iPythonで画像処理（設定編）

[Pillow環境構築 -- Docker + iPythonの場合（あと、OpenCVも） - Qiita](http://qiita.com/suto3/items/949532ba83c0da671df2 "Pillow環境構築 -- Docker + iPythonの場合（あと、OpenCVも） - Qiita")
の続き

##イメージの取得
DockerHubからイメージを取ってくる
[suto3/ipython-pillow Repository | Docker Hub Registry - Repositories of Docker Images](https://registry.hub.docker.com/u/suto3/ipython-pillow/ "suto3/ipython-pillow Repository | Docker Hub Registry - Repositories of Docker Images")
```
docker run -d -p 8080:8888 -v $PWD:/notebook suto3/ipython-pillow:0.1
```
なお、イメージのサイズはばかでっかいので覚悟すること。

http://ホストのIPアドレス:8080/ にアクセスすればiPythonが使える。

Dockerの環境を作ってしまえば、これだけで動く、と。

###Windows の boot2dockerで注意すること
ホストOS（Windows）～ゲストOS（Linux）間のファイルのやりとりは、/c/Users （ホストから見るとC:Users\）配下のディレクトリで行う

###Mac OSX の　boot2dockerで注意すること
ホストOS（Mac OSX）～ゲストOS（Linux）間のファイルのやりとりは、/Users 配下のディレクトリで行う。

###Linuxで注意すること
いまのところなし

##使ってみよう
[Docker + iPythonで画像処理（Pillow編） - Qiita](http://qiita.com/suto3/items/41f5a4a1d6e159c1aa31 "Docker + iPythonで画像処理（Pillow編） - Qiita")

[Docker + iPythonで画像処理（OpenCV編） - Qiita](http://qiita.com/suto3/items/eba0f6a640dba3bdc496 "Docker + iPythonで画像処理（OpenCV編） - Qiita")
MongoDBのDatabaseをリネームする

MongoDBのDB名を変更する方法を紹介します。

残念ながら一発でアトミックにリネームする方法はないので、「コピーして古い方を削除」するしかありません。

ここでは「ダンプしてリストア」方式を紹介します。
具体的には`mongodump`と`mongorestore`というコマンドを使います。

`old_db`という名前のデータベースを`new_db`に変更したいとします。

MongoDBサーバが稼働してる状態で、

```
$ mongodump old_db
$ mongorestore --db new_db ./dump/old_db
```

ここで、new_dbがちゃんと想定どおりの状態になっていることをテストます。
(具体的には、count()でレコード数を数えたり、アプリケーションから接続して動かしたり)

OKであれば旧DBを削除します。

```
$ use old_database
$ db.dropDatabase()
```
Android 開発で使う JAR を生成する際の注意点

#前書き

Java を利用した開発において、ある程度まとまった機能は JAR にすると管理が容易になります。

これは Android 開発においても同様のことが言えます。例えば 自作 ImageView を作成した時、ImageView を拡張したソースコードをそのままプロジェクトに入れておくよりも、パッケージにして切り離した方が、他のプロジェクトで利用したくなった時でも容易に使い回す事が出来ます。

しかし、JDK 8 環境において JAR を生成する時は、バージョンの差異に対する対策が必要となります。

#コンパイル

IntelliJ IDEA を利用してコンパイルすると、JDK8 環境の場合は バージョン 1.8 のバイトコードを生成します。
しかし、この JAR を Android プロジェクトに含めてコンパイルすると 


> Error:Gradle: Execution failed for task ':app:preDexDebug'.
\> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/usr/lib/jvm/java-8-jdk/bin/java'' finished with non-zero exit value 1

というエラーに見舞われます。
これだけではコンパイラが異常終了したことしか分からないので、もう少し詳しく原因を追ってみると `gradle:preDexDebug` において

> UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)

というエラーが発生していることが判明します。

#対策

このエラーは、Android 自体が Java 1.7 までの対応であるために、Java 1.8 で生成されたバイトコードを利用できない事が原因です。

これを回避するには、`File` → `Settings` より設定画面を開き、`Build, Execution, Deployment` → `Compiler` → `Java Compiler` → `Project bytecode version` の値を空白から `1.7` に変更してからコンパイルします。

すると、コンパイル時にバージョン 1.7 のバイトコードを生成するため、Android プロジェクトでも利用できるようになります。
ReactでshouldComponentUpdateを使ったチューニングの効果と注意どころ


[GitHubはこちら](https://github.com/wordijp/todomvc-perf-comparison)

# 背景

Reactが流行ってる理由として、
Fluxやもともとのフレームワークの用法からデータフローが単方向へと簡略化され、速度面ではチューニングしたDOMを直接触る従来の方式には敵わないが、遅くなる事はないし何よりシンプルな方向へとバイアスがかかる恩恵がでかい、というのが自分の中での認識となっています。

ただ、速度は速い方が嬉しいので、フレームワークのベンチマーク比較プロジェクトに、shouldComponentUpdateを実装して、必要時にだけrenderが呼ばれるようにチューニングをしてどれだけ効果があるのかを検証してみた、というのが今回の記事です。

プロジェクトは[こちらの記事](https://html5experts.jp/hokaccha/13301/)のをForkして利用しています。


# 計測結果

![benchmark.png](https://qiita-image-store.s3.amazonaws.com/0/51728/45162277-4f2c-f5cd-5427-c208bed49e68.png)

上から、

- Backboneの部分的再描画、
- Backboneの全再描画
- ReactのVirtualDOM全再描画、
- ReactのVirtualDOM部分再描画(shouldComponentUpdateの手動チューニング)、
- ReactのVirtualDOM部分再描画(shouldComponentUpdateチューニングに自作の汎用Mixinの利用)

となっています、shouldComponentUpdateの実装はかなり効果があるものと言えます。

# shouldComponentUpdateで比較時の注意どころ

```js:test.js
  shouldComponentUpdate: function(nextProps, nextState) {
    if (差分があった) {
      return true;
    }
    else {
      return false;
    }
  }
```

基本的に、やる事と言えばメンバのthis.props、this.stateと、引数のnextProps、nextStateとで差異があればtrueを返すだけで良いのですが、愚直にメンバの比較を羅列するのはこのメソッドのメンテナンスコストがかなり高くなってしまいます(効果は高いですが)。

また、シャローコピーされた参照型がプロパティに含まれている場合は、比較しても常にtrueが返ってしまい、誤動作の原因となってしまいます。

```js:ng.js
  this.state.shallowedInstance === nextState.shallowedInstance; // FIXME : 常にtrue
```

全てのプロパティが値型なのであれば、[PureRenderMixin](https://facebook.github.io/react/docs/pure-render-mixin.html)アドオンが提供されているため、それを使うことが出来ますが、参照型の場合は別の手を考える必要があります。

# メンテナンスコストを緩和する今回の対策

今回の対応方法としては、公式でも使用を推奨している[immutable-js](https://github.com/facebook/immutable-js)を使い、Mixinとして使えるようにして、shouldComponentUpdateを使った時のメンテナンスコストを下げれるように図ってみました、速度は計測結果の一番下です、場合にもよりますが、効果はある方なんじゃないかと思います。

```js:mixin.js
var Immutable = require('immutable');
var Mixin = {
  prevPropsMap: undefined,
  prevStateMap: undefined,

  getInitialState: function() {
    this.prevPropsMap = Immutable.Map();
    this.prevStateMap = Immutable.Map();

    return {};
  },

  shouldComponentUpdate: function(nextProps, nextState) {
    var nextPropsMap = Immutable.Map(nextProps);
    var nextStateMap = Immutable.Map(nextState);

    if (!Immutable.is(nextPropsMap, this.prevPropsMap) ||
        !Immutable.is(nextStateMap, this.prevStateMap)) {

      this.prevPropsMap = nextPropsMap;
      this.prevStateMap = nextStateMap;
      return true;
    }

    return false;
  }
};
```

使い方は、mixinsにこちらのmixinオブジェクトを指定して使います。
ちなみにGitHubのプロジェクトにもソースあります
(todomvc/react3/js/components/ShouldComponentUpdateMixin.react.js)。


# 参考

https://facebook.github.io/react/docs/advanced-performance.html
setStateを複数回実行してもrenderは1回しか呼ばれない



ReactjsのsetStateとrenderの挙動をちょっと確認してみました。
具体的には以下のコードで検証。

はじめはsetStateの度にrenderが呼び出されるのかと思ってましたが
そうではなくて、stateの変更をキューに入れてrenderを呼び出す前にまとめて解決するようです。
setTimeoutでコールバックを呼んだ時なんかは
別のキューになるようです
setStateが呼ばれなければもちろんrenderも呼ばれない


```app.js

var MyComponent = React.createClass({
	getInitialState: function () {
    return {
    	value: 'step 0'
    };
	},
	handleClick: function() {
		this.setState({
			value: 'step 1'
		});
		console.log('called step 1');

		this.setState({
			value: 'step 2'
		});
		console.log('called step 2');

		this._func();
		this.setState({
			value: 'step 4'
		});
		console.log('called step 4');
		setTimeout(this._callback, 1000, this);
	},
	_func: function() {
		this.setState({
			value: 'step 3 this is inner func'
		});
		console.log('step 3 _func called');
	},
	_callback: function(self) {
		self.setState({
			value: 'step 5'
		});
		console.log('step 5 called');
	},
	doNothing: function() {
		console.log('do nothing');
	},
	render: function() {
		console.log('will render!');
		return (
			<div>
				<div>{this.state.value}</div>
				<a onClick={ this.handleClick }>Click me!</a>
				<p onClick={ this.doNothing }>Click me but I will do nothing</p>
			</div>
		);
	}
});
React.render(
	<MyComponent />,
	document.getElementById('app')
);
```

```console

//will render! 最初
//app.js:44 called step 1
//app.js:49 called step 2
//app.js:62 step 3 _func called
//app.js:55 called step 4
//app.js:74 will render! 一回だけ呼ばれる
// １秒空くよ
//app.js:74 will render!  順番が違う?
//app.js:68 step 5 called
ヤフオクの落札データを取得したい

ヤフオクの自分の落札データを、YahooのAPIで取得したいのですが、
「Yahoo! ID連携」を使うしかないのでしょうか？

自分が落札したデータを、管理画面で管理するだけなので、
一般に公開しているHPを持っていません。

「Yahoo! ID連携」の申込画面に「会社ウェブサイトURL」とあり、
入力必須になっていますが、「Yahoo! ID連携」を使わずに、
自分の落札データを取得する方法はないのでしょうか？
Capistranoで確認スクリプトの実行

以下のtest-script.shのようなスクリプトを作って、Capistrano3で

```bash
$ cap test execute_script
```
してVagrantで作成した仮想マシンで実行すると、

```bash
test-project $ cap test execute_script
INFO [035ec69f] Running /usr/bin/env cd capistrano-test; pwd as vagrant@127.0.0.1
DEBUG [035ec69f] Command: cd capistrano-test; pwd
Text will be echoed in the clear. Please install the HighLine or Termios libraries to suppress echoed text.
Enter passphrase for /Users/kazuhirokomoda/.ssh/id_rsa:
DEBUG [035ec69f] 	/home/vagrant/capistrano-test
INFO [035ec69f] Finished in 7.728 seconds with exit status 0 (successful).
DEBUG [4d80d295] Running /usr/bin/env sh ~/capistrano-test/test-script.sh as vagrant@127.0.0.1
DEBUG [4d80d295] Command: sh ~/capistrano-test/test-script.sh
DEBUG [4d80d295] 	Is it OK to continue? :  (y/n)?
y
n
y
...動かない
```
みたいに

```bash
Is it OK to continue? :
```
の表示が出た後で毎回止まり、ユーザの入力を受け付けてくれない。
こういうユーザ入力を待つスクリプトをCapistranoで実行する方法を知りたいです。


*設定等はこのページを参考。
http://labs.gree.jp/blog/2013/12/10084/


```bash:test-script.sh
#!/bin/sh

askYesOrNo() {
    while true ; do
        read -p "$1 (y/n)?" answer
        case $answer in
            [yY] | [yY]es | YES )
                return 0;;
            [nN] | [nN]o | NO )
                return 1;;
            * ) echo "Please answer yes or no.";;
        esac
    done
}

askYesOrNo "Is it OK to continue? : "
if [ $? -eq 0 ]; then
    # the return value of the shell script is obtained by `$?`, which means terminate code
    echo "nice!"
else
    echo "boo..."
fi
```


```rb:deploy.rb
# 前略
# a task
desc "execute a script on a web server"
task :execute_script do
  on roles(:web) do
    execute "cd capistrano-test; pwd"
    output = capture "sh ~/capistrano-test/test-script.sh"
    info output
  end
end
# 後略
```

```rb:deploy/test.rb
set :stage, :test

server '127.0.0.1', port: 2222, user: 'vagrant', roles: %w{web app db}, ssh_options: {
  #keys: %w(~/.ssh/authorized_keys),
  #forward_agent: true,
  #auth_methods: %w(publickey)
}
```
『パーフェクト Ruby on Rails』の http://lvm.me がよくわからないので http://127.0.0.1 でやった

コメント欄より、 lvh.me:3000 を使えばOKとのこと。誤植ですね、これ。
@babie さんありがとうございました。

---

[『パーフェクト Ruby on Rails』](http://www.amazon.co.jp/dp/4774165166)のPart3 第6章では、イベント管理アプリみたいなのを作っていきます。

Twitter認証のコールバック処理を書くために、「http://localhost:3000 だとダメだから、 http://lvm.me:3000 を使うよー。localhost:3000と同じ意味になるよー。」みたいな事が書いてあったと思うんだけど、僕の環境だとlvm.me:3000でもダメなんだよね……。 試しにブラウザでアクセスしてみると http://www.lvm.co.il/ に飛ばされちゃいます。

とりあえず http://127.0.0.1:3000 とすることで回避したんだけど、同じような境遇の人、もしくは「これはこういうことだよ」って教えてくれる人募集中です。。
文字列から任意の文字列を取得する

文字列から任意の文字列を取得したい場合、以下のようなコードはシンタックスエラーとなります。

```swift:sample1.swift
let str = "world"
println(str.substringFromIndex(2)) // rld を期待
```

Intを直接指定することはできず、String.Indexを指定する必要があります。
String.Indexはadvance関数を使って作成します。

```swift:sample2.swift
let str = "world"
println(str.substringFromIndex(advance(str.startIndex, 2))) // rld
```

NSString型として取得することもできます。

```swift:sample3.swift
let str = "world"
println(NSString(string: str).substringFromIndex(2)) // rld
```

機能拡張（extension）として実装すると次のようになります。
substring1とsubstring2はともに同じ実行結果となります。


```swift:sample4.swift
extension String {
    func substring1(start: Int) -> String {
        return self.substringFromIndex(advance(self.startIndex, start))
    }
    
    func substring2(start: Int) -> String {
        return NSString(string: self).substringFromIndex(start)
    }
}

let str = "world"
println(str.substring1(2)) // rld
println(str.substring2(2)) // rld
```

文字列のstartで指定された位置からlength分の文字列を返す場合は次のようになります。

```swift:sample5.swift
extension String {
    func substring(start: Int) -> String {
        return self.substringFromIndex(advance(self.startIndex, start))
    }
    
    func substring(start: Int, length:Int) -> String {
        return self.substringFromIndex(advance(self.startIndex, start)).substringToIndex(advance(self.startIndex, length))
    }
}

let str = "world"
println(str.substring(2, length:2)) // rl
println("おはようせかい".substring(1, length: 3)) // はよう
```
気づいたらBoxen放置して、Brew Caskとかで環境構築してた話


# Boxenの管理が難しかった
会社PCと私用のMacが同じになればいいだけなのに、なんであんなにファイル管理しなきゃいけないんだ...
[Code:Github](https://github.com/kuozumijp/my-boxen)

# Hoembrewだけでやっぱりなんとかしたい
### Brewfile終わってね？
[参考:Homebrewとbrewfileとhomebrew-caskでMacの環境構築](http://unasuke.com/howto/2014/homebrew-and-brewfile-and-homebrew-cask/)

### Brewdlerとかもあるけど...
[参考:Brewfileはオワコンではない](http://rcmdnk.github.io/blog/2015/03/24/computer-mac/)

# 自分はこうした。
* AppStoreでダウンロードできるものはそこでダウンロードする。
* それ以外はHomebrew/Caskでダウンロードする。(zshとかchromeとか)

```BrewInstall.sh
# Make sure using latest Homebrew
brew update

# Update already-installed formula
brew upgrade

# Add Repository
brew tap phinze/homebrew-cask || true
brew tap homebrew/dupes || true
brew tap homebrew/binary || true

# Packages for development
brew install ...

# Packages for brew-cask
brew install phinze/cask/brew-cask

# .dmg from brew-cask
brew cask install …

# Remove outdated versions
brew cleanup
```
[Code:Github](https://github.com/kuozumijp/Dotfiles/blob/master/BrewInstall.sh)
rspec-modeでrspecを実行する時だけエラーが起きた時

コマンドラインからrspecを走らせても、エラーにならず、rspec-modeのrspec-verify-singleとかから起動する時だけエラーになっちゃう時がありました。

## 背景 ##

テストはこんな感じ。turnipのfeatureです。

やってることは

1. Twitte.updateメソッドをtweetするんじゃなくて、標準出力するように偽装する
2. 標準出力をStringIOのインスタンスに書き換ええる
3. テストでtweetの内容( `stdout` )と期待値を確認する
3. afterでオリジナルの標準出力に戻す

ということをしています。

``` ruby:spec_helper.rb
RSpec.configure do |config|
  config.before(:each) do
    allow(Twitter).to receive(:update) {|tweet| puts tweet}
    @orig_stdout = $stdout
    $stdout = @stringio = StringIO.new
  end

  config.after(:each) do
    $stdout = @orig_stdout
  end
end
```

``` gherkin:bot.feature
シナリオ: botコマンド
  前提 日時が "2013-07-30 19:00" となっていること
  ならば "あつきものむかし大坂夏御陣  夏目漱石" とつぶやかれていること
```


``` ruby:global_steps.rb
step ":tweet とつぶやかれていること" do |tweet|
  expect($stdout.string.chomp).to eq tweet
end
```

backtraceはこんな感じ。

```
bundle/ruby/2.1.0/gems/rspec-core-3.1.7/lib/rspec/core/notifications.rb:226:in `strip': invalid byte sequence in US-ASCII (ArgumentError)
```

## 対処 ##

調べるとrspec-verify-singleとかした時だけ、 `Encoding.default_external` が `US-ASCII` になっていた。
なので

``` ruby:spec_helper
RSpec.configure do |config|
  Encoding.default_external = Encoding::UTF_8
end
```

と追加してあげればok。

## 追記

そもそもturnipのfeatureをrspec-verifyってできないのですが、emacsで独自関数を作っています。 [私のconfigファイル](https://github.com/tomiacannondale/dot.emacs.d/blob/master/conf/80_feature-mode.el ) 

多分、発生している原因はemacs内でrubyを起動すると `Encoding.default_external` が `Encoding:US-ASCII` になっているのが原因なので、turnipを介しているのが原因ではないと思います。
根本解決はemacs内での環境変数LANGをちゃんと指定するのかなぁ。
nginxでjenkinsのサブドメイン設定が上手くできない

jenkinsを導入したので、サブドメインでアクセスできるように設定したかったけど、nginxの設定方法がいまいちわからなかったので、調べてみた。

[How To Configure Nginx with SSL as a Reverse Proxy for Jenkins | DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-with-ssl-as-a-reverse-proxy-for-jenkins)

ここを参考に`/etc/nginx/cond.d/...`をこんな感じに。

```
server {
    listen 80;
    server_name jenkins.hostname;
    location / {
        proxy_pass http://localhost:8080;
        proxy_redirect http://localhost:8080 https://jenkins.hostname;
    }
}
```

と思ったらちゃんと公式に設定方法があったのでこちらを使うことにした。

[Jenkins behind an NGinX reverse proxy - Jenkins - Jenkins Wiki](https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+behind+an+NGinX+reverse+proxy)

```
server {
  listen 80;
  server_name jenkins.domain.tld;

  location / {
    proxy_pass              http://localhost:8080;
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout   150;
    proxy_send_timeout      100;
    proxy_read_timeout      100;
    proxy_buffers           4 32k;
    client_max_body_size    8m;
    client_body_buffer_size 128k;

  }
}
```

うーむ。
Gradleでprovidedが定義できないエラーに遭遇しました

Gradleを使ったJavaのプロジェクトにおいてlombokが使いたくて、build.gradleにprovidedを追加しようと試みたところ以下のようなエラーに遭遇しました。

```text
Cannot change configuration ':provided' after it has been resolved.
```

#環境

- Gradle 2.3
- JDK 8

#解決方法

参考にさせていただいたページのおかげで解消することができました。Gradle 2.0 以降では、コレクションにはコレクションしか追加できないようになったためだそうです。変更点をピックアップしておきます。

##変更前

```groovy
eclipse.classpath {
    plusConfigurations += configurations.provided
    noExportConfigurations += configurations.provided
}
```

##変更後
```groovy
eclipse.classpath {
    plusConfigurations += [configurations.provided]
    noExportConfigurations += [configurations.provided]
}
```

#参考

- [Gradle 2.0 以降と IDEA プラグインで Configuration として provided を定義して idea.module のスコープに追加すると ClassCastException が発生する](http://qiita.com/yukung/items/1ccb29cc2c0cc9905e8e)
Collectionの要素の変更検知の仕方

要素の追加・削除だけであればObservableCollectionで良いのですが，さらにその要素の変更によって処理をさせたい！そう思った時のメモです．

以下のように，Rxを使ってコレクションの要素のPropertyChangedイベントをトリガーにして，さらに別プロパティのPropertyChangedイベントを発火させてみました．

```csharp

// 要素
class Hoge : BindableBase
{
  private bool isChecked;
  public bool IsChecked
  {
    get
    {
      return this.isChecked;
    }
    set
    {
      this.isChecked = value;
      this.OnPropertyChanged(() => IsChecked);
    }
  }

  private int num;
  public int Num
  {
    get
    {
      return this.num;
    }
    set
    {
      this.num= value;
      this.OnPropertyChanged(() => Num);
    }
  }
}
```

```csharp
// 別のクラス ViewModelとか
class Foo
{
  // 監視するコレクション
  public ObservableCollection<Hoge> HogeCollection

  // HogeCollectionの内フラグがtrueの要素の値の合計値プロパティ
  public int HogeSum
  {
    get
    {
      HogeCollection.Where(x => x.IsChecked).Sum(y => y.Num);
    }
  }

  // HogeCollectionの値をセットする際
  public void addItem(Hoge item)
  {
    // itemのPropertyChangedに対するハンドラの記述
    Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
      h => item.PropertyChanged += h,
      h => item.PropertyChanged -= h)
      .Subscribe(e =>
      {
        // 変更があったらHogeSumも変更する
        this.OnPropertyChanged(() => this.HogeSum);
      });
    HogeCollection.add(item);
  }
}
```
Windows: git に sshの設定


- ssh_config に IdentityFile を設定すればいい、という話

##  ChocolateyでNugetのGitインストール

- [gitパッケージ](https://chocolatey.org/packages/git)

~~~bat
C:\Users\hdknr> choco install git
~~~

## ssh-keygen でキーの作成

~~~bat
C:\Users\hdknr>where ssh-keygen
C:\ProgramData\chocolatey\bin\ssh-keygen
C:\ProgramData\chocolatey\bin\ssh-keygen.bat
~~~

~~~bat
C:\Users\hdknr> mkdir .ssh
~~~

~~~bat
C:\Users\hdknr> ssh-keygen -b 4096 -f \Users\hdknr\.ssh\win8.key

Generating public/private rsa key pair.
cygwin warning:
  MS-DOS style path detected: \Users\hdknr\.ssh\win8.key
  Preferred POSIX equivalent is: /cygdrive/c/Users/hdknr/.ssh/win8.key
  CYGWIN environment variable option "nodosfilewarning" turns off this warning.
  Consult the user's guide for more details about POSIX paths:
    http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in \Users\hdknr\.ssh\win8.key.
Your public key has been saved in \Users\hdknr\.ssh\win8.key.pub.
The key fingerprint is:
93:66:5a:0e:7b:e4:a1:2d:fc:ee:46:4f:46:1c:07:fa hdknr@Blacky
The key's randomart image is:
+--[ RSA 4096]----+
|          ..     |
|         .. .    |
|        .. o     |
|         oo      |
|      . S.E      |
|     . &.oo      |
|      *.=+       |
|       +. .      |
|       ++        |
+-----------------+

~~~

~~~
C:\Users\hdknr>dir \Users\hdknr\.ssh
 ドライブ C のボリューム ラベルは Acer です
 ボリューム シリアル番号は 9AAA-8637 です

 C:\Users\hdknr\.ssh のディレクトリ

2015/03/29  17:35    <DIR>          .
2015/03/29  17:35    <DIR>          ..
2015/03/29  16:51               410 known_hosts
2015/03/29  17:35             3,243 win8.key
2015/03/29  17:35               738 win8.key.pub

               5 個のファイル               8,372 バイト
               2 個のディレクトリ  807,079,927,808 バイトの空き領域
~~~

## %GIT%¥etc¥ssh¥ssh_config で IndentityFile 指定

~~~bat
C:\Users\hdknr>where git
C:\Program Files (x86)\Git\cmd\git.exe
~~~

~~~bat
C:\Users\hdknr>cd C:\Program Files (x86)\Git\etc
C:\Program Files (x86)\Git\etc>mkdir ssh
~~~

- 編集

~~~bat
C:\Program Files (x86)\Git\etc>gvim ssh\ssh_config
~~~

- Bitbucket.org に設定

~~~
Host bitbucket.org
  IdentityFile C:\Users\hdknr\.ssh\win8.key
~~~

## Bitbucketからclone

- bitbuket に win8.key.pub を設定しておくこと

~~~bat
C:\Users\hdknr>git clone git@bitbucket.org:hdknr/photo.git
Cloning into 'photo'...
remote: Counting objects: 33, done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 33 (delta 1), reused 0 (delta 0)
Receiving objects: 100% (33/33), 9.72 MiB | 400.00 KiB/s, done.
Resolving deltas: 100% (1/1), done.
Checking connectivity... done.
~~~
twicli で対象ツイート前後のツイートを表示する（便利）

# twicli で対象ツイート前後のツイートを表示する（便利）

[「リツイート直後のツイートを探す」twicliプラグイン - Okiraku Programming](http://d.hatena.ne.jp/NeoCat/20150308) が作成されたので、これをパクれば念願の「対象ツイート前後のツイートを表示する」も可能になるのでは！？　と思い、作ってみました。
PR してみたら、ありがたいことに本体に取り込んでもらえました ＼(^O^)／

設定から、プラグインに tweets_around_tw.js を加えることで、「リツイート直後のツイートを探す」twicliプラグインと同じように使えます。

RT で回ってきたツイートがどういった文脈でなされたのか知るために、そのツイートの前後（前後10分）のツイートを表示することができます（便利）
twicli のショートカット追加

# twicli のショートカット追加

[twicliの夜フクロウ風ショートカットプラグインを作りました - oui-log](http://oui.hatenablog.com/entry/2015/03/16/221038) でいくつか便利なショートカットがあったので使わせてもらった。

加えて、「ツイートのURLをツイート欄へコピー+フォーカスを移す」を c に割り当てた。
リツイートした後に、それに対するコメントをする際に使っている。

https://bitbucket.org/hokorobi/twicli/raw/4cb96b7b46b26f6c7451c60749585d2d67c271b9/plugins/shortcutkey.js
PHPでAOP的にメソッドの実行時間を計測

# PHPでAOP的にメソッドの実行時間を計測

## 概要

* 特定のインスタンスの呼び出されるメソッド全ての計測をしたい
* そのクラスのソースコードは(できる限り)かえたくない

こういったものを実現します。

## サンプル

### code

```
<html>
<body>
<?php

class PHoge {
  public function getPHoge() {
    return "getPHoge called!!";
  }
}

class Hoge extends PHoge {

    public $hoge;
    public static $hogeStatic = "hoge static";

    public function __construct() {
        $this->hoge = "hoge prop";
        $this->_hoge = "_hoge prop";
    }

    public function getHoge() {
        return $this->_getHoge();
    }

    private function _getHoge() {
        return "_getHoge is called";
    }

    public static function getHogeStatic() {
        return "getHogeStatic is called";
    }
}

class MethodIntercepter {

    private $_instance;
    private static $_className;

    public function __construct($instance) {
        $this->_instance = $instance;
        $ref = new ReflectionClass($instance);
        self::$_className = $ref->getName();
    }

    public function __call($method, $arguments) {

        $timeStart = microtime(true);
        $ret = call_user_func_array(array($this->_instance, $method), $arguments);
        $timePassed = microtime(true) - $timeStart;
        $timePassed *= 1000;        
        $calledMethod = self::$_className . "->{$method}";
        $calledMethodArgs = json_encode($arguments, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        echo "{$calledMethod}({$calledMethodArgs}):{$timePassed}ms<br />";
        
        return $ret;
    }

    public static function __callStatic($method, $arguments) {

        $timeStart = microtime(true);
        $ret = call_user_func_array(array(self::$_className, $method), $arguments);
        $timePassed = microtime(true) - $timeStart;
        $timePassed *= 1000;
        $calledMethod = self::$_className . "::{$method}";
        $calledMethodArgs = json_encode($arguments, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        echo "{$calledMethod}({$calledMethodArgs}):{$timePassed}ms<br />";
        
        return $ret;
    }
    
    public function __get($key) {

        return $this->_instance->$key;
    }

    public function __set($key, $value) {

        $this->_instance->$key = $value;
    }
}

$hoge = new Hoge();
$hoge = new MethodIntercepter($hoge); // MethodIntercepter でくるむ
echo $hoge->getPHoge() . '<br />';
echo $hoge->getHoge() . '<br />';
echo $hoge->hoge . '<br />';
$hoge->hoge = "hoge prop is changed";
echo $hoge->hoge . '<br />';
echo $hoge::getHogeStatic() . '<br />';
echo Hoge::$hogeStatic . '<br />'; // $hoge::$hogeStatic はできない @see http://stackoverflow.com/questions/1279382/magic-get-getter-for-static-properties-in-php
?>
</body>
</html>
```

### 実行結果

![スクリーンショット 2015-03-29 17.38.38.png](https://qiita-image-store.s3.amazonaws.com/0/53629/905a0a66-fa43-d8e6-abe2-dd5aece11976.png)

## 使い方

1. MethodIntercepter というクラスを定義します
2. 計測したいインスタンスを MethodIntercepterでラップします

これだけで、計測したいインスタンスのメソッドの呼び出し全てに対して実行時間を計測できるようになります。
MVCなどで、Controllerに設定されるModelインスタンスに対して適用するなどすると便利です。
OSXからRaspberryPi2にリモートデスクトップ接続する

RaspberryPi2（raspi2）をいじくるとき

* いちいちHDMIケーブルを挿してモニタに接続するの面倒くさい
* sshでも接続できるけどできたらGUIで

がきっかけです。x11vncを使います。

## 環境
* ターゲット：RaspberryPi2 Model B（デスフラッシュ仕様w）
* OS：Raspbian

## 前提
* Raspbianの初期設定（raspi-configでするやつ）が完了していること
* raspi2がネットワークに接続されていること  
たぶんLANケーブル挿すだけでIPアドレスがふられるはず

# raspi2側
#### SSHでraspi2に接続する
`$ ssh -l <username> <IP Address>`
#### x11vncをインストールする
`$ sudo apt-get install x11vnc`
#### x11vncの起動パスワードを設定する
`$ x11vnc -storepasswd`
パスワード入力＆ベリファイします。
パスワード設定無しでも起動できますが、念のため設定しておきます。
#### X Windowの起動
Raspbianを GUIで操作するため、X を起動します。
`$ startx`
なお、raspi2起動時にXが開始するように設定している場合、このstartxコマンドの実行は不要です。
そうではなく、startxコマンドを実行した場合、Xを起動させたターミナルはこれ以上操作できません。ですので、これ以降の作業はターミナルの別タブをもう一枚開いてから、再度SSH接続でログインして行います（ターミナルのメニュー → 表示 → タブバーを表示 で タブバーの +マークをクリック）
また、X の起動ログに`FATAL: Module g2d_23 not found.`と表示されますが、起動はしているようなのでまぁよいとしますw
#### x11vncを起動する
`$ x11vnc -usepw -forever`
私の環境では、-forever を指定しないと、OSXから接続後まもなくセッションが切れ、x11vncが落ちるので指定しています。
また、起動ログの最後のほうに
`The VNC desktop is:      raspberrypi:0`
`PORT=5900`
とあるのでポート番号を覚えておきます。これでraspi2側の設定は終わりです。

# OSX側の設定
特別な設定はありません。Finderのメニューから 移動 → サーバへ接続 を選択すると接続先を訊いてくるので、サーバアドレス欄に
`vnc://<IP Address>:5900`
と入力します
IP Address はraspi2のものです。ポート番号（5900）は先ほど起動ログに表示されていたものです。  
接続をクリックするとパスワードを訊いてくるので入力します。

![raspi2_x11vnc.png](https://qiita-image-store.s3.amazonaws.com/0/25351/dc6cb644-07d5-7691-3cf1-efca18b61daf.png)

画面サイズをもう少し大きくしたいな・・・

***

できました！
![1920x1680.png](https://qiita-image-store.s3.amazonaws.com/0/25351/b2443d9e-6151-adea-8c23-447db2c39bb6.png)
npmでグローバルにインストールしたモジュールを確認

npmコマンドで確認する方法

```
npm ls -g --depth=0
```

grepを使っても良い

```
npm ls -g | grep "^├"
```

以下のディレクトリの中身を確認しても良い

```
/usr/local/lib/node_modules
```
Rails Tutorial-第7章メモ_part2


##リスト7.16のテストについて

###
今回出てきた、fill_inメソッド周辺がよくわからなかったので、少しだけ調べてみた。


####リスト7.16 ユーザー登録の基本的なテスト

```ruby:user_pages_spec.rb

require 'spec_helper'
  2 describe "User pages" do
  3 
  4 #RSpec.describe "UserPages", :type => :request do
  5 #describe "GET /user_pages" do
  6  #   it "works! (now write some real specs)" do
  7   #    get user_pages_index_path
  8    #   expect(response).to have_http_status(200)
  9     #end
 10   #end
 11 #end
 12 
 13   subject { page }
 14 
 15   describe "profile page" do
 16     let(:user) { FactoryGirl.create(:user) }
 17     before{ visit user_path(user) }
 18 
 19     it{ should have_content(user.name) }
 20     it{ should have_title(full_title(user.name)) }
 21   end
 22 
 23   describe "signup page" do
 24     before { visit signup_path }
 25 
 26     it{ should have_content('Sign up') }
 27     it{ should have_title(full_title('Sign up')) }
 28   end
 29 
 30   describe "signup" do
 31     before{ visit signup_path }
 32 
 33     let(:submit){"Create my account"}
 34 
 35     describe "with invalid information" do
 36       it "should not create a user" do
 37         expect{ click_button submit }.not_to change(User, :count)
 38       end
 39     end
 40 
 41     describe "with valid information" do
 42       before do
 43         fill_in "Name",         with: "Example User"
 44         fill_in "Email",        with: "user@example.com"
 45         fill_in "Password",     with: "foobar"
 46         fill_in "Confirmation", with: "foobar"
 47       end
 48 
 49       it "should create a user" do
 50         expect { click_button submit }.to change(User, :count).by(1)
 51       end
 52     end
 53   end
 54 end                              

```

Capybaraのメソッド``fill_in``は、フォームへの入力をシュミレートするらしい。

```
visit signup_path

fill_in "Name",         with: "Example User"
fill_in "Email",        with: "user@example.com"
fill_in "Password",     with: "foobar"
fill_in "Confirmation", with: "foobar"
```

``fill_in "Name", with: "Example User"``

例えば上記を実行することで、``fill_in``後の"Name"に、``with``後の文字列、"Example User"が入力されたことをシュミレートできている。

このブロックでは上記のシュミレーションを実行した後、

``expect { click_button submit }.to change(User, :count).by(1)
``

ここで``change``メソッドを用いてボタンクリック前後のユーザー数が1だけ変化しているかどうかを観測している。

またこの``exepct``メソッドは、従来の``should``メソッドと同等のものらしい。よって書き換えも可能で、

``expect { click_button submit }.to``

↓

``{ click_button submit }.should``

と書き換えられる...と思ったのだが。

どうやら``should``ではブロックを扱うことができないらしい。

よって正しくは

``submit { click_button }.should``

とする必要があった。

見た目的に、``expect``の方がすっきりしてイイネ。
ssh-addできなかったときへの対処

Windowsのgit bash上でssh-addしようとして、`Could not open a connection to your authentication agent.`と出たのでメモ。Windowsのお話です。

ssh-agentを起動するコマンド, `ssh-agent`を打ってからじゃないとssh-addできないということ（おそらくWindowsだからって話）なんだけど、Windowsだと更にひとくせあって、`` $ eval `ssh-agent` ``じゃないといけないらしい。

下記を、Windows7, Git bash上で実行して解決しました。

```
$ ssh-add ~/.ssh/id_rsa_bitbucket # ssh-addしようとするも、失敗。
Could not open a connection to your authentication agent.

$ ll ~/.ssh # ls -ltr ~/.ssh あたりと同じコマンドです
total 19
drwxr-xr-x    1 user Administ     4096 Mar 29 15:49 .
drwxr-xr-x    1 user Administ    24576 Mar 18 20:15 ..
-rw-r--r--    1 user Administ      290 Feb 13 10:47 config
-rw-r--r--    1 user Administ      680 Feb 12 12:03 id_dsa
-rw-r--r--    1 user Administ     1702 Feb 13 10:30 id_rsa
-rw-r--r--    1 user Administ     1675 Mar 29 15:49 id_rsa_bitbucket
-rw-r--r--    1 user Administ      399 Mar 29 15:49 id_rsa_bitbucket.pub
-rw-r--r--    1 user Administ     2025 Mar 29 15:52 known_hosts

$ ssh-agent # これだと何も起こらない
SSH_AUTH_SOCK=/tmp/ssh-WaUWIb2288/agent.2288; export SSH_AUTH_SOCK;
SSH_AGENT_PID=6064; export SSH_AGENT_PID;
echo Agent pid 6064;

$ eval `ssh-agent` # 正解
Agent pid 10908

$ ssh-add ~/.ssh/id_rsa_bitbucket # ヨッシャああああ！！！
Identity added: /c/Users/{USER}/.ssh/id_rsa_bitbucket (/c/Users/{USER}/.ss
h/id_rsa_bitbucket)
$ git branch # pushしたかったので、branch見る
  develop
* master
$ git pull origin master # 無事pushしました
From bitbucket.org:sshojiro/some-repo
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
Updating e7cb29d..c9eb758
Fast-forward
 libs/+Common/Evaluation.m      | 29 +++++++----------------------
 libs/+Common/FigureGenerator.m | 16 ++++++++++++----
 2 files changed, 19 insertions(+), 26 deletions(-)
```

以上。

## 結局 ssh-agent とは何だったのか (2019/12/26 追記)

Git Bash for Windowsにおける`ssh-agent`とは結局なんだったのでしょうか。気になってきたので調べます。

まず挙動を調べると、乱数で`PID` (プロセスID)とtemporary folderを生成している様子が確認できました。これは、文字列をdumpしているだけです。

```bash
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-BxfRPlTH3nyI/agent.15928; export SSH_AUTH_SOCK;
SSH_AGENT_PID=13268; export SSH_AGENT_PID;
echo Agent pid 13268;
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-1AhcaPKDImvP/agent.4592; export SSH_AUTH_SOCK;
SSH_AGENT_PID=16204; export SSH_AGENT_PID;
echo Agent pid 16204;
```

さて、`ssh-agent`コマンドの実体はどこにあるのでしょう。

```bash 
$ which ssh-agent # コマンドが定義してあるファイルのpathを出力
/usr/bin/ssh-agent
$ file /usr/bin/ssh-agent # ファイルの情報を取得する`file`コマンド
/usr/bin/ssh-agent: PE32+ executable (console) x86-64 (stripped to external PDB), for MS Windows
```

...ソースが読めないのでこれ以上は読めない...残念...

ひとまず、`ssh-agent`は毎回ssh agent (daemon相当だと思います)にPIDとsocketまでのpathを割り当てているようです。
`ssh-agent`自体は(少なくともGit Bash for Windows上では)その割当を乱数で生成するところまでしか担っていないので、ちゃんと`$ eval ｀ssh-agent｀`を実行しないと、`ssh`コマンドが有効にならないということでした。実装上の都合ということですね。
iOSシミュレータのスタックトレースをタップした時にコードを開くエディタを変更する

`REACT_EDITOR` に設定しておく。

https://github.com/facebook/react-native/blob/72d3d724a3a0c6bc46981efd0dad8f7f61121a47/packager/launchEditor.js#L18

```
REACT_EDITOR=atom ./packager/packager.sh --root Examples/UIExplorer/
```