OmniAICreator/Qiita-1.07M huggingface dataset:
AspectJのJoin PointsとPointcutとは何なのか

##はじめに
この記事はAspectJ公式プログラミングガイドを訳したものです。
[公式プログラミングガイド](http://www.eclipse.org/aspectj/doc/released/progguide/language-joinPoints.html)


##Join Points と Pointcut

以下のクラスを例に、考えていきます。

```java:Point.java
class Point {
    private int x, y;

    Point(int x, int y) { this.x = x; this.y = y; }

    void setX(int x) { this.x = x; }
    void setY(int y) { this.y = y; }

    int getX() { return x; }
    int getY() { return y; }
}
```

AspectJのjoin pointsとpointcutをより直感的に理解するために、Javaの基本的な原則に戻ってみましょう。以下のメソッドはPointクラスに宣言されているものです。

```java
void setX(int x) { this.x = x; }
```

このプログラムは、「メソッドの名前は setX　であり、int型の引数を一つ必要とし、Point型のオブジェクトとして呼ばれる。その際に、メソッドの本体である { this.x = x; }　が実行される」ことを表しています。

この事より、一つの様式が明らかになります。それは**何かが起きたときというのは、何かが実行された時である**、ということです。以上の例だと「メソッドの呼び出し　＝　起こる　、　メソッドの実行　＝　実行」という関係になります。

OOPにおいては、様々な種類の”起こる”があり、それらは言語によって決定されます。我々はこれをJavaにおいてJoin Pointと呼びます。Join Pointは例のようにメソッド呼び出しや、メソッドの実行、オブジェクトのインスタンス化、コンストラクタの実行、フィールドの参照のようなもので構成されています。

完全なるJoin Poiuntのリストは[AspectJ Quick Reference](http://www.eclipse.org/aspectj/doc/released/progguide/quick.html)に載っています。

そしてPointcutはこれらのJoin Pointの集合から、いくつかのJoin Point（部分集合）を選択することです。以下はPointcutの例です。

```aspectj
pointcut setter(): target(Point) &&
                   (call(void setX(int)) ||
                    call(void setY(int)));
```

このPointcutの例ではsetX(int)もしくはsetY(int)が、Pointのインスタンスとして呼ばれた際のJoin Pointを選択しています。また、他の例として以下があります。

```aspectj
pointcut ioHandler(): within(MyClass) && handler(IOException);
```
この例ではMyClassというクラス内で定義されたコードにおいて、IOException型の例外がキャッチされた際のJoin Pointを選択しています。

###Pointcutの構成

Pointcutはコロンによって分割された左式と右式によって構成されています。左の式でPointcutの名前、Pointcutのパラメーターによって構成されます。右の式ではPointcut自体で構成されます。
Docker1.10に追加されたEmbedded DNS Serverを試す

Docker1.10からユーザー定義ネットワークを使うと同じネットワーク内のコンテナのIPをコンテナ名で引けるようになりました。
https://docs.docker.com/engine/userguide/networking/configure-dns/

これを使うとコンテナ同士で連携している場合などにコンテナの差し替えがとても簡単になりそうです。
アプリケーションのデプロイもdocker rename(コンテナ名を変更する)で可能になるのではないでしょうか。

##実行例

ユーザー定義ネットワークを作成する

```bash
$ docker network create --driver bridge isolated_nw
```

作成したネットワークを指定して通信先にするコンテナを立ち上げ

```bash
$ docker run -ti --net=isolated_nw --name=foo busybox
```

作成したネットワークを指定して通信元のコンテナを立ち上げて、コンテナ名を使って通信

```bash
$ docker run -ti --net=isolated_nw --name=bar busybox
$ ping foo
PING foo (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=255 time=0.050 ms
64 bytes from 172.18.0.2: seq=1 ttl=255 time=0.061 ms
64 bytes from 172.18.0.2: seq=2 ttl=255 time=0.090 ms

--- foo ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.050/0.067/0.090 ms
```

##デフォルトネットワークのコンテナをユーザー定義ネットワークに接続する

デフォルトのブリッジ(docker0)でコンテナを起動。このままでは先ほどのユーザー定義ネットワークに参加しているコンテナから名前解決できない。

```bash
$ docker run -ti --name=hoge busybox
```

作成済みのユーザー定義ネットワークにコンテナを接続する

```bash
$ docker network connect isolated_nw hoge
```

##余談
docker renameによる簡単デプロイが可能になりそうですがダウンタイムが発生しますね。
docker rename自体は高速なので一瞬だとは思いますが。
複数回のdocker renameをアトミックに行える機能とか追加されたらゼロダウンタイムのデプロイができるのにとかいう妄想が広がります。

追記
docker renameでアプリケーションサーバのデプロイをするとして、前段にNginxがいる構成の場合、NginxのDNSキャッシュがあるのでゼロダウンタイムでのデプロイが可能になるはず。

追記2
1.10.3にはIPv6絡みのバグがあって、名前解決にすごく時間がかかったりする場合があるみたいです。
その現象が発生する場合はホストマシンのIPv6を無効にするととりあえず直ります。
このバグの修正は1.11(4/11リリース)に入るようです。
kintone プラグインを販売してみた

#kintone プラグインを販売するには

最近 kintone プラグインを作るのにハマっていますが、一般的な販売ルートが無いので、販売の負担の少ない方法を考えてみました。

#クラウドソーシングのランサーズで販売
お客様にプロジェクトとして、依頼してもらいプラグインを販売してみましたが、いろいろお客様側の手続きが面倒です。カスタマイズを伴う場合は、いいかもしれません。
プラグイン販売は、別の方法を検討することにしました。

#VECTOR でシェアウェアとして販売
kintone カテゴリーも無いし、公開しても埋もれるだけ。
kintone ユーザは、ここでは誰も買わないだろうと思い、却下。

#独自のECシステムを構築して販売
ECシステム構築は、決済関係の手続きや運用が大変そう。
苦労して作るほど、販売見込みが立たないので却下。

#ダウンロード販売をサポートしているサイトで販売
知らなかったのですが、ソフトなどのデジタルコンテンツを販売できるサービスが、いつの間にかありました。
[ダウンロード販売のできるサービスをまとめました](http://matome.naver.jp/odai/2140246651338211101?&page=3)
ここで、紹介されているサービスをいくつか試してみて、STORES で販売してみることにしました。

[rex0220 stores](https://rex0220.stores.jp/)
なんの飾りもなく、そっけないデザインでプラグインしか無い怪しげな店です。
それでも、無料で商品を５点まで販売できるというのが素晴らしい。
手数料は５％と、他の方法よりもかなり低額。
商品画像は説明資料の使いまわしで、商品登録にもあまり工数をかけていません。
ありがたいことに、こんなお店でも数は少ないですが、お客様にご購入していただけました。
もう少し説明を追加してもいいかもしれませんが、売れてサポートが大変になると困るし。
でもあまり売れないと寂しいので、ここに公開。

#プラグインの値段について
現在、各社から提供されている有料のプラグインは、売切りと月額使用料のものがあります。
STORES でサポートしている販売形態は、売切りだけです。

プラグインの機能を独自で開発するよりは安く、５万円に設定してみました。
フィールドコード設定プラグインは、アプリ開発者しか使わないと思われますので、５千円。
まあ、相場というものも無いので、値付けは感覚的なものです。開発工数はそんなに違いません。
クラウドソーシングによるシステム開発の価格破壊が進んでいますが、アプリ毎に実装したらさすが５万円では出来ないはず？

#今後のプラグイン開発について
いろいろ小物を作るのが好きなので、プラグインは暇が出来ると一気に作っています。
中身の処理は、使いまわしが効くので、作りやすいのもあります。
これから作ってみたいのは、いくつかありますが、なんとなくアイデアが出てきたらそれを優先するのでどうなるかは未定。
ユーザが欲しいものと少しギャップがあるかもしませんが、作りたいものを作れるので問題なし。

- ルックアップ関連　なんで標準機能で自動更新しない？
- 関連テーブル　なんかフォーマットを指定したい
- デザインテーマ　試作版を使っていると、個人的には十分。売り物にするには、直したいところがある。
- 一覧画面で、コピペでまとめて入力したい。
- 帳票関連　CSS でなんとか形にできないかと思いましたが、設定が一般ユーザが出来なくなる
- 自動採番　MAXレコード番号だと、処理が重なるとダブル気がする。

ものによっては、プラグインではなくテンプレートになるかもしれない。
エンジニアのハマり時間とその技術的難易度の相関関係

めちゃくちゃにハマったからと言って、その問題は技術的難易度が高い訳ではないんじゃね？という話。
ここで言う「ハマる」とはなにかに夢中になって没頭することではない。バグとかエラーがあって、なかなか解決できなくてそのために時間を割かれてハマる、の「ハマる」。

先日、ハマった問題が解決した時の感情は「ついに解決したぞ」という安堵感と「しょーもないハマりポイント作りやがって、あのボケが！」という前任者への怒りが混ざった状態だった。

サイトのSSLの有効期限切れが２週間後にせまっていた。やる事は証明書の更新、新しい証明書をAWSのELBに入れること。ただこれだけ。しかしハマった。どうやってもELBから「あなたのキーは無効です」みたいなエラーメッセージが返ってきた。２年前にSSLを設定したエンジニアは退職してしまって、もう居ない。その前任者とほぼ同じことをすればOkなはずなのに、なぜかできなかった。

ググっていろいろ調べてpemファイルのフォーマットをopensslコマンドで変換したりして入れるのだが、一向にエラーが解決しない。期限は２週間後に迫ってるしどうしよう、と焦った。

詳しく内容説明しても面白くもなんともないので省略するが、要は以下の３つの枠内にそれぞれのキーを入れるのだ。

<img width="512" alt="20160323124006 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/108761/3a42e73e-86a1-c376-1583-785a64a400ca.png">

あまりにできないので３日ほど放置して、ふと「もしかして秘密鍵が違うのかも」と考えた。今の会社では２０以上のプロジェクトがあって、それぞれの秘密鍵は＜プロジェクト名＞.pemという名で保存されている。もちろん今回もその＜プロジェクト名＞.pemを使っていたのだが、ここまでエラーが返ってくるということは、前任者はこの秘密鍵とは異なる鍵を使って証明書を発行したのかもしれない、と考えた。そこであらゆるところを探して社内にあるいろんなpemファイルを入れて、総当りで試してみた。するとあるフォルダからその＜前任者の名前＞.pemなるファイルが見つかった。ここでは仮にその前任者の名前をのび太として「のび太.pem」とする。いくらなんでも「のび太.pem」はないだろ、と思ったが一応試してみた。すると見事に前回の証明書と合致して、新しいのに更新されELBに入ったのだ。

だいたい大切に保管しなければならない証明書をありえない場所に保管しておくのもどうかと思うし、いつもの正しい場所に正しい名前で置いてあったが役には立たない＜プロジェクト名＞.pemは人をおちょくるためだけに置いてんのか？というのと、正解のファイルの名前が「のび太.pem」でファイルを眺めているだけで、のび太に対する怒りがフツフツとこみあげてきた。腹立たしい事この上ない！おい、のび太！テメーしょうもない地雷設置して会社辞めやがって、マジええかげんにしとけよ、このクソボケがぁああー！！！


しかし今回の件と歴代のハマった内容を思い返してある結論に達した。それはハマり時間に比例して技術難易度が高くなる訳ではない、ということだ。

例えば１時間悩んで解決した問題と１００時間悩んで解決した問題を比較した場合に必ずしも１００時間の方が１００倍技術的難易度が高度か？というとそうでもない。
このグラフに示すように考えがちだが、現実はちょっと違う。

<img width="512" alt="20160323124139.png" src="https://qiita-image-store.s3.amazonaws.com/0/108761/a707edc2-4c85-a025-5ecd-4dda55633adf.png">


実際はこのようなグラフの方が実感としてはしっくりくる。

<img width="480" alt="20160323124153.png" src="https://qiita-image-store.s3.amazonaws.com/0/108761/e23b5268-6f59-6706-5320-9ad71df8f5a0.png">

もう１日悩んで解決できなかったら、だいたいその技術難易度は低い。
最初の５時間ぐらいまではそのハマり時間に比例して技術的難易度は高くなる傾向がある。どんなエンジニアでも５時間とかググッて調べまくったら、その件に関しては相当な知見が貯まる。その詳しくなったエンジニアの知識を持ってしても解決できない場合、もうほとんど問題の根本は技術じゃないことが多いのだ。１日経っても解決できなかったら、それは技術どうこうではなく、前述の例でいうフォルダからファイルを探す、みたいな極めてローテクな内容を試してみるのもいい。

ハマった時ほどこのグラフにあるように考えようと思った。

**ハマった時は怒らない、焦らない、落ち込まない、感情を乱さない。足元にあるとても基本的なことに目を向け、冷静に冷静にひとつひとつ確かめるべし。**

自戒をこめてここに書いた。
 
---

最近こんなの作りました。目標設定の際にはぜひご利用ください。

[お金を賭けた目標設定でハラハラドキドキ達成させるサイトを作った【個人開発】](https://qiita.com/jabba/items/85ca69f6f690c2151316)
GoogleTagManager と GoogleAnalyticsについて

#GoogleTagManagerわかりにくい
使ってみようと思ったが、コンテナ・タグ・トリガ・変数って何!?ってなった。
ので自分なりに把握した概要を備忘も兼ねて残しておきます。
※ページビューとイベントのトラッキングしか試してないです。

概念把握してから下記読めば理解しやすい。
https://support.google.com/tagmanager#topic=3441530

##そもそも何したいんだっけ？
そもそも分析したいんだよね、ってとこから考えるのがわかりやすかった。

分析したいってのはこういう事。
1.何をしたときに
2.何をカウントしたいか
3.(何の軸で)

##これらの情報をGoogleTagManagerの概念にあてはめると
####1.何をしたときに
・トラッキングタイプ
・（トラッキングタイプに「イベント」を指定している場合）トリガー
が相当する概念です。 
####2.何をカウントしたいか
タグ作成画面の
・イベントトラッキングパラメータ
・その他の設定>設定するフィールド
が相当する概念です。

####3.(何の軸で)
タグ作成画面の
・その他の設定>カスタムディメンジョン
が相当する概念です。

#トリガーの発火タイミング
https://support.google.com/tagmanager/answer/6106961?hl=ja
###カスタムイベントについて
イベント名に「test-event」と指定した場合、
自サイトのjavascriptで
dataLayer.push({ ‘event’: ‘test-event’ });
って書けば動く。

#変数がある意味
「2.何をカウントしたいか」で例えばエナジードリンクの購入ボタンが「朝・昼・夜」のいつに押されているかをカウントしたいとすると、
エナジードリンク購入ボタン押したときに動くタグに対して、
「タイミング」というフィールドを追加して、
その値に
毎朝に「朝」
毎昼に「昼」
毎夜に「夜」
と設定を書き換えてあげれば統計が取れます。

で、これは馬鹿らしいので、値に変数が指定できるようになってます。

変数の値を変えるだけで、設定を変更しないで利用ができます。

変数はカスタムディメンジョンやフィールドなんかに渡しせます。

##変数って何の値が取れるの？
###有効な組み込み変数
GoogleTagManagerではデフォルトの変数として「有効な組み込み変数」を持っていて、pageの名前とかクリックされたボタンのクラスだとかが変数になってます。
###ユーザー定義変数
「これだと足りないよ」「サイト内の独自の情報を集計したいんだよ」って人のためにGoogleTagManagerでは「ユーザー定義変数」が指定できます。

例えばDOM要素のあるattribute(例えばdata-test)の値をとりたい場合は
　種類:「DOM要素」
　選択方法:「CSSセレクタ」
　要素セレクタ:data-test
と指定した変数を作れます。

例えば自サイトのある情報の値(例えばtest-value)をとりたい場合は、
　種類：「データレイヤーの変数」
　データレイヤーの変数名:「test-value」
と指定した変数を作成します。
そして自サイトのjavascriptで
dataLayer.push({"test-value":"ほげほげ"});
と書けば送れます。

##その他
どんなフィールドがあるの？
http://www.kagua.biz/help/reference/overridethefield.html

#UserIdを有効化したGoogleAnalyticsのビューでTagManagerのイベントが表示されない件
http://qiita.com/ssaita/items/ccdda4035fa9c9d595c0
上記のようにタグの「&uid」フィールドにuserIdを渡してあげないと表示されない。
下記はGoogleAnalyticsでの「User-ID ビューの作成」の部分からの抜粋。
>User-ID ビューはフィルタリングされています。このビューのレポートには、User-ID で検出されたセッションからのデータが表示されます。User-ID が検出されていないセッションからのデータを見るには別のビューを使用します。
AnsibleでcentOS7を再起動する

今までは下記のように書いていたが、なんかうまくいかない

```yaml:main.yml
- name: サーバ再起動
  shell: shutdown -r now
- name: OS再起動待ち
  pause: minutes=5 prompt="OS再起動待ち5分"
```

と思ったらここ↓にそのまま答えが書いてあった
http://connvoi.com/blog/tech/2016/03/03/reboot-ansible.html

ただ、今回は
~/roles/reboot/task/main.yml
に記述するので

```yaml:main.yml
- name: restart machine
  shell: sleep 2 && shutdown -r now "Ansible updates triggered"
  async: 1
  poll: 0
  sudo: true
  ignore_errors: true

- name: waiting for server to come back
  local_action: wait_for host={{ inventory_hostname }} state=started delay=10 timeout=300
  sudo: false

```

```ansible:ansible_hosts
[ansible-base]
ansible_base ansible_ssh_host=XXX.XXX.XXX.XXX
[all:vars]
inventory_hostname=XXX.XXX.XXX.XXX
```

と、こんな感じ
UIActivityViewControllerを使ってTwitterへ画像が投稿できない症状


が起きているようです。ただし大多数のアプリは問題無く動作しているはずです。

## 2016/05/19追記

Twitter バージョン6.53.1、iOS 9.3.1 環境にて無事に動作する事を確認しました。
（やはりTwitterアプリ側の問題だったのではないかと思われます）

## 再現コード

single viewプロジェクト作成、test.pngをプロジェクトに突っ込んであります。

```swift:
import UIKit

class ViewController: UIViewController {
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        guard let path = NSBundle.mainBundle().pathForResource("test", ofType: "png") else { return }
        let url = NSURL(fileURLWithPath: path)
        let vc = UIActivityViewController(activityItems: [url, "あいうえおかきくけこさしすせそたちつてと"], applicationActivities: nil)
        presentViewController(vc, animated: true, completion: nil)
    }
}

```

## 実行結果

投稿画面は正しく出ますが

![Screen Shot 2016-03-23 at 16.35.45.png](https://qiita-image-store.s3.amazonaws.com/0/31347/92489a87-9809-62d9-884f-9be4b9c12222.png "Screen Shot 2016-03-23 at 16.35.45.png")

Twitterアプリへ行くと...

![Screen Shot 2016-03-23 at 16.37.02.png](https://qiita-image-store.s3.amazonaws.com/0/31347/86c3c30a-6d3b-1db6-acd7-1ac5f514aa34.png "Screen Shot 2016-03-23 at 16.37.02.png")

下書きを見に行くと、パスが本文に入っちゃって文字数オーバーし、投稿にしくじっている事がわかります。

![Screen Shot 2016-03-23 at 16.37.22.png](https://qiita-image-store.s3.amazonaws.com/0/31347/5c9b0a77-22da-96c0-cd00-7c52958d51ca.png "Screen Shot 2016-03-23 at 16.37.22.png")

## 考察

画像パスから`NSURL`オブジェクトを生成し、そいつを`UIActivityViewController`に渡すと、2016年3月23日現在（Twitter バージョン6.49, iOS9.3）このような症状が起こるようです（＊以前はこのようなことはありませんでした）。

中の仕組みがどうなっているかは判りませんが、おそらくTwitter公式アプリの方で`NSURL`の情報をうまくさばけない不具合が起きているのではないかと推測しています（というかそうであってほしい）。

ちなみに`UIImage`を直で渡している場合は特に問題は起きていませんので、大多数のアプリは影響を受けていないと思われます。
自分のアプリはどうしてもPNGやGIFといった素のバイナリデータを共有したかったためにこのような問題に当たりました。

Twitterの開発者サイトのフォーラムにも同じ報告が挙がっていたので、しばらくは様子を見るしかなさそうです。
https://twittercommunity.com/t/bug-in-ios-twitter-app-when-sharing-images-as-nsurl-with-uiactivityviewcontroller/63252
（小技）Windowsのフォルダやファイルの最終更新日時を修正する

Windowsフォルダやファイルの更新日時を意図的にいじりたい時の小技
フリーソフトを使わずにPowerShellで割と簡単にできちゃいます

①コマンドプロンプトを開く

②PowerSherllを起動する
`powershell`

③以下のコマンドを実行する。（「2016/03/26 10:00」に書き換える ）
`Set-ItemProperty "フォルダやファイルのパス" -Name LastWriteTime -Value "23/03/2016 10:00"`
Rails上で、CSVファイルを読み込んでみた

# やりたいこと

CSVなどのスプレッドシートから一気に読み込みたい。
（新規にシステムを作ったりするときにありがち）

# 前提

- Rails 4.2.5（4.x系）　SQLiteを使用
- すでに登録対象のモデルが存在する。

登録対象のモデルに関しては、

objectという名前で
- name:string
- status:integer
- content:text

を持つと仮定する。

# 実装

ここを参照にした。ほぼこれに近いけど少し違うって感じ

http://ruby-rails.hatenadiary.com/entry/20141120/1416483136

- ビューに、ファイルを指定してアップロードする処理を呼び出す機能を実装
- コントローラに、ファイルの受け取りとリダイレクト処理を実装
- モデルに、内容に基づいた保存処理を実装
- ルーティングの設定

## ビューの実装

アップロード箇所を実装したい表示させたいビューに、こんな感じの実装を行います。


```rails:実装箇所
<%= form_tag({controller: "objects", action: "import", method: "post"}, {multipart: true}) do %>
  <%= file_field_tag :file %>
  <%= submit_tag "オブジェクトを一括インポート" %>
<% end %>
```

## コントローラの実装

コントローラは元々ビューやモデルに対する処理を呼び出したりする部分なので、ここではモデルに実装するDBアクセス処理の呼び出しと、リダイレクト処理を実装する。

さっきのビューでは、objectsのコントローラ、にimportという操作をpostメソッドでアクセスする。という意味合いになる。

```rb:app/controllers/objects_controller.rb
  def import
    Object.import(params[:file])
    redirect_to "/object"
  end
```

ここでは、読み込みファイルを引数として、モデルに実装したimportメソッドを呼び出し処理を行った上で、 /object の一覧ページにリダイレクトするという意味合いになる。

## モデルの実装

モデルでは、対象のファイルを読み込み１件１件バリデーションして登録する処理を実施している。

関係ある箇所だけ抜粋。

例によってパラメータの精査も忘れず実施。

```rb:app/models/object.rb
  def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|

      obj = new
      obj.attributes = row.to_hash.slice(*updatable_attributes)

      obj.save!
    end
  end

  def self.updatable_attributes
    ["name","status","content"]
  end
```

# ルーティングの修正

関係のあるところだけ抜粋

```rb:routes.rb
  #objects に限り、post で import 処理を許可する
  resources 'objects', only: :index do
    collection { post :import }
  end
```
WordPress上でマルチバイト名のファイルを扱った時の問題

WordPressのデプロイやバックアップをしていたのですが、
「極端に長い日本語名のメディアファイル」が何件かあり、そこで不具合が発生し苦戦した件について。

なお、WP Multibyte Patchを使ってファイル名を強制的にMD5化する処理はSEO対策上使用不可能。

# 概要

BackupWpを使ってWordPressサイトを丸ごとバックアップしようとしていたら・・・

極端に長いファイル名の時だけ警告が出て、そのファイルの名前が一部`%A1Qiitaのロゴ（以下略）` みたいにエンコードされたようになったり、全角文字から始まるファイルは完全に対象外になり、半角英数字の部分だけ残りファイル　とみなされてしまう珍現象が発生した。

# 発生条件

極端に長いファイル名が一部エンコードしたようになり、欠損する現象は、圧縮形式をTar.Gzip（初期設定）にした時に発生する。

一方、全角文字から始まるファイルが完全に対象外になったりする現象は、圧縮形式をZipにした時に発生する。


# 対応

圧縮形式は Tar.Gzip を採用。Zip形式は使わない。
・・・と言うのも、これらのファイルを扱うのはWebエンジニアなので、
Windows環境では見慣れない拡張子を使っていても問題ない。

マルチバイト名のファイルの使用はOK。ただし長すぎるとファイル名を正しく保存することが不可能なので使用を控えるように依頼。
AWS Lambdaでサポートに問い合わせる前に（S3イベント編）

AWS LambdaではLambdaファンクションに指定したイベントソースで発生したイベントに応じてファンクションがInvokeされるのですが、イベントが発生したはずなのにファンクションが思ったようにInvokeされない！と悩むときがあるかと思います。そんなときイベントソースがイベントを送ったかどうか確認したくなるのですが、実はこれはユーザ側では難しかったりします。

というわけでそういった場合はサポートに問い合わせて調査をしてもらうわけですがイベントソースがS3の場合に**サポートへ問い合わせる上で最低限必要となるのが2種類のリクエストID**です。気をつけなければいけないのはこれらは**通常のアクセスログ等には記録されていないのでユーザ側で取得・記録する必要がある**ということです。また、状況に応じて必要になる情報は異なるので、これらだけで必ずしも原因が特定可能というわけではないこともお伝えしておきます。少なくともS3側でイベント通知の発生有無の調査には少なくともこの2種類のリクエストIDが必要ということです。

詳細は[ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/troubleshooting.html)にも記載があるのでそちらを参照頂くとして、ここでは簡単に要点のみまとめます。

必要となるのはx-amz-request-idとx-amz-id-2という2つのリクエストIDです。そしてこれらはイベントの発生元となるオブジェクト操作リクエストに対するレスポンスとしてのみ取得可能です。従ってこれらをS3のオブジェクト操作リクエストを発行する側で取得した上で何らかの手段で記録しておく必要があります。やり方としてはクライアント側でログファイルに記録する方法もありますし、モバイルなどの場合、ログ記録用のAPIなどを用意して別途サーバサイドに送って記録する方法もあります。

実際にこのリクエストIDの値を確認するには、いくつか方法がありますが簡単に試せるものとしてブラウザからS3上にリクエストした際のエラーページです。例えばS3で静的Webサイト配信の機能を利用して配信している場合にブラウザ上のアドレスバーに存在しないオブジェクトを含むURLを入れて表示すると以下のようなレスポンスが表示されます。

![Screen Shot 2016-03-23 at 2.42.20 PM.png](https://qiita-image-store.s3.amazonaws.com/0/30135/5cbeda74-b695-27f6-3e1e-9662b21a0559.png)

ここで表示されているRequestIdとHostIdがそれぞれx-amz-request-idとx-amz-id-2に対応します。
成功したリクエストでこの値を確認する場合にはレスポンスヘッダを確認する必要があります。最近のブラウザだと開発者ツールなどが提供されていて確認することが可能です。例えばchromeの場合であれば「Developer Tools」を起動した上でリクエストすることでそのリクエストに対するレスポンスのヘッダが確認できます。以下のような感じです。

![Screen_Shot_2016-03-23_at_2_46_02_PM.png](https://qiita-image-store.s3.amazonaws.com/0/30135/914b5341-eeb5-d98b-ebf0-769e97e9c474.png)

この赤枠で囲った部分が必要となるリクエストIDです。

また、各言語のSDKではログ出力がサポートされています。詳細な設定方法は上記ドキュメントや各言語のドキュメントを参照頂くとして、Javaの場合は個別の出力も可能となっています。
例えば以下のように出力します。

```java

DefaultAWSCredentialsProviderChain credentialProviderChain = new DefaultAWSCredentialsProviderChain();
AmazonS3Client client = new AmazonS3Client(credentialProviderChain);
PutObjectRequest req = new PutObjectRequest("sample-bucket", "sample.json", new File("sample.json"));
client.putObject(req);
S3ResponseMetadata md = client.getCachedResponseMetadata(req);
System.out.println("x-amz-request-id: " + md.getRequestId() + " x-amz-id-2: " + md.getHostId());

```

あとはここで取得した値をクライアントサイドでローカルファイルにロギングすることも別途サーバサイドに送ってロギングすることも可能ですね。
誕生日から年齢を簡単計算

#美墨なぎさの年齢を求めてみる
```rb
birthday = Date.parse('1990-10-10') 
(Date.today.strftime('%Y%m%d').to_i - birthday.strftime('%Y%m%d').to_i) / 10000
#25@2016-03-23 
```

冷静に考えてみたら当たり前なんだけど、頭いい計算方法だな。
Yearの引き算と、誕生日を越えてなければ1引く処理が一つにまとまってる。
Dataframe to JSON (一形式の)


## はじめに

- data.frameのものをJSONファイルに出力するのが目的
- 色々方法がありますが、欲しい形式のJSONにするものが無かったので、ちょっと処理を書いてみた

## 出力したいJSONの形式

- とあるデータベースへのインポートが楽な以下の形式を目指す

```
$ head aaa.json
{"Sepal.Length":"5.1","Sepal.Width":"3.5","Petal.Length":"1.4","Petal.Width":"0.2","Species":"setosa"}
{"Sepal.Length":"4.9","Sepal.Width":"3.0","Petal.Length":"1.4","Petal.Width":"0.2","Species":"setosa"}
{"Sepal.Length":"4.7","Sepal.Width":"3.2","Petal.Length":"1.3","Petal.Width":"0.2","Species":"setosa"}
{"Sepal.Length":"4.6","Sepal.Width":"3.1","Petal.Length":"1.5","Petal.Width":"0.2","Species":"setosa"}
<snip>
```

## df to json

```
df <- iris
head(df)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa
vec <- apply(df, 1, RJSONIO::toJSON)
vec %>% gsub("\n", "", .) %>% gsub(" ", "", .) -> vec
write(vec, file = "aaa.json")
```

- [Strategies for formatting JSON output from R](http://stackoverflow.com/questions/8288925/strategies-for-formatting-json-output-from-r)が参考になりましたが、欲しい形式までもうちょい。
- ポイントは、RJSONIO::toJSONを使うところ。jsonlite::toJSONだと、違う形式で出力されるので、うまくいかなかった。
- [この記事](http://notchained.hatenablog.com/entry/2014/05/04/010248)でも言及されているが、jsonliteが元と同じではない模様
websocket-railsでチャネルに対してtriggerしても、サーバ側でイベントルーティングされない

# 概要
チャットルームのように、特定の部屋に入っているユーザにのみメッセージを送受信しようと、WebScocket-railsのチャネル機能を利用しようとしてハマったのでメモ。

ruby 2.2.2
rails 4.2.6
websocket-rails 0.7.0 712fd4e

# 結論
タイトルおよび、下記参考URLに記載されている通り、チャネルに対してtriggerしても、サーバ側でイベントルーティングされない。

このため、trigger（javascript ⇒ Railsの送信）は、チャネルではなく大元のディスパッチャに対して行い、bind（Rails ⇒ javascriptの送信）は、チャネル毎に行うのが良いと思われる。

# 詳細
特定のチャネルに接続しているクライアントに対してのみデータを送受信するには、以下のchannerl_dispatcherように、特定のチャネル名を指定したディスパッチャを作成する。

```chat.js
ws_dispatcher = new WebSocketRails("localhost:3000/websocket");
channel_dispatcher = ws_dispatcher.subscribe(room_name);
```

ただし、

```chat.js
ws_dispatcher = new WebSocketRails("localhost:3000/websocket");
channel_dispatcher = ws_dispatcher.subscribe(room_name);

channel_dispatcher.trigger("new_message", {msg_body: comment});

channel_dispatcher.bind("new_message", function(message){
// 以下省略

```

などとした場合、events.rbにはnew_messageイベントは入ってこなかった。

この場合でも、複数のブラウザ間でルーム内に限定したメッセージの送受信は実際に動作していたため、events.rbを通らずともjavascript間でtrigger ⇒ bindできているようであった。
（あくまでもチャットは動いているため、events.rb⇒チャット用コントローラを経由しているはずと思い込んでしまう可能性があるので注意）

websocket-railsのwikiによると、chanelを利用した場合は、イベントルーティングの対象外となるが仕様のようだ。

結局、triggerはチャネルを利用せず、メッセージにチャットルームを表す識別子を含めた上で大元のディスパッチャを経由してサーバへ送信、コントローラ内でチャットルームを区別して、ルーム毎のチャネルに対してcastするようにするのが良いと思われる。

```event.rb
  subscribe :new_message, to: WebsocketChatController, with_method: :new_message
```
```chat_controller.rb
  def new_message
    # クライアントからのメッセージを取得
    recieve_message = message()
    WebsocketRails[recieve_message[:room_name]].trigger(:cast_new_message, recieve_message)
  end
```

```chat.js
  WebSocketRails("localhost:3000/websocket");
  channel_dispatcher = ws_dispatcher.subscribe(room_name);

  // メッセージ送信時の処理
  $('#send').click(function(){
  // room_name = document.getElementById("room_name").innerText;
    comment = $("#comment").prop("value");
    ws_dispatcher.trigger("new_message", {room_name: room_name, user_name: user_name, msg_body: comment});
  });

  // メッセージ受信時の処理
  channel_dispatcher.bind("cast_new_message", function(message){
    message_li = document.createElement("li");
    message_li.textContent = message.room_name + " | " + message.user_name + " | " + message.msg_body;
    document.getElementById("chat_area").appendChild(message_li);
  });
```

(上記では、大元のディスパッチャに送るか、チャネル毎のディスパッチャに送るかで、"new_message"と、"cast_new_message"とにイベント名を分けているが、判りやすくするためそうしているだけで、同じイベント名でも問題はないはず）

# 参考
[[websocket-rails wiki ：Working with Channels]](https://github.com/websocket-rails/websocket-rails/wiki/Working-with-Channels)

感謝
VeriloggenをWindowsで使ってみる以前

#要約
PythonでVerilog書けるライブラリ[Veriloggen](https://github.com/PyHDI/veriloggen)をWindows+VisualStudioで使おうとした。
そしたらシミュレーション関係でエラーでたので、やっつけ修正した。

#使ってみようとする
暇になったので、前々から気になっていたVeriloggenを使ってみる。
ついでにPythonも初めて使う。

とりあえずVSのPython拡張をさくっとインストール
ゆとりなのでIDEの支援がないと何もできない。

仮想環境とやらをVS上で作りVeriloggen及び依存パッケージをpipで導入

サンプルコードを実行してみると

```
...
endmodule


C:\Users\*******\AppData\Local\Temp\tmp16lswu9y: Permission denied
No top level modules, and no -s option.
'.' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```
オウフ

#やっつけ修正を試みる

なにやらシミュレーションでこけているようなので、
Veriloggenの`simulation.py`を見てみる。

まずPermissionどーたらのほう。

```py3:simulation.py
tmp = tempfile.NamedTemporaryFile()
tmp.write(code.encode(encode))
tmp.read()
filename = tmp.name

cmd.append(filename)

# synthesis
p = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE)
```

Permissionがどうのこうの言っているのだから
この一時ファイルがなにかうまく行っていないのだろう。

いろいろ調べると`tempfile.NamedTemporaryFile()`について、
なにやらWindows環境下について不穏なことを言っているのをちらちら見る。
で、`mkstemp()`を使え、とのことなので(よくわからんが)そうしてみる。
[参考](http://mattn.kaoriya.net/software/lang/python/20090218173310.htm)

```py3:simulation.py
# tmp = tempfile.NamedTemporaryFile()
fd, path = tempfile.mkstemp()
os.close(fd)
tmp = open(path, "w+b")

tmp.write(code.encode(encode))
tmp.read()
filename = tmp.name

#中略

# close temporal source code file
tmp.close()
os.remove(path)
```

とりあえずPermissionについては何も言ってこなくなった。


次にこの行

```py3:simulation.py
# simulation
p = subprocess.Popen('./' + outputfile, shell=True, stdout=subprocess.PIPE)
```

`./`を`.\\`に書き換える。以上。


ここまでして実行したらシミュレーションが走った。
わーい
windows server 2008のIEでアクセス制限を回避

## 参考

* ["Windows Server 2008"のIEでサイトアクセスできない LUNARAVE WEBクリエイターの仕事と休息/ウェブリブログ](http://warumono.at.webry.info/201111/article_4.html)

## 手順

1. 「サーバマネージャ」を起動する。
1. 「セキュリティ情報」欄にある「IE ESCの構成」をクリックする。
    * (中央右端にあります)
1. 「Internet Explorer セキュリティ強化の構成」というウィンドウが表示されるので、管理者またはユーザーのセキュリティ設定を"オフ"にする
1. IEを起動し、googleなどアクセスできることを確認。
[AWS][API Gateway]API Gatewayで生成したSDKからはHTTP Headerを参照することができない

標題がこの記事の全てなのでわざわざ記事にするか迷ったのですが、多分同じところでハマる人がいると思うので書いておきます。

# やりたかったこと
API Gatewayから生成したSDK(Android)を使用してHTTP Headerに含めた値を取得したい。

# やってみたこと
API GatewayからSDKを生成してHTTP Headerの値を参照しようとした。

# 結果
そもそも返却値がModelクラスそのものなのでHTTP Headerが入る余地が無い。
つまり
**API Gatewayで生成したSDKからはHTTP Headerを参照することができない**
ということです。

RESTfulなAPIなどではsessionIdなどをHTTP Headerに含めて返却したいケースなどがあると思うのですが、現状(2016/03/23)では自前で実装するしかなさそうです。
`toDictionary` by Extension of SequenceType

Xcode7.3にしたら、closureとかの引数をvarにすると警告が出るようになっちゃいましたね。Swift3からは正式に出来なくなるようです。
今までは、arrayからdictionaryを作るときはreduce使ってたんですが、varじゃないと書きにくいですね。それならいっその事、extensionでやってみました。

```SequenceType+toDictionary.swift
extension SequenceType {
  func toDictionary<K, V>() -> [K: V] {
    var dictionary: [K: V] = [:]
    self.forEach { e in
      if let kv = e as? (K, V) {
        dictionary[kv.0] = kv.1
      }
    }
    return dictionary
  }

  func toDictionary<K, V>(transform: (element: Self.Generator.Element) -> (key: K, value: V)?) -> [K: V] {
    var dictionary: [K: V] = [:]
    self.forEach { e in
      guard let (key, value) = transform(element: e) else {
        return
      }
      dictionary[key] = value
    }
    return dictionary
  }

  func toDictionary<K, V>(combine: (value1: V, value2: V) -> V?) -> [K:  V] {
    var dictionary: [K: V] = [:]
    self.forEach { e in
      guard let kv = e as? (K, V) else {
        return
      }
      let (key, value2) = kv
      if let value1 = dictionary[key] {
        dictionary[key] = combine(value1: value1, value2: value2)
      } else {
        dictionary[key] = value2
      }
    }
    return dictionary
  }

  func toDictionary<K, V>(transform transform: (element: Self.Generator.Element) -> (key: K, value: V)?, combine: (value1: V, value2: V) -> V?) -> [K:  V] {
    var dictionary: [K: V] = [:]
    self.forEach { e in
      guard let (key, value2) = transform(element: e) else {
        return
      }
      if let value1 = dictionary[key] {
        dictionary[key] = combine(value1: value1, value2: value2)
      } else {
        dictionary[key] = value2
      }
    }
    return dictionary
  }
}
```
Lombok valのススメ


Lombokはgetter/setterの自動生成など非常に便利な機能を提供してくれます。が、意外と使われてなさそうな"val"。とってもオススメです。参照（ http://qiita.com/alpha_pz/items/914722e78cdd5cb5a3c2 ）

valは参照記事のように、変数宣言を省略しますが、加えてfinal宣言も追加します。

```java
val value = new String();

```

は、

```java
final String value = new String();
```

と同義になります。なので、valで宣言された変数は不変であることも保証されます。変数の使い回しはろくでもないことがよく起こるのでいいことですね。
基本valで宣言、不変にできない変数だけvalを使わない、ぐらいの方針でいいのではないでしょうか。

逆に言うと以下のコードは通りません。

```java
val value = new String();
value = "a"; // error!
```
Homebrewで古いバージョンをインストール

参考：http://effectif.com/mac-os-x/installing-specific-version-of-homebrew-formula

carthageを例に書いています。

``` specify_version.sh
# formulaのディレクトリへ移動
$ cd /usr/local/Library/Formula/

# 一回怒られる
$ brew log carthage
Warning: The git repository is a shallow clone therefore the filtering may be incorrect.
Use `git fetch --unshallow` to get the full repository.

$ git fetch --unshallow
remote: Counting objects: 324024, done.
remote: Compressing objects: 100% (79532/79532), done.
remote: Total 324024 (delta 247862), reused 319162 (delta 243007), pack-reused 0
Receiving objects: 100% (324024/324024), 61.09 MiB | 207.00 KiB/s, done.
Resolving deltas: 100% (247862/247862), completed with 3307 local objects.
From https://github.com/Homebrew/homebrew
   470ea39..0e00db6  master     -> origin/master

# もう一回。欲しいバージョンのハッシュ値をコピー
$ brew log carthage

$ git checkout c6fa6777 carthage.rb
$ brew unlink carthage
$ brew install carthage
```

# 元の状態に戻す

``` fix_version.sh
$ cd /usr/local/Library/Formula/
$ git checkout master carthage.rb
```
CakePHP3でBootstrapを使う

CakePHP3にBootstrapのプラグインを入れていい感じにします。
色々ありますが、Holt59/cakephp3-bootstrap-helpersというのを入れてみることにしました。

参照：
[CakePHP 3, Bootstrap Helpers](https://holt59.github.io/cakephp3-bootstrap-helpers/)
[Bootstrap](http://getbootstrap.com/)

# インストール

以下を実行してcomposerで入れます。

```bash
composer require holt59/cakephp3-bootstrap-helpers:dev-master
```

# 準備

- config/bootstrap.phpに以下を追加

```php
Plugin::load('Bootstrap');
```

- src/Controller/AppController.phpに以下(使うものだけでOK)を追加

```php
public $helpers = [
    'Flash' => ['className' => 'Bootstrap.BootstrapFlash'],
    'Form' => ['className' => 'Bootstrap.BootstrapForm'],
    'Html' => ['className' => 'Bootstrap.BootstrapHtml'],
    'Modal' => ['className' => 'Bootstrap.BootstrapModal'],
    'Navbar' => ['className' => 'Bootstrap.BootstrapNavbar'],
    'Panel' => ['className' => 'Bootstrap.BootstrapPanel'],
    'Paginator' => ['className' => 'Bootstrap.BootstrapPaginator'],
];
```

- src/Template/Layout/default.ctpに以下を追加

```php
<?= $this->Html->script('//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js', ['block' => true]) ?>
<?= $this->Html->script('//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js', ['block' => true]) ?>
<?= $this->Html->css('//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css') ?>
```

# Form記述例

ラベルの横に入力フォームが並ぶようにする、[Horizontal form](http://getbootstrap.com/css/#forms-horizontal)を書いてみます。

```php
<?= $this->Form->create($article, ['horizontal' => true]) ?>
<?= $this->Form->input('title', ['label' => ['text' => 'タイトル']]) ?>
<?= $this->Form->input('start_date', ['label' => ['text' => '開始日']]) ?>
<?= $this->Form->button(__('登録する'), ['class' => 'btn-primary col-md-offset-2']) ?>
<?= $this->Form->end() ?>
```

↓こんな感じになります。

![スクリーンショット 2016-03-23 14.14.49.png](https://qiita-image-store.s3.amazonaws.com/0/75498/13392004-a2da-a5c4-efcc-31dec3223135.png)

ラベルと入力フォーム(とエラー)のカラム幅は`create()`のオプションで指定できます。

```php
<?= $this->Form->create($article, [
        'horizontal' => true,
        'cols' => [
            'label' => 3,
            'input' => 9,
            'error' => 0
        ]
]) ?>
```

デフォルトのlabel/input/errorは2/10/0のようです。errorは0にするとinputの下に表示されます。
全部足すと12になるように指定します。

他にも`$this->Html->icon('pencil')`とかでGlyphiconが出せたり、色々あるので詳しくは[ドキュメント](https://holt59.github.io/cakephp3-bootstrap-helpers/)見てください。

ちなみにBootstrapはそろそろ4が出そうですね〜。
HTTP通信で任意ヘッダーが消える！？そんな時はアンダースコアをつけてないか確認しよう！

APIにBIX_SSOなるヘッダーを入れてGETするとなぜかヘッダを取得できないという問題にアタリました

通信を確認してみるとブラウザ側からはしっかり送れてるな～Apache(Nginx)あたりで消されてるのかな～

調べてみるとどうやら、HTTPはデフォルトでは、アンダースコア付きのヘッダを無視する仕様になってるようです

configにこれを追加すればいいじゃん

```lang:xxx.conf
underscores_in_headers on
```

という話もあるんですがHTTPはおかしな文字がヘッダに含まれていたら強制的にアンダースコアに変換する仕様なので、なにかあった時の原因切り分けのために素直にハイフンを使ったほうがいいかなと思いました

ということで、ヘッダが消えて困っている方、キー名にアンダースコアついてないか確認してみてください
[AWS][S3] Amazon S3 でUserAgentに応じてリダイレクトでディレクトリを振り分ける・・のはできない

AWS S3では結構細かいリダイレクトルールを設定できる。
http://dev.classmethod.jp/cloud/aws/s3-redirection-rules2/

UserAgentに応じてディレクトリを振り分ける設定もできるかなーと期待したが、さすがにそこまではできなかった。

https://forums.aws.amazon.com/thread.jspa?threadID=219871
この記事だと、それをやりたければEC2を立ててリバースプロキシとせよと。
惜しい・・今後の機能追加に期待。
Gitでファイルの実行権限を変更する

WindowsとLinuxをまたがって、スクリプトファイルを編集する場合のTips。

Linux系の場合、ファイルシステム上でファイル実行権限を変更する(chmod）と、Gitが「ファイルが変更された」と認識する。
そのため通常の変更と同じく、```git add``` 、```git commit```でファイルアクセス権をリポジトリに反映できる。

Windowsでアクセス権を変更したい場合は、下記のようなGitコマンドを使う。

実行権限を付与するとき
```$ git update-index --add --chmod=+x [filename]```

実行権限を外すとき
```$ git update-index --add --chmod=-x [filename]```


なお、config設定で「ファイル権限設定を無視する」というオプションがあるため、注意。
```$ git config -l |grep filemode```
（小技）Linux 現在時刻を基準としたファイルを作成する

touchコマンドとdateコマンドを利用することで、現在時刻を基準として○○時間前のタイムスタンプをファイルに付与できます。各種シェルのテスト時に便利です。

```
touch ファイルのパス -t `date '+%m%d%H%M' -d '120 minitutes ago'`
```
Swiftコードで画面遷移

storyboardを使いたくなかったのでコーディング。
遷移の管理はナビゲーションバーを使用する。

```swift:AppDelegate.swift
...
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  // トップ画面のコントローラ
  let first = FirstViewController()
  // ナビゲーションバーのコントローラ
  let navi = UINavigationController(rootViewController: first as UIViewController)
  // 今回はスワイプでバックする機能は無効化しておく
  navi.interactivePopGestureRecognizer?.enabled = false

  window = UIWindow(frame: UIScreen.mainScreen().bounds)
  window?.rootViewController = navi
  window?.makeKeyAndVisible()

  return true
}
...
```

```swift:FirstViewController.swift
...
override func viewDidLoad() {
  // ナビゲーションバーの設定
  navigationController?.navigationBar.backgrondColor = UIColor.grayColor()
  navigationController?.setNavigationBarHidden(false, animated: false)
  // 遷移先でナビゲーションバーに戻るボタンを表示させない
  navigationItem.setHidesBackButton(true, animated: false)

  // 次へ進むボタン
  let button = UIButton(frame: CGRectMake(0, 0, view.bounds.width / 2, view.bounds.height / 2))
  button.layer.cornerRadius = 10
  button.layer.position = view.center
  // ボタンを押した(離した)際のイベントを登録
  button.addTarget(self, action: "goSecond:", forControlEvents: .TouchUpInside)
  view.addSubview(button)
}

func goSecond(sender: UIButton) {
  let second = SecondViewController()
  next.modalTransitionStyle = .CrossDissolve
  // 変数に任意の値を渡せる
  next.myMessasge = "トップ画面からの遷移" 
  // 画像データも渡せるので、撮影した画像をアルバムに保存しなくて良い
  next.myImage = UIImage(...)
  // 遷移履歴に追加する形で画面遷移
  navigationController?.pushViewController(second as UIViewController, animated: true)
}
...
```

```swift:SecondViewController.swift
// 省略
```

```swift:ThirdViewController.swift
...
func goFirst(sender: UIButton) {
  let first = FirstViewController()
  top.modalTransitionStyle = .CrossDissolve
  // 遷移履歴は First -> Second -> Third -> First となる
  navigationController?.pushViewController(first as UIViewController, animated: true)
}

func backOne(sender: UIButton) {
  // 遷移履歴を一つ戻る
  // 一度戻ると再び進むことはできないので注意
  navigationController?.popViewControllerAnimated(true)
}

func backTwo(sender: UIButton) {
  // 遷移履歴を二つ戻る
  let count = navigationController!.viewControllers.count - 3
  let target = navigationController!.viewControllers[count]
  target.modalTransitionStyle = .CrossDissolve
  navigationController?.popToViewController(target as UIViewController, animated: true)
}

func backRoot(sender: UIButton) {
  // 遷移履歴の最初に戻る
  navigationController?.popToRootViewControllerAnimated(true)
}
...
```

ナビゲーションバーを使うとその分画面がずれたりずれなかったり、
調整が面倒なのだがそれはまた別の話。
AppleScript でURLエンコード・デコード

## AppleScript とURLエンコード・デコード

　ここでいうURLエンコード・デコードとは、ブラウザに要求するURL文字列の中に、URLとして使用してはいけない文字コードを、エンコード・デコードすることで、他にパーセントエンコードや、エスケープなどとも呼ばれるものです。
　これは [RFC3986のSection 2.1 ](http://tools.ietf.org/html/rfc3986#section-2.1)で定義されています。

AppleScript には、文字コードをURLエスケープする関数が入っていない（多分）ので、他の助けを借りて実装します。

## OS Xに組み込まれていて変換に利用できるもの
　do shell script を使用して、OS Xに入っている機能を使いますが、それには次のような方法があるようです。

#### PHP を使う
 ` php -r 'echo rawurlencode("＜＜変換文字列＞＞”);' `

#### Perl を使う
` perl -MURI::Escape -wle 'print uri_escape("＜＜変換文字列＞＞")'  `

#### Ruby を使う
` ruby -r cgi -e 'puts CGI.escape("＜＜変換文字列＞＞")'  `

### 選んだのは
　perl のURI::Escape モジュールは、渡す文字列の中にエンコード不要な文字が入っていると、正しく変換できない問題があるようです。
　それ以外で、文字数がすくなかった PHP を選びました。

## エンコード・デコードする AppleScript
　起動するとエンコードかデコードしたい文字列を入力するダイアログボックスが出力されます。
![aURL1.jpg](https://qiita-image-store.s3.amazonaws.com/0/16491/02e46456-044a-178e-6efe-788431f572db.jpeg)
　入力する文字数は、このボックスを無視して長いものでもOKです。
入力した後、「URLエンコード」か「URLデコード」のボタンを押します。

そうすると、変換された結果が表示されます。
![aURL2.jpg](https://qiita-image-store.s3.amazonaws.com/0/16491/63d10812-16c1-a876-3ee1-0fcb886ca0a9.jpeg)

「OK」ボタンを押すと、変換結果のみがクリップボードにコピーされます。

```AppleScript:URLendodeDecode.scpt
-- 入力した文字列をURLで使用できない文字をエスケープ（%エンコード・URLエンコード）したり、
-- 逆にエンコードされた文字列を元の文字列に変換して表示します。
-- 表示後にOKボタンを押すと、変換結果をクリップボードにコピーします。
-- エンコード・デコード部分は php の関数を使用しています。

on urlEncode(inData) -- URLエンコード（%エンコード）
	-- 文字コードを utf8 としてエンコードしたい場合は、「as «class utf8»」で変換したものを渡すこと。
	set scpt to "php -r 'echo rawurlencode(" & quote & inData & quote & ");'"
	return (do shell script scpt) as string
end urlEncode

on urlDecode(inData) -- URLデコード（%デコード）
	set scpt to "php -r 'echo rawurldecode(" & quote & inData & quote & ");'"
	return (do shell script scpt) as string
end urlDecode

set ans to display dialog "変換したい文字列を入力" default answer "" buttons {"URLデコード", "URLエンコード"} default button 2
set inData to text returned of ans
if button returned of ans = "URLエンコード" then
	set rs to urlEncode(inData)
else
	set rs to urlDecode(inData)
end if
display dialog "変換結果：" & return & return & rs & return & return & "（OKボタンでクリップボードにコピーします。）"
set the clipboard to rs

```
"Fastboot surnia S"のドライバーがなくてAndroidをUnlockできなかった

[MotorolaはUnlockの方法を公開している（リンク先は要ログイン）](https://motorola-global-portal.custhelp.com/app/standalone/bootloader/unlock-your-device-b)んだけど、最初の方の手順でつまづいてしまった。

# 症状

Device Managerには"Fastboot surnia S"の表示。

<img width="597" src="https://qiita-image-store.s3.amazonaws.com/0/10765/300f54f9-1468-401c-27c2-2d4f0be88efa.png">

`fastboot devices` しても表示されない。

# ツール類をインストール

- [[TOOL] [WINDOWS] ADB, Fastboot and Drivers -… | Android Development and Hacking](http://forum.xda-developers.com/showthread.php?t=2588979)

具体的に何がインストールされてるのかよくわかってない。色々探すとここを参照してるところが多いので、たぶんマルウェアの類ではないんだろうと判断。

# FastbootモードにしてAndroidをUSB接続

という表現でいいの？　自分の端末 (Moto E 2nd) の場合は一度電源を切り、Volume Downを押しながら電源ボタン。

# デバイスドライバーをインストール

0. Device Managerで"Other devices" > "Fastboot surnia S"を選択
1. 右クリックしてUpdate Software Driver...
2. Browse
3. Let me pick
4. Android Device
5. Android Bootloader Interface

Windowsに「互換性なくてPC壊れても知らんぞ」と言われるので自己責任で続行。

# 接続を確認

```
> cd C:\Users\おなまえ\AppData\Local\Android\sdk\platform-tools
> fastboot.exe devices
```

何か表示されれば成功。

# 参考

- [[ROOT][Surnia]Moto E 2015 root all the thing… - Pg. 5 | Moto E 2015](http://forum.xda-developers.com/moto-e-2015/general/root-moto-e-2015-root-t3046933/page5)
Swift 2.2 の新機能: SE-0015: タプル比較演算子

次は [SE-0015: タプル比較演算子](https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md) です。だいぶ意訳です。
原文に従ってこの訳は [Apache License 2.0](https://github.com/apple/swift-evolution/blob/master/LICENSE.txt) とします。

# タプル比較演算子

* 提案: [SE-0015](https://github.com/apple/swift-evolution/blob/master/proposals/0015-tuple-comparison-operators.md)
* 著者: [Kevin Ballard](https://github.com/kballard)
* ステータス: **Swift 2.2 で実装された** ([Pull request](https://github.com/apple/swift/pull/408))
* レビューマネージャ: [Dave Abrahams](https://github.com/dabrahams)

## はじめに

あるアリティ(訳注:タプルの要素数)以下のタプルの比較演算子を実装します。

## 動機

比較可能な値のタプルを比較しようとして、タプルは比較演算子を何もサポートしていないことに気づくとイラッとするものです。比較可能な値のタプルの `==` と `!=` の定義は極めて明らかです。また(辞書順の)順序比較演算子の定義もほぼ明らかです。

タプルの比較にとどまらず、タプルを比較可能にするとタプルに似た構造体の比較演算子を実装するのも容易になります。適切な演算子が構造体のプロパティを含むタプルも単純に比較できるからです。

## 提案手法

Swift の標準ライブラリはあるアリティ以下の全てのタプルに対する比較演算子の汎用的な実装を提供するべきです。そのアリティは利便性(全てのタプルでサポート)とコードサイズ(どの定義も標準ライブラリのコードサイズを増やす)とのバランスによって選ばれるべきです。

Swift が条件付きプロトコル準拠とタプルの拡張もサポートするようになった場合は、バランスを加味して選んだアリティ以下のすべてのタプルも `Equatable` と `Comparable` に準拠するよう条件付きで宣言されるべきです。

Swift が可変長型パラメータを採用するようになった場合は、演算子(プロトコル準拠についても)の再定義について検討するべきです。コードサイズが膨れ上がるのを防げるかもしれません。

## 詳細設計

実際の定義は gyb で生成するでしょう。ここで提案するアリティは 6 です。これは大幅はコードサイズの増加なしにほとんどの適切な使い方をしているタプルをサポートするのに十分な長さです(私の好みほどは長くありませんが)。アリティ 6 でこの提案を実装してみたところ、Ninja-ReleaseAssert ビルドの `libswiftCore.dylib` (macosx 用と iphoneos 用の両方) のコードサイズの増加は 43.6KiB でした。これは 1.4% の増加です。

自動生成された定義は以下のようになります(アリティ 3 の場合):

```swift
@warn_unused_result
public func == <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2
}

@warn_unused_result
public func != <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  return lhs.0 != rhs.0 || lhs.1 != rhs.1 || lhs.2 != rhs.2
}

@warn_unused_result
public func < <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
  if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
  return lhs.2 < rhs.2
}
@warn_unused_result
public func <= <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
  if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
  return lhs.2 <= rhs.2
}
@warn_unused_result
public func > <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
  if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
  return lhs.2 > rhs.2
}
@warn_unused_result
public func >= <A: Comparable, B: Comparable, C: Comparable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
  if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
  if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
  return lhs.2 >= rhs.2
}
```

## 既存のコードに対する提供

既存のコードに影響はないはずです。

## 考えられる代替案

アリティ 12 までのタプルをサポートするよう Ninja-ReleaseAssert ビルドで試してみましたが、コードサイズの増加は 171Kib (5.5%の増加)でした。他のアリティについては試していません。
wordpressの管理画面でSSH接続設定

wordpressの管理画面からデフォルトでFTP接続は出来ますが、SSH接続はできないので設定。
使いドコロが多そうなのでメモ。

## SSH2ライブラリ　インストール

```
# yum install libssh2-devel
# pecl install -f ssh2
```

ここでエラー。

```
WARNING: failed to download pecl.php.net/ssh2 within preferred state "stable", will instead download version 0.12, stability "beta"
WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update

....

sh: phpize: command not found
ERROR: `phpize' failed
```

色々調べたら、「channel://pecl.php.net/ssh2-0.12 を使ってインストールしろ」とか「phpizeを使えるようにphp-develをインストールしろ」とかあったので試す。

```
# yum install php-devel
# pecl install channel://pecl.php.net/ssh2-0.12
```

これで無事インストールできたので、php.iniに以下の記述を追加。

```
extension=ssh2.so
```

Apacheを再起動して、wordpressの管理画面を見に行くと...

![sample.png](https://qiita-image-store.s3.amazonaws.com/0/43281/6d5d10d8-b82f-23d7-11ff-b4d15bb70881.png)

無事ssh接続が追加されました。


## 追記
wp-configに接続情報等を設定しておくことができるみたいです。
その他の設定も実は色々あったり。知らなかった。。。
自動更新とかで失敗する場合にも設定するとうまくいったりするらしい。

```
/* wordpressへのルート・ディレクトリ設定 */
define( 'FTP_BASE', '/path/to/wordpress/' );
define( 'FTP_CONTENT_DIR', '/path/to/wordpress/wp-content/' );
define( 'FTP_PLUGIN_DIR ', '/path/to/wordpress/wp-content/plugins/' );
/* 公開鍵へのルート設定 */
define( 'FTP_PUBKEY', '/home/username/.ssh/id_rsa.pub' );
/* 秘密鍵へのルート設定 */
define( 'FTP_PRIKEY', '/home/username/.ssh/id_rsa' );

```

## さらに追記
実は上記の時点で接続は出来ていたけど、自動更新がうまく行かなかった。
上の記述をしているにも関わらず、「ルートディレクトリが見つかりません。」みたいなエラーがでてハマってました。
原因はwordpress配下のユーザーがapacheでなかったから。
管理画面から画像uploadとか自動更新をする場合は、apacheにしないと出来ないので注意。
これ、wp界の常識なのかもしれないですが、すっかり抜けてました。
Homebrewを使ってRuby on Rails開発環境をMacにインストールする

Homebrewを使って、MacにRuby on Rails（RoR）の開発環境をインストールする方法です。OS X Yosemiteを使っていますが、OS X El Capitanでもほぼ同じ流れでいけます。

# 準備

## Xcodeをインストールする

Homebrewを使うためには、Command Line Tools for Xcodeが必要です。ということで、まずはXcodeをインストールします。

[Xcode – 新機能 – Apple Developer](https://developer.apple.com/jp/xcode/index.html)

Xcodeなしに進めることもできるようですが、いろいろと便利なのでインストールしておくことをオススメします。App Storeからインストールするのですが、Xodeは4GBくらいあるのでちょっと時間はかかります。

はじめてXcodeを使う場合は、一度Xcodeをひらいてライセンスへの同意をしておきましょう。下記のコマンドをたたいてもOKです。

```
$ sudo xcodebuild -license
```

## Command Line Tools for Xcodeをインストールする

ターミナルをひらき、下記のコマンドをたたいてください。

```
$ xcode-select --install
```

お使いのMacにCommand Line Tools for Xcodeがない場合は、下記のように表示されるかと思います。

```
xcode-select: note: install requested for command line developer tools
```

下記のコマンドを実行して、Command Line Tools for Xcodeをインストールしてください。

```
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```

## Homebrewをインストールする

次はHomebrewです。下記の公式ページに移動して、Homebrewインストール用のスクリプトをコピーします。

![０１.jpg](https://qiita-image-store.s3.amazonaws.com/0/93776/016a683e-75bb-4867-fd0d-18fa0fc885f9.jpeg)

[Homebrew — OS X 用パッケージマネージャー](http://brew.sh/index_ja.html)

ターミナルにペーストして実行します。

```
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

```
Press RETURN to continue or any other key to abort
```

と言われるので、Enterを押します。

```
Password:*
```

パスワードを入力して、Enterをクリック。これでHomebrewのインストールがはじまります。下記のように表示されたら、インストール完了です。

```
==> Installation successfull!
==> Next steps
Run 'brew help' to get started
```

下記のコマンドを実行して、正常にインストールできたか確認しておきましょう。エラーが出なければOKです。

```
$ brew doctor
```

# Ruby on Railsの開発環境をつくる

## rbenvをインストールする

Rubyのバージョンを管理してくれるツール、rbenvをインストールします。ターミナルから下記のコマンドを実行してください。

```
$ brew update
$ brew install rbenv ruby-build
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

## Rubyをインストールする

rbenvを使って、新しいバージョンのRubyをインストールします。

```
$ rbenv install -l
$ rbenv install 2.0.0-pXXX
$ rbenv rehash
$ rbenv global 2.0.0-pXXX
```

インストールが完了したら、下記のコマンドでRubyのバージョンを確認しておきましょう。指定したバージョンになっていますでしょうか？

```
$ ruby -v
```

## MySQLをインストールする

Homebrewを使って、MySQLをインストールします。下記のコマンドを実行してください。

```
$ brew install mysql
```

少し時間がかかると思いますが、気長に待ちます。

インストールが終わったら、MySQLのセットアップです。下記のコマンドを入力していってください。

```
$ unset TMPDIR
$ mysql_install_db --verbose --user=`username` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
```

## Powをインストールする

下記のコマンドを実行して、Rails & RackサーバのPowをインストールします。

```
$ gem install powder
$ rbenv rehash
$ powder install
```

## Ruby on Railsをインストールする

さて、最後です。下記のコマンドをたたいて、Ruby on Railsをインストールしましょう。

```
$ gem install bundler
$ gem install rails
$ rbenv rehash
```

インストールが完了したら、下記のコマンドでバージョン確認をしておきましょう。

```
$ rails -v
```
Rmarkdown v0.9.5 新機能ハイライト

Rmarkdown v0.9.5がリリースされたので、自分の為も含めて新機能をメモ。

# フローティングTOC
RStudioの解説ページや、Qiitaの右側にあるような目次が作成可能になりました

outputオプションでtocとtoc_floatをtrueにすると、設定が出来ます

```
output:
  html_document:
    toc: true
    toc_float: true
```

# コードの折りたたみ
コードの折り畳み機能が追加されました。
```echo=FALSE```でコードを隠す事はできましたが、処理を確認したくなった時はソースファイルを読むか```echo=TRUE```に戻して```knitr()```しなおす必要がありました。
このオプションで、コードを非表示にしておいて、後からクリックで表示にし直す事が出来るようになります。

設定の仕方は
```
output:
  html_document:
    code_folding: hide
```
とすればOK

※どうやら、チャンク毎に個別でオプションをつける事はまだできないっぽいです。


# タブセクション
タブつきドキュメントが簡単に作れるようになりました。
やり方は、ヘッダを書いた後に ```{.tabset}``` と書くだけです。
```{.tabset}``` のヘッダレベルより下位のヘッダで書いたものは全て
タブになります。

例えばこんな感じで書くと DailyとMonthlyのタブができます。

```
## Sales Report {.tabset}
### Daily
GOOD

### Monthly
Excellent

```

他にもRStudioと連携したアウトライン機能の強化や
５種類のテンプレート(“lumen”, “paper”, “sandstone”, “simplex”, “yeti”)の追加がされています。


# 注意ポイント
例の如く日本語の扱いには注意が必要で、
タブセクションやフローティングTOCの生成にASCII文字以外が入っていると
上手く処理されないようです。
~~回避するために、YAMLフロントマターによるメタ情報の設定を行えばOKで~~
最近のrmarkdownでは、pandoc markdown拡張の設定が簡単に出来るようになっていて

```
md_extensions: -ascii_identifiers
```

と指定してあげればOKだそうです！

参考: http://rmarkdown.rstudio.com/html_document_format.html#markdown_extensions

ぞうさんでお馴染みのkazutanさんが見つけてくださいました。有難うございます！


# おまけ
フローティングTOC、コード折り畳み、タブセクションを実際に見てみるには
下のコードをコピペって```knitr()```してみるとOKです

    ---
    title: "rmarkdown v0.9.5 新機能全盛りテスト"
    output:
      html_document:
        toc: true
        toc_float: true
        code_folding: hide
        md_extensions: -ascii_identifiers
    ---
    
    
    # プロットしてみましょう
    プロットのスクリプトを後からやっぱり見たいなって時、ありますよね？
    
    ちなみに、ドキュメントの一番右上にCodeってボタンが出てくる筈です。
    これはドキュメントにあるコードを全て表示/非表示にするためのモノです。
    ```{r}
    x <- seq(0, 10, 0.1)
    plot(x, exp(x), type = "o")
    grid()
    ```
    
    
    # フローティングTOC
    レスポンシブデザイン対応なので、狭めの環境だとドキュメントの頭に
    それなりに幅がある環境なら左にTOCが生成されます。
    
    
    # タブセクション
    ダダ長いドキュメントとはこれでおさらば…
    
    ## Sales Report {.tabset}
    ### Daily
    how do you think?
    ```{r}
    plot(cumsum(runif(1000, min = -1, max = 1)), type = "l")
    ```
    
    ### Monthly
    how do you think?
    ```{r}
    plot(cumsum(runif(1000, min = -1, max = 1)), type = "l")
    ```
    




ENJOY!!
仮作業時にSmartyでよく使うの

システム側が未実装の場合に条件文などを仮実装しておく場合に使うの。
システム側のファイルを汚さないようにするのが目的。
基本、予約変数（$smarty）で賄う。

##{$smarty.get.hoge}
//www.example.com/index.php?hoge=foo
URLからhogeの値を取得
$_GET['hoge']と同義

##{$smarty.post.page}
フォームから送信された変数 hogeの値を取得
$_POST['hoge']と同義
mysql-utilities my note


# What is login-path?
https://dev.mysql.com/doc/mysql-utilities/1.5/en/mysql-utils-intro-connspec-mylogin.cnf.html

```sql:
shell> mysql_config_editor set --login-path=localhost --host=localhost --user=root --port=13001 --password
Enter password: <Password is prompted to be inserted in a more secure way>

$ mysql --login-path=localhost
```

## Invalid password @ login-path
Bug? My password had contained `#`.

# What is configuration File?
https://dev.mysql.com/doc/mysql-utilities/1.5/en/mysql-utils-intro-connspec-config_file.html

Not-encrypted, but it runs well.

```ini:/dev/env/test1/my.cnf
[server1]
port=3308
user=root
password=other-pass
host=localhost
```

```bash:
mysqlserverinfo.py --server=/dev/env/test1/my.cnf[server1] --format=vertical
```

# mysqlrplcheck
If you want to failover or switchover, at 1st must run this command.

```ini:/home/h-imaoka/myutils.cnf
[master1]
port=3306
user=root
password=other-pass
host=localhost

[slave1]
port=3306
user=root
password=other-pass
host=slave1
```

```bash:
mysqlrplcheck --master=/home/h-imaoka/myutils.cnf[master1] \
              --slave=/home/h-imaoka/myutils.cnf[slave1]
```

If Not returned status [pass], you ___CAN NOT___ use mysqlfailover too.

# mysqlfailover
If you want to run as daemon-mode, you should set --discover-slave-login.

- slave's user/password shoud be same one
- `--discover-slave-login` __NOT EQUAL__ replication user's credential

```bash:
mysqlrplcheck --master=/home/h-imaoka/myutils.cnf[master1] \
              --discover-slaves-login=/home/h-imaoka/myutils.cnf[slave1]

```

# mysqlrpladmin (manual fo/swo)
For manual fail-over(switch-over).
You __don't have to__ set --master, because this command target is `when master is already dead`.

```bash:

```