OmniAICreator/Qiita-1.07M huggingface dataset:
switch LED by nfc(suica)

# install nfcpy
忘れたけどたぶん
`pip install nfcpy`
でインストール

# say hello
```say_hello.py
import nfc

def say_hello (tag):
    print('hello')
    
clf =  nfc.ContactlessFrontend('usb')
rdwr = {'on-connect': say_hello}

print('start')
clf.connect(rdwr=rdwr)
print('end')
```
で, 最初のテスト. 
suicaを載せると"hello"と喋る. 
一回きり. 

# Lチカ
Lチカに移る. 
+は7番. 
-はGND. 

```switch_led.py
import nfc
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)

GPIO.output(7, False)

def turn_led (tag):
    is_turn = GPIO.input(7)
    print(is_turn)
    if(is_turn):
        GPIO.output(7, False)
    else:
        GPIO.output(7, True)

    time.sleep(1)
    
clf = nfc.ContactlessFrontend('usb')

rdwr = {'on-connect':turn_led}

while True:
    print('waiting...')
    clf.connect(rdwr=rdwr)
    print('scaned')
```
suicaをタッチするたびにLEDがON/OFFする. 

timeの1秒はタッチの反応が連続して動作しないようにするため. 

![IMG_3560.jpg](https://qiita-image-store.s3.amazonaws.com/0/102253/e8e9e929-0a6c-62b6-cd55-6959dcb8e306.jpeg)


https://youtu.be/afYKrMki8qk
PHPでMastodonのStreaming APIを受信する。

# はじめに
MastodonのStreaming API、簡単に受信できたので 共有します。

# PHPのコード
やっていることは受信してvar_dump出力しているだけです。

```php:stream.php
<?php

$fp = fsockopen('ssl://example.com', 443, $errno, $errstr, 5);

const ACCESS_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$req = ['GET /api/v1/streaming/public HTTP/1.1',
		'Host: pawoo.net',
		'User-Agent: bot20170416',
		'Authorization: Bearer '.ACCESS_TOKEN,
		];

// GETリクエストを送信
fwrite($fp, implode($req, "\r\n")."\r\n"."\r\n" );

while (!feof($fp)) {
	$read = fgets($fp);
	var_dump($read);
}

fclose($fp);
```

こちらの記事（[MastodonのAPIを使ってみた - Qiita](http://qiita.com/shindyu/items/6a1f0c567774516f07da)）を参考にして、 ACCESS_TOKENを取得します。取得できたら、ACCESS_TOKENの`xxxxxx`を書き換えてください。

## やらなければならないこと。

- エラー処理
- 取得したあとの処理
［備忘録］Mastodonアップデートの時のメモと注意

## はじめに
本日の朝に私のhttps://mustardon.tokyo にもv1.2のアップデートを掛けました
この記事はMastodonのアップデート時に注意すべき点を踏まえたgitコマンドの備忘録です

Mastodonのmasterブランチには今現在ではバギーなコードが多く含まれているので
buildに失敗することが多いそうです。安定版を使用しましょう

## 作業
1. ```git status```
現在のローカルリポジトリの状態の確認
1. ```git stash```
変更されてcommitされていないファイルを一時的に退避
1. ```git stash list -p```
退避されているファイルの一覧とそのdiffを取得
1. 
```git fetch```
リモートリポジトリの情報を更新
1. 
```git checkout -b production refs/tags/v1.2```
productionブランチを作成しタグ付けされたv1.2のリリースを展開
1. 
```vim docker-compose.yml```
3.より元々設定していた、DB類の永続化設定をコメントアウトして再度有効に

後はbuildしていつも通りに
**バージョンアップする際はGitHubのUpgrade notesを参照して
適宜DBの統合やassetsのプリコンパイルを実行するようにしてください**

#### 追記
V1.2.2にもあげました
MSYS2環境でnanoエディタを導入してみた


[GNU nano](https://www.nano-editor.org/)

## nanoすごいよかった
- 習得コストがVimの五万分の１くらい
    - ノーマルモードとかない
        - ターミナル上で動作するだけのおれらが知ってるテキストエディタ
    - キーバインドが今のOS標準じゃないとこだけ注意なかんじ
        - でも下の方に表示されるからびびることない
        - キーバインド変更でWindows風とかもできる
            - [nanoエディタでWindowsっぽいキーバインド \- Qiita](http://qiita.com/tadsan/items/5e825271d6eabac14810)
    - 日本語が通らないとか一切ない
- そいでいてそこそこやりよる
    - 行コピーとかカットとかできる
    - シンタックスハイライトもできる

すごい

## pacmanでインストール
```shell-session
$ pacman -Ss nano
```

## .nanorcの作成
```shell-session
$ cp /etc/nanorc ~/.nanorc
$ nano ~/.nanorc
```

適当にオプションをアンコメントしたりする

### シンタックスハイライト用のnanorcをインクルード
めんどいので全部まとめて

```.nanorc
## include "/path/to/syntax_file.nanorc"
##
## Unless otherwise noted, the name of the syntax file (without the
## ".nanorc" extension) should be the same as the "short description"
## name inside that file.  These names are kept fairly short to make
## them easier to remember and faster to type using nano's -Y option.
##
## To include all existing syntax definitions, you can do:
-# include "/usr/share/nano/*.nanorc"
+include "/usr/share/nano/*.nanorc"
```

## まさかのエラー
```shell-session
$ nano .nanorc

エラー検出 /usr/share/nano/json.nanorc の 18 行目: 不正な正規表現 "\\u[0-9abcdefABCDEF]{4})": parentheses not balanced

エンターキーで開始します
```

同梱されてるシンタックスファイルをインクルードしたらエラー吐くってどんな了見だよ。

### json.nanorcを確認

```json.nanorc
# Escapes.
color green "\\\\" "\\\"" "\\[bfnrt]" "\\u[0-9abcdefABCDEF]{4})"
```

確かに、`)`の前に、対応する`(`がない。

適当に編集してみる。

```shell-session
$ cp  /usr/share/nano/json.nanorc  /usr/share/nano/json.nanorc.bak
$ nano /usr/share/nano/json.nanorc
```

でもって

```json.nanorc
# Escapes.
-color green "\\\\" "\\\"" "\\[bfnrt]" "\\u[0-9abcdefABCDEF]{4})"
+color green "\\\\" "\\\"" "\\[bfnrt]" "(\\u[0-9abcdefABCDEF]{4})"
```

とりあえずエラーは解消した。jsonファイルも正常にハイライトされてるっぽい。

![test.json](http://i.imgur.com/i8bsQlI.png)

しかしこれ、ドットファイルのイニシャライズのときどちゃくそめんどいんだけどどうしようかね。

Pacmanのパッケージが古かったりしない？とか期待して[リポジトリ](http://git.savannah.gnu.org/cgit/nano.git/tree/syntax/json.nanorc)見に行ってみたけど別に変わってなかった。

## 参考
- [誰も興味が無いnanoの基礎の基礎　\- nanoはpicoの千倍なの！ \- \- KAYAC engineers' blog](http://techblog.kayac.com/nano-tutorial.html)
- [jsonファイル読み込みサンプル \- shima111の日記](http://d.hatena.ne.jp/shima111/20090929/p1)
- [nanoエディタでWindowsっぽいキーバインド \- Qiita](http://qiita.com/tadsan/items/5e825271d6eabac14810)
    - 貼ってあるコードが古いので https://gist.github.com/zonuexe/3760480 参照
phpをテンプレートにした時に偏らないページネーション

自分メモ　変数とかきたねえ
というかこれリスト全部出力してjqueryあたりで表示範囲切り替えたほうがいいのではって思ったけど
探したんだけど良さそうなのなかったので、なんかもっと綺麗ないい方法あったら教えてください；ｗ；


本題
こういう偏らないようになるやつ（これは前後4つ、合わせて9個表示される）

![スクリーンショット 2017-04-17 20.59.49.png](https://qiita-image-store.s3.amazonaws.com/0/92042/fad057df-b8b3-d71e-9eb7-d8e09d0dfc89.png)

![スクリーンショット 2017-04-17 20.59.55.png](https://qiita-image-store.s3.amazonaws.com/0/92042/a7989858-4689-30ba-21b3-b29e4046916e.png)


テンプレートの方

```php
// 定数
define("SY_SEARCH_PAGING_PN_MAX",4); // 前後のページ数

// コントローラから受け取った有効なクエリを結合したもの
$_search_querys="";
foreach($searchResult['param'] as $key=>$val){
    if($key=="q"){
        $val=implode(" ",$val);
    }
    $_search_querys.=($_search_querys!=""?"&amp;":"").spc($key."=".$val);
}

// ここ別のコントローラから受け取るデータ入ります（あらかじめ$searchResultで返り値入るようにしてたそのままですごめんね。都度環境に合わせて変える）
$searchResult['nav']=array("total"=>50,"now"=>4);

// テンプレートphpに突っ込むやつ
<ul class="pagination">
    <li>
        <a href="/search/result?<?php print $_search_querys."&amp;p=1"; ?>" aria-label="最初のページへ">
            <span aria-hidden="true"><i class="fa fa-fw fa-angle-double-left nm"></i></span>
        </a>
    </li>
    <?php
        // for回す範囲を設定
        $_pg_for_start = 1;
        $_pg_for_now = $searchResult['nav']['now'];
        $_pg_for_end = $searchResult['nav']['total'];
        $_pg_diff_start = 0; // start寄りの値だった時、startへ減算する値
        $_pg_diff_end = 0; // end寄りの値だった時、endへ加算する値
        if(SY_SEARCH_PAGING_PN_MAX<$_pg_for_now){
            $_pg_for_start=$_pg_for_now-SY_SEARCH_PAGING_PN_MAX;
        }else{
            $_pg_diff_end=SY_SEARCH_PAGING_PN_MAX-$_pg_for_now+1;
        }
        if($_pg_for_now+SY_SEARCH_PAGING_PN_MAX<=$_pg_for_end){
            $_pg_for_end=$_pg_for_now+SY_SEARCH_PAGING_PN_MAX;
        }else{
            $_pg_diff_start=SY_SEARCH_PAGING_PN_MAX-abs($_pg_for_now-$_pg_for_end);
        }
        for($pi=$_pg_for_start-$_pg_diff_start;$pi<=$_pg_for_end+$_pg_diff_end;$pi++){
    ?>
    <li<?php print ($pi==$searchResult['nav']['now']?' class="active"':""); ?>><a href="/search/result?<?php print $_search_querys."&amp;p=".$pi; ?>"><?php print $pi; ?></a></li>
    <?php } ?>
    <li>
        <a href="/search/result?<?php print $_search_querys."&amp;p=".$searchResult['nav']['total']; ?>" aria-label="最後のページへ">
            <span aria-hidden="true"><i class="fa fa-fw fa-angle-double-right nm"></i></span>
        </a>
    </li>
</ul>
```


```php
// spc()ってなんだよって思って忘れてた
// この処理なので、htmlspecialcharsに置き換えればいいです
function spc($getStr){
    return htmlspecialchars($getStr);
}

```
MacOSX Sierra でRubyonRailsの開発環境を構築する

もともとvagrant上で開発していましたが、ポート関連とかWebSocketとか諸々問題が発生することが多く、快適に開発できないのでMac自体に環境を構築することにしました。

## Homebrewのインストール

### 本体のインストール
```
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
```

### インストール確認
```
$ brew doctor
Your system is ready to brew.
```

### 最新パッケージへの更新
```
$ brew update
Already up-to-date.
```

## Rubyのインストール

### rbenvのインストール
```
$ brew install ruby-build
$ brew install rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

### rubyのインストール
2.3系の最新を入れることにしました。

```
$ rbenv install -l
$ rbenv install 2.3.4
$ rbenv global 2.3.4
$ rbenv version
2.3.4 (set by /Users/ryo/.rbenv/version)
$ ruby -v
ruby 2.3.4p301 (2017-03-30 revision 58214) [x86_64-darwin16]
```

Railsのインストール

```
$ gem install rails
$ gem install bundler
$ rbenv rehash
$ source ~/.bash_profile
$ rails -v
Rails 5.0.2
```

railsサンプルアプリを動かしてみる。
各プロジェクト用ディレクトリとして私はホームディレクトリ配下にwebappディレクトリを作成しています。

```
$ mkdir webapp
$ cd webapp
$ rails new sample
$ cd sample/
$ rails g scaffold Name name:string
$ rake db:migrate
$ rails server
```

http://localhost:3000/names
にアクセス
VCCW導入　メモ

#VCCWで導入して次やる時忘れそうなところをメモ
<br>
なんとなくMAMPから脱却したく、
VCCWでとりあえずローカル環境を構築してみたので、とりあえずメモ
<br>
####導入する上で参考にしたサイト
大変わかりやすく特に問題なく導入できました。
http://vdeep.net/first-vccw
http://qiita.com/naru0504/items/58011181f2c271808c7f

微妙にはまったポイントとしてはsite.ymlをprovisionフォルダ（default.ymlと同一階層）で設定しても反映されず、もう一つ上の階層（Vargrantfileがある階層）でvagrant起動すると反映されました。

<br>
####なぜか追加したsite.ymlが表示されない問題
あとVCCWとは直接関係ないのですが、Finder上ではあるのにatomでなぜかsite.ymlがファイルツリーに表示されず、謎だったのですが調べたら速攻で解決しました。

http://qiita.com/suin/items/f7aa13625c1545d08a8b


単純にクローンした時点でのファイルしか表示されない設定？になっていたらしく、
tree-viewのHide VCS Ignored Filesのチェックをはずせば表示されました。
<br>
####VCCWを自分のローカルにクローンしてから自分で作ったリポジトリへプッシュしたい時
bitbucketやgithubでリポジトリを作成したら、

```
$ git remote set-url origin git@bitbucket.org:username/sample.git #bitbucketの場合
$ git push -u origin master
```
でOK


###サーバーのコマンド
サーバーの起動、終了についてはこんな感じです。

起動

```
vagrant up
```
終了

```
vagrant halt
```
再起動

```
vagrant reload
```
自分の環境だと毎回起動する時ものすごく時間がかかってしまうのですがなぜでしょう。。


<br>
####２つ目以降構築する時
二つ目以降サイトの開発環境を構築したい時は、単純にあらかじめVCCWをまとめるフォルダを作っておき、

```
cd # 開発環境をまとめておくフォルダ #
git clone https://github.com/vccw-team/vccw.git # 新たに作るプロジェクト名 #
```

でOK

フォルダ構成は大体こんな感じです。

```

root
`-- 開発環境をまとめておくフォルダ
    |-- VCCW 1
    `-- VCCW 2

```

こんな感じでなんとか導入できましたが今度はWordMoveを使って、VCCWで作ったローカル環境を効率よく本番環境にデプロイしたいです。


<br>
<br>
C++ 初期化リストの初期化順序について

#はじめに

そもそも初期化リストをご存じでしょうか？

```main.cpp:

class Hoge
{
	const int a;
	const int b;
	const int c;

public:
	Hoge():
		a(1),
		b(2),
		c(3)
	{}

};
```
基底クラスの引数もちコンストラクタを呼びたいとき、constメンバ変数を初期化したいときは必須になるでしょうし、メンバ変数を引数もちコンストラクタで初期化したいときもコンストラクタ本体で代入するのは一時変数が生成されてしまい、決して良くはないでしょう。

このように可能な限りメンバ変数の初期化は初期化リストで行うのがいいです。

なお、基底クラスのメンバ変数を派生先の初期化リストで初期化できない点には注意が必要です。

#本題
##初期化順序を知る

突然ですが次のコードを見てください

```main.cpp:
class Hoge
{

	int square;
	int num = 0;

public:
	Hoge(int n):
		num(n),
		square(num*num)
	{}

};
```

いっけん何の問題もないように見えますが実は**バグ**です。

僕自身最初は初期化リストの書いた順番に初期化されると思っていましたが実はそうではありません。

**メンバ変数の宣言した順番に初期化されるのです**

つまり上の例でいうと
squareが初期化されたあとに、numが初期化されることになります。
num=0としていますが、ここでの初期化も同様です。

**メンバ変数どうしが依存する初期化が必要な場合は宣言順に注意が必要です**

#まとめ

 + メンバ変数の初期化には初期化リストを使おう
 + 初期化リストの初期化順は宣言順
MastodonのAdministratorを作成する



Mastodonでの管理者は作成するのではなく、特定のユーザーを管理者に昇格させるようになっています。

https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Administration-guide.md


コマンドが「mastodon:make_admin」なので、てっきり管理者ユーザー的なのを作ってくれるのかと思ったらそうではありませんでした。

docker-composeを使っているのであれば以下のコマンドで指定したユーザーを管理者に昇格出来ます。

```bash
$ docker-compose run --rm web rails mastodon:make_admin USERNAME={user}
```
ユニットテストに対する燃えたぎる思い

## はじめに
まず、はじめに本記事は「ユニットテストの良さを伝えること」が目的です。
ターゲットは、テストを書いたことのない新卒・学生エンジニアの方々を想定しています。
インターン時代に僕がテストについて学び、考えたこと・気付いたことを共有して、この記事を読んだ人に「テスト書いてみようかな？」って思わせるのがゴールです。

なので、内容のほとんどがテストに対する思いやモチベーションについてです。

具体的なテストの書き方については別記事でまとめようと思っているので、それを読んで頂ければと思います(^^)

あくまで個人的な考えなので、「これってこうじゃないの？」とか、「これってどういうことと？」などのツッコミはバシバシくださいm( _ _ )m

## ユニットテスト is 何？
ユニットテストについて知ってもらうために、ユニットテストとは何かというところから始めたいと思います。

> ユニットテスト(単体テスト)とは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュータプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御データ、使用手順、操作手順とともにテストする手法である。by Wikipedia

うーん、難しい。

僕はもっとフラットに考えていて、"プログラムの最小単位(ユニット)で、検証(テスト)を行うもの"だと思っています。

僕の場合大抵は、プログラムの最小単位をメソッドとして扱っています。

## ユニットテストを書く理由
次に、ユニットテストを書く理由についてです。ユニットテストを書く理由は調べれば沢山出て来ると思います。
しかし、折角なのでこの記事では僕がユニットテストを書く理由を1つだけご紹介しようと思います。

それは、"自信を持ってコーディングするため"です。

僕は、自分が書くプログラムが常に完璧であると胸を張って言えません。「本当にちゃんと動くのか？」「今書いたところ他に影響及ぼしてないか？」「もっといい書き方があるんじゃないか？」など疑心暗鬼になりながらコードを書いています。
しかし、ユニットテストを書くようになってから「テスト通ってるから大丈夫」「最低限この動きが保証されていればOK」「もっと良い書き方があったらリファクタリングすればいいやー」くらいに割り切って考えるようになりました。

「自信を持ってコーディングするため」ってユニットテストを書く理由としては弱いかもしれませんし、ピンとこないかもしれません。
しかし、僕がテストを書く理由のほとんどは"これ"なんです。

## ユニットテストのメリット・デメリット
僕のテストに対する熱い思いを語ったところで次は、ユニットテストのメリット・デメリットについて述べようと思います。これについては、あらゆる記事で沢山紹介されているので、個人的な意見を述べようと思います。

### ユニットテストを書くメリット
ここでは、個人的にユニットテスト書いてて良かったなと思えたことを列挙しようと思います。だいたい以下の3つですね。

1. クラスが疎結合になる
2. リファクタリングが楽になる
3. デバッグが楽になる

2,3に関してはなんとなくわかると思うので、1についてだけ説明しようと思います。
僕がいつも苦戦するのが、クラスを疎結合にすることです。
オブジェクト指向でプログラミングしていると、あるクラスが他クラスに依存していることがしばしば起こります。
実際にユニットテストを書いてみるとわかると思うんですが、他のクラスに依存しているクラスのテストって書きにくいんですよね(理由は別記事で)。
ユニットテストが書きにくいなって思った時はリファクタリングの良い機会になります。そのタイミングでリファクタリングすれば段々と疎結合になっていくはずです。

### ユニットテストのデメリット
デメリットについても個人的な意見です。

1. テストを書く分、工数を取られる
2. テスト文化を浸透させるのが大変

1.に関しては単純に考えれば、テストを書く分、普段より工数が取られてしまうと思います。しかし、デバッグにとられる時間を考えてみるとそんなに変わらない気がします。

2.に関してはとても難しいことだと思います。ユニットテストを書いたことのない人に書かせることも大変なのに、それをチーム、または組織に広めることはかなり大変なことだと思います。

この記事のターゲットに対して、僕が考える解決策は、「チームの1番"若い人"がユニットテストを書く」ことです。
組織は所属する人の3割が変われば変化するそうです。
テストの書ける"若い人"がチームに新しく入るメンバーにユニットテストを教えるようになれば、いつの日かテスト文化が浸透するはずです(^^)

## ユニットテストを導入するにあたって
ユニットテストを導入するにあたって、まず知って欲しいのが、テストの文法自体はそんなに難しくないということです。
しかし、テストを書いていて難しいと感じたことは多々あります。
では、なにが難しいのでしょうか？

僕は、テストのスコープだと思います。

### テストのスコープ
僕がテストを書いていていつも思うのは、「どこまでテストを書いたら充分なのだろうか」ということです。
少なすぎるテストは問題外ですし、多すぎるテストも無駄でしかありません。つまり、必要なテストだけを書くというのが難しいのです。テストを書いたことのない人がテストを煩わしく思うのがこれが理由だと思います(僕がそうでした)。

でも、安心してほしいのが、必要なテストだけを書くテクニックは存在します(詳しくは別記事で)し、最初は無駄なテストを沢山書いても良いと思います。そのうち段々と慣れてくるはずなので、とにかく書いてみることが大切だと思います。

## さいごに
ここまで読んでみていかがだったでしょうか？
この記事を読んで少しでも「ユニットテスト書いてみようかな？」と思って頂けたのであれば幸いです。
テストを書けるようになれば、エンジニアとしてワンランク成長できるはずです。この機会に是非テストを書くことをおすすめします。
MSYS2+mintty+bashでanyenv導入するのにえらい苦労した


anyenv→goenv→golang入れようとしたときのこと。

## anyenvが動かない
[riywo/anyenv: all in one for \*\*env](https://github.com/riywo/anyenv)

```shell-session
$ git clone https://github.com/riywo/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

ってやるじゃないすか？

```shell-session
/home/<ユーザー名>/.anyenv/bin/anyenv: 行 1: ../libexec/anyenv: No such file or directory
```

っていうエラーが出る。`eval "$(anyenv init -)"`ができてない。

ここで`anyenv`コマンドで実行されてるファイルは`.anyenv/bin/anyenv`のはずなので、中身を見てみる。

[anyenv/anyenv at master ・ riywo/anyenv](https://github.com/riywo/anyenv/blob/master/bin/anyenv)

```bash
../libexec/anyenv
```

実際の処理としては`.anyenv/libexec/anyenv`が呼ばれてるらしい。

じゃあ絶対パスに書き換えたらどうなん。

```bash
-../libexec/anyenv
+~/.anyenv/libexec/anyenv
```

すると、なんかヘルプメッセージが出てくる。おかしい。

```shell-session
anyenv
Usage: anyenv <command> [<args>]

Some useful anyenv commands are:
   commands            List all available anyenv commands
   local               Show the local application-specific Any version
   global              Show the global Any version
   install             Install a **env
   uninstall           Uninstall a specific **anv
   version             Show the current Any version and its origin
   versions            List all Any versions available to **env

See `anyenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/riywo/anyenv#readme
```

`anyenc install goenv`とか`anyenv version`とかやっても同じメッセージしか出ない。

## goenvも動かない
ここでいったん諦めて直接goenvを入れてみたのだが、まさかの**全く同じ症状**が発生。やってらんない。

## シンボリックリンクで解決
色々ぐぐっていたらヒントを見つけた。

[Macでrbenvをgit\-cloneしたときに、シンボリックリンクがおかしくなっていた件 \- ゆっくり備忘録](http://mitsuakikawamorita.com/blog/?p=1297)

これ、bin/anyenvを「libexec/anyenvを実行するスクリプト」じゃなくて、「libexec/anyenvそのもののシンボリックリンク」にしたらどうなの？

```shell-session
$ cd ~/.anyenv
$ mv bin/anyenv bin/anyenv_old #bin/anyenvをリネーム
$ ln -s $(pwd)/libexec/anyenv $(pwd)/bin/anyenv #シンボリックリンク
$ exec $SHELL -l #.bash_profileでanyenv初期化処理を実行
$ anyenv install goenv
/tmp/goenv.20170417194201.11480 ~/.anyenv
Cloning https://github.com/kaneshin/goenv.git...
Cloning into 'goenv'...
remote: Counting objects: 210, done.
remote: Total 210 (delta 0), reused 0 (delta 0), pack-reused 210
Receiving objects: 100% (210/210), 30.20 KiB | 0 bytes/s, done.
Resolving deltas: 100% (131/131), done.
~/.anyenv

Install goenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```

……いけるやん！

## goenvでループ

```shell-session
$ exec $SHELL -l
/home/<ユーザー名>/.anyenv/envs/goenv/bin/goenv: 行 1: ./../libexec/goenv: No such file or directory
```

そりゃgoenv直接入れてダメだったんだから同じ症状出るよね！！！！

```shell-session
$ cd .anyenv/
$ mv envs/goenv/bin/goenv envs/goenv/bin/goenv_old
$ ln -s $(pwd)/envs/goenv/libexec/goenv $(pwd)/envs/goenv/bin/goenv
$ anyenv versions
goenv:
goenv: couldn't find any version specified for use
```

## 解決はしたけど
はたして問題は那辺にありや。明らかに環境起因だからissueとか送る気しないですし。
Fastly でコンテンツをパージ（キャッシュを削除）する

CDN を使う場合、コンテンツがキャッシュされるため、オリジンサーバでアップデートした場合、キャッシュを明示的に削除する必要があります。Fastly ではキャッシュの削除を 150ms 以内で実施できるという特徴があるので、従来の CDN では更新の頻度が多く、キャッシュできなかったコンテンツがキャッシュできるようになります。
ここではキャッシュの削除（パージ）する方法をご紹介します。
# パージの種類
Fastly のパージには通常のパージ、ソフトパージの２種類があります。
通常のパージはキャッシュの削除を行い、強制的にオリジンサーバからファイル取得を行い、キャッシュ上のコンテンツを更新します。一方、ソフトパージはキャッシュの削除はせずにキャッシュを期限切れ状態にすることにより、オリジンに更新の有無を確認し、更新されていれば再取得、されていなければキャッシュ上のコンテンツをそのまま利用します。

# パージの対象
上記のようにパージ対象の指定には３つの方法があります。

| パージ名 | パージ対象 | 通常のパージ | ソフトパージ | 認証（デフォルト） |
|:--|:--|:-:|:-:|:--|
| Purge URL | 指定した URL | ⚪️ | ⚪️ | なし |
| Purge Key | 指定した Key を Surrogate-Key ヘッダに持つ URL | ⚪️ | ⚪️ | API Token (GUI ではなし)|
| Purge All | 該当サービスの全 URL | ⚪️ | - | API Token (GUI ではなし) |


# GUI によるパージ
コントロールパネル（ https://manage.fastly.com ）へのログイン後、CONFIGURE 画面にて下記、PURGE ボタンから実施します。ソフトパージは対応していません。
![Screen Shot 0029-04-17 at 16.27.12.png](https://qiita-image-store.s3.amazonaws.com/0/149542/f03325d8-f251-8dd1-1372-219972b87f66.png)
## Purge URL
Purge URL を選択すると下記のウィンドウが表示されます。
パージしたい URL のドメインを選択し、パスを指定します。
![Screen_Shot_0029-04-17_at_17_39_21.png](https://qiita-image-store.s3.amazonaws.com/0/149542/2ad4ab08-71b1-731e-ad4f-eeb254857f6c.png)

## Purge Key
Purge Key を選択すると下記のウィンドウが表示されます。
パージ対象の URL グループに指定した Surrogate-Key の値を指定します。
![Screen Shot 0029-04-17 at 17.37.34.png](https://qiita-image-store.s3.amazonaws.com/0/149542/2a5d3a14-09ad-0d7f-9968-c0c4045840bd.png)

# Purge All
Purge All を選択すると下記のウィンドウが表示されます。
Purge All は全てのコンテンツがキャッシュクリアされるため、一時的に全てのリクエストがオリジンに問い合わせ行くことになります。その場合のオリジンサーバの負荷にご注意ください。
![Screen Shot 0029-04-17 at 17.37.51.png](https://qiita-image-store.s3.amazonaws.com/0/149542/136a136e-bf62-ec23-16bf-c54b1fa2d4c0.png)

# CLI によるパージ
## Purge URL
```
$ curl -X PURGE http://www.example.com/image.jpg
```
（ソフトパージの場合は `-H "Fastly-Soft-Purge:1"` を追加）

# Purge Key
```
curl -X POST -H "Fastly-Key: <API TOKEN>" https://api.fastly.com/service/<Service ID>/purge/<Key>
```
（ソフトパージの場合は `-H "Fastly-Soft-Purge:1"` を追加）

# Purge All
```
curl -X POST -H "Fastly-Key: <API TOKEN>" https://api.fastly.com/service/<Service ID>/purge_all
```

# URL パージで API Token 認証を有効にする
デフォルトでは URL パージでは認証が必要ないため、任意のユーザがパージを行うことができます。パージに制限をかけるために、Purge Key, Purge All と同様に API Token による認証をかけることができます。
`Fastly-Purge-Requires-Auth` がリクエストヘッダに存在している場合には API Token による認証が必要になります。Purge URL のリクエストは Fastly VCL において処理されるため、Fastly の設定の中で本ヘッダを追加します。

1. Configuration より CONTENT タブを選択し、`CREATE HEADER` を選択
2. 下記を設定
   - Name : 任意の名前を設定（例：Fastly Purge）
   - Type / Action : Request / Set
   - Destination : http.Fastly-Purge-Requires-Auth
   - Source : "1"
   - Ignore if set : No
   - Priority : 10
3. `Create` ボタンで作成
4. 2 で設定したヘッダの追加を行う条件を適用するために `Attach ad condition` を選択
5. 下記を設定
   - Type : Request
   - Name : 任意の名前を設定（例：Purge request）
   - Apply if : req.request == "FASTLYPURGE" (PURGE リクエストは `FASTLYPURGE` というリクエストメソッドで処理されます)
6. `Save and Apply to` ボタンで条件を適用

パージのパフォーマンスは Fastly の特徴でもあります。コンテンツを更新すると同時に API によりパージを行うといった自動化処理を実装することにより、頻繁に更新が行われ、リアルタイムに更新を反映したい場合にもコンテンツのキャッシュが可能となります。
android.os.Processが定義するスレッド優先度とjava.lang.Threadが定義するスレッド優先度の関係

# スレッド優先度の2つの系統

Androidでは、スレッドの優先度に関して2つの系統があります。

- [`java.lang.Thread`](https://developer.android.com/reference/java/lang/Thread.html) 系
    - Java標準のAPIで使われる (`Thread`, `ThreadFactory` など)
    - 最小値 1 ([`MIN_PRIORITY`](https://developer.android.com/reference/java/lang/Thread.html#MIN_PRIORITY)) 〜 最大値 10 ([`MAX_PRIORITY`](https://developer.android.com/reference/java/lang/Thread.html#MAX_PRIORITY))
    - 値が大きい方が優先される
- [`android.os.Process`](https://developer.android.com/reference/android/os/Process.html) 系
    - Java標準でないAndroid APIで使われる (`android.os.Process` など)
    - 最小値 -20 〜 最大値 19
    - 値が小さいほうが優先される
    - いわゆるUnix/Linuxにおける [nice値](https://ja.wikipedia.org/wiki/Nice_(UNIX))

AndroidはLinuxがベースのOSなので、内部的には後者のnice系でスレッドの優先度が管理されています。

# 2つのスレッド優先度系の間のマッピング

つまり、Java系で定義されるスレッド優先度は、どこかでnice系のスレッド優先度に変換されます。アプリのランタイムにARTが使われている近年のAndroidの場合、ARTの実装に変換テーブルが埋め込まれており、それを見ると、Java系のスレッド優先度がどのnice値に変換されるかがわかります。

https://android.googlesource.com/platform/art/+/master/runtime/thread_android.cc#36

```cpp
static const int kNiceValues[10] = {
  ANDROID_PRIORITY_LOWEST,                // 1 (MIN_PRIORITY)
  ANDROID_PRIORITY_BACKGROUND + 6,
  ANDROID_PRIORITY_BACKGROUND + 3,
  ANDROID_PRIORITY_BACKGROUND,
  ANDROID_PRIORITY_NORMAL,                // 5 (NORM_PRIORITY)
  ANDROID_PRIORITY_NORMAL - 2,
  ANDROID_PRIORITY_NORMAL - 4,
  ANDROID_PRIORITY_URGENT_DISPLAY + 3,
  ANDROID_PRIORITY_URGENT_DISPLAY + 2,
  ANDROID_PRIORITY_URGENT_DISPLAY         // 10 (MAX_PRIORITY)
};
```

上記の配列は、Java系 [`Thread.MIN_PRIORITY`](https://developer.android.com/reference/java/lang/Thread.html#MIN_PRIORITY) がnice系 `ANDROID_PRIORITY_LOWEST` に、Java系 [`Thread.MAX_PRIORITY`](https://developer.android.com/reference/java/lang/Thread.html#MAX_PRIORITY) がnice系 `ANDROID_PRIORITY_URGENT_DISPLAY` にマッピングされることを表しています。

[`Thread.MAX_PRIORITY`](https://developer.android.com/reference/java/lang/Thread.html#MAX_PRIORITY) にマッピングされている [`ANDROID_PRIORITY_URGENT_DISPLAY`](https://android.googlesource.com/platform/system/core/+/master/libsystem/include/system/thread_defs.h#56) は -8 なので、それよりも優先度が高い [`Process.THREAD_PRIORITY_AUDIO`](https://developer.android.com/reference/android/os/Process.html#THREAD_PRIORITY_AUDIO) や [`Process.THREAD_PRIORITY_URGENT_AUDIO`](https://developer.android.com/reference/android/os/Process.html#THREAD_PRIORITY_URGENT_AUDIO) はJava標準のAPIでは設定できません。普通のアプリではあまり必要性はないと思いますが、もし、そういった優先度を設定したい場合は、Android APIである [`android.os.Process.setThreadPriority(int)`](https://developer.android.com/reference/android/os/Process.html#setThreadPriority(int)) などを使う必要があります。
Unityでアナログ時計を動かしてみる。

Unityのスプライトを使ってアナログ時計を作った。
DateTime.Nowとtransform.eulerAnglesを使った。

# 時計の見た目を作る

## 画像の準備
Gimpで適当に描いた。
![clock.png](https://qiita-image-store.s3.amazonaws.com/0/46612/b979fada-222c-4fa9-ed6b-168e50a087e2.png)

左から時計の枠、時針、分針、秒針。

時刻は省略した。

## Sprite Editorでスライス
Sprite Mode -> Single
をMultipleに変更。

Sprite Editorを開き、とりあえずAutoでスライスしたあと微調整。
Pivotはそれぞれ,
枠 -> Center
時針 -> 0.5,0.04
分針 -> Bottom
秒針 -> Bottom

編集が終わったらApply。

#シーンの編集
それぞれのスプライトをSceneに配置。

以下のスクリプトを追加して、何かしらのオブジェクトにアタッチする。

```csharp:clockController.cs
using System;   // DateTimeに必要
using System.Collections;
using UnityEngine;

public class clockController : MonoBehaviour {

	public bool sec;   // 秒針の有無
	public bool secTick;   // 秒針を秒ごとに動かすか

	public GameObject hour;
	public GameObject minute;
	public GameObject second;

	void Start ()
	{
		if (!sec)
			Destroy(second); // 秒針を消す
	}
	
	void Update ()
	{
		DateTime dt = DateTime.Now;
		
		hour.transform.eulerAngles = new Vector3(0,0,(float)dt.Hour/12*-360 + (float)dt.Minute/60*-30);
		minute.transform.eulerAngles = new Vector3(0,0,(float)dt.Minute/60*-360);
		if (sec)
		{
			if (secTick)
				second.transform.eulerAngles = new Vector3(0,0,(float)dt.Second/60*-360);
			else
				second.transform.eulerAngles = new Vector3(0,0,(float)dt.Second/60*-360 + (float)dt.Millisecond/60/1000*-360);
		}

	}
}
```

アタッチしたオブジェクトのInspectorに配置したスプライトをドラッグ＆ドロップする。

再生したら現在時刻を表示してくれるはずです！
![capdelay.gif](https://qiita-image-store.s3.amazonaws.com/0/46612/ae0676e2-0758-d68d-6675-bcc1d348b982.gif)
*2017/05/09 gif画像を追加

# スクリプトの解説

### 時間の取得
現在時刻はPCやデバイスに依存する。
using system;を追加し
DateTime.Nowで現在時刻を取得できる。

詳細は[DateTime.Now プロパティ (System) - MSDN - Microsoft](https://msdn.microsoft.com/ja-jp/library/system.datetime.now(v=vs.110).aspx)

### 回転
```csharp
transform.eulerAngles = new Vector3(x,y,z);
```
x,y,z は360で1回転。InspectorのRotationと同じ値。
H1 より H2 のほうがFontSizeが大きい？

なんじゃこりゃ？って思ったので書いておく。

## tl;dr

`h1` タグは, `article` / `section` / `aside` / `nav` タグでネストされていると `h(n+1)` タグと同じになる。

```html
<h1>H1</h1>

<article>
  <h1>H1 === H2</h1>
</article>

<article>
  <section>
    <h1>H1 === H3</h1>
  </section>
</article>
```

## 確認環境

Chrome 57

## 発端

`article` タグの中の `section` タグ内で `h1` を使ったら `h2` タグより文字サイズが小さい。

どういうことだ！バグじゃないか！！

<img width="139" alt="H1とH3が同じ？" src="https://qiita-image-store.s3.amazonaws.com/0/19605/f6bf10da-a873-02f5-c5ac-d53d20d9f67f.png">

と思ったけど落ち着いてぐぐってみた。

## あっさりヒット

以下の Stackoverflow のページがあっさりヒット。

* [&lt;h1> is smaller than &lt;h2> in firefox and chrome](http://stackoverflow.com/questions/6851833/h1-is-smaller-than-h2-in-firefox-and-chrome)

質問者も同じように「おかしくね？」って言ってます。が、ベストアンサーの回答を見てみると

> In HTML5, an `<h1>` inside sections nested n levels deep is treated like `<h(n+1)>` instead. So an `<h1>` inside a single `<section>` is semantically equivalent to an `<h2>` and is rendered as such. 
> (雑訳: HTML5 ではネストされた中にある `h1` タグは `<h(n+1)>` になるよ。`<section>` の中にある `<h1>` は `<h2>` と同じ意味になるよ。)

## 解決

とのことで、 `article` / `section` / `aside` / `nav` タグの中にある `h1` は、 `h(ネストされた数 + 1)` になるとのことでした。

へぇ。へぇ。へぇ。へぇ。へぇ。
MSYS2+mintty+bashでghq導入したらghq.rootがおかしなことになった


[motemen/ghq: Remote repository management made easy](https://github.com/motemen/ghq)

最初anyenvから導入しようとして、anyenv入れる段階でうまくいかなかったけど、それは解決したので削除済み。

## go入れる
pacmanで入れた。

```shell-session
$ pacman -S mingw-w64-x86_64-go
```

.bashrcに追記。

```.bashrc
export GOPATH=$HOME/.go
export PATH=$GOPATH/bin:$PATH
```

## ghq入れる
```shell-session
$ go get github.com/motemen/ghq
```

実は`GOPATH`の指定忘れたまま上記コマンド実行して、どこにもねーじゃねーか！っつってしばらく詰まってた。

`GOPATH`指定がない状態で`go get`するとどこにも保存されないくさい。

## ghq.rootの設定がおかしくなる
まさかここまで来て罠があると思わないやん。

ここで.gitconfigに以下を追記。

```.gitconfig
[ghq]
	root = ~/ghq
```

試しに[catfist/dotfiles](https://github.com/catfist/dotfiles)をget。

```shell-session
$ ghq get catfist/dotfiles
     clone https://github.com/catfist/dotfiles -> \home\<ユーザー名>\ghq/github.com/catfist/dotfiles
       git clone https://github.com/catfist/dotfiles \home\<ユーザー名>\ghq/github.com/catfist/dotfiles
Cloning into '/c/home/MM/ghq/github.com/catfist/dotfiles'...
remote: Counting objects: 284, done.
remote: Total 284 (delta 0), reused 0 (delta 0), pack-reused 283
Receiving objects: 100% (284/284), 94.25 KiB | 148.00 KiB/s, done.
Resolving deltas: 100% (109/109), done.
```

するとプロセスメッセージは出るのだが、探せど~/ghqが存在しない。でも、もっかいgetするともうあるよって言われる。

というか、clone先のパス`\home\<ユーザー名>\ghq/github.com/catfist/dotfiles`にバックスラッシュ（あるいは半角￥）とスラッシュが混在してるのが怖すぎるんだけど。

Windows環境では通常パスの階層区切りはバックスラッシュで表現されるが、MSYS2含むターミナル環境ではスラッシュで表現されるじゃないすか。全部スラッシュになってないとおかしいはず。

とにかくgetはできてるんだから、ghqでローカルリポジトリに移動してみんべっつってやってみた。

```shell-session
$ ghq look dotfiles
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\home\<ユーザー名>\ghq\github.com\catfist\dotfiles>
```

まさかの、Cドライブ直下。

しかもmintty内でコマンドプロンプトが起動しておもろいことになった。（`exit`で脱出）

MSYS2環境だと`~`つまりホームディレクトリは`/home/<ユーザー名>/`であり、ここでいう`/home/`はMSYS2インストールディレクトリなわけだが、これがWindows的な意味での`\home\<ユーザー名>\`として解釈されてしまっている。

goが単バイナリ生成する前提のモンだからかどうか知らないが、呼び出し元がMSYS2だろうがなんだろうが、パスをWindows風にしか扱わないらしい。

ということは。

```.gitconfig
[ghq]
	root = /msys64/home/<ユーザー名>/ghq
```

```shell-session
$ ghq get catfist/dotfiles
     clone https://github.com/catfist/dotfiles -> \msys64\home\<ユーザー名>\ghq/github.com/catfist/dotfiles
       git clone https://github.com/catfist/dotfiles \msys64\home\<ユーザー名>\ghq/github.com/catfist/dotfiles
Cloning into '/home/MM/ghq/github.com/catfist/dotfiles'...
remote: Counting objects: 284, done.
remote: Total 284 (delta 0), reused 0 (delta 0), pack-reused 283
Receiving objects: 100% (284/284), 94.25 KiB | 0 bytes/s, done.
Resolving deltas: 100% (109/109), done.
```

できた！ 相変わらずバックスラッシュとスラッシュが混在してるけど！

## ghq lookでコマンドプロンプトが起動してしまう
移動先はMSYS2管理下のディレクトリになったものの、`ghq look`実行時にコマンドプロンプトが起動する不具合は相変わらず。

ただし、これは`ghq list`でローカルリポジトリを特定し、ビルトイン`cd`で移動するスクリプトを書いてあったので概ね問題なし。
vscode ver.1.11でSCMを以前のgitに戻す

以前までこのように見れていたのが、ver.1.11からSCM(Source Control Model)という機能に代わっている。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/51326/8c7c1743-5282-0683-07c6-47747c2c75bb.png)
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/51326/a637903b-6c25-46d5-11f7-85dfc8316aa8.png)

ちゃんと設定すれば以前のようにGit差分表示できるっぽいんだが、めんどくさかったのでコマンド一つで戻せるのでやってみた。

コマンドパレットで`SCM: Disable Preview SCM command`と打てばとりあえずいいはず。
戻したいときはDisableをEnableに変えるだけ。

ソース: https://code.visualstudio.com/updates/v1_11#_troubleshooting
2. 富士通 WEB MART for クラウドへ登録

このページは、
FUJITSU Cloud サービス K5 を使ってみる - Qiita
http://qiita.com/ynott/items/a256669c692625c5fd25
の「2. 富士通 WEB MART for クラウドへ登録」のページです。

K5への登録はすみましたか？
すんでなければ、[1. FUJITSU Cloud サービス K5へ登録](http://qiita.com/ynott/items/2e13cdd57c92f6d3e577) でK5サービスへの登録をすませましょう。

まだまだ、道半ばです。もうちょっと頑張りましょうね。

## 2-1. 登録開始

https://cloud-direct.jp.fujitsu.com
を開いて、「会員登録」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/5ebf8955-a893-6c57-3282-f900b660e0d7.png)

## 2-2. 規約に同意
「同意します」を押すだけです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/9dc56146-9e6e-9fbe-8011-138e76bb3e95.png)

## 2-3. ユーザー情報を入力

サラッと入れて「進む」をクリックしましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/6ca8ffcd-79f8-0578-1988-b9261275abdd.png)

## 2-4. 情報の確認

確認するだけです。「新規登録」を押しましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/2821f607-0f86-fc64-6a18-b92cb0b00374.png)

## 2-5. 登録完了

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/8da126ee-76e5-1a76-f8b8-730a268bdde6.png)

## 2-6. メール確認
メールが届いていると思うので、メールを確認します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/5055e722-8307-a48f-3056-f6541a13bc0f.png)
メールに書いてあるURLにアクセスしたら登録が完了です。

## 2-7. 登録完了

![image.png](https://qiita-image-store.s3.amazonaws.com/0/15176/1ffee391-9f6f-97e6-d80b-f9b12800f8b2.png)

----

次は、トライアル申し込みへ進みましょう。
[3. K5トライアル申し込み](http://qiita.com/ynott/items/244023ad5d5417b61596)
cloudfront.netがPublic Suffixで困ったという話

CloudFrontの署名付Cookieの設定でつまずいた、という話。

## CloudFrontで署名付Cookieを扱う

会員限定、期間限定とか、特定のユーザーにだけコンテンツを公開したいと思ったら、AWSのCloudFrontなら簡単にできるらしい。

**CloudFrontを使用してプライベートコンテンツを供給する**
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html

署名付URLもしくは署名付Cookieを発行して、ユーザーを限定してS3へのアセットへのアクセスを許可することができるとのこと。使い分けとしてはざっくり以下の通り。

- 署名付URL: 単独の制限されたファイル（ダウンロードリンク等）に適している
- 署名付Cookie: 複数の制限されたファイル（動画のストリーミング等）に適している

Cookieのほうが自分の用途にあってるので、こちらを選択。

**署名付き Cookie の使用**
http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html

## CloudFrontのクロスドメインCookie問題

SDKを使って署名付Cookieを発行するわけですが、そうなるとこんな状況になります。

**アプリ側のドメイン（署名付Cookieの発行） ==Cross Domain==> CloudFrontのドメイン（Cookieを判別してアクセス許可）**

仕様上、別のドメインからはCookieは読めないわけなので、アプリとCloudFrontのサブドメイン以降は同じでなければいけない、ということになります。
本来、固有のドメインを取得して設定すればいいわけですが、まだ開発中のデモにお金かけたくない。。。

それなら、AWSがランダムに発行する xxxxxxxxx.cloudfront.net に合わせて、hostsファイルを設定してしまえばいいのでは？ というわけで、local.cloudfront.net を設定してみました。

**local.cloudfront.net ==Cross Domain==> xxxxxxxxx.cloudfront.net**

```ruby
start_time = (Time.now - 60).to_i
expire_time = 3.hours.from_now.to_i

policy = {
  Statement: [
    Resource: "https://local.cloudfront.net/sample/*",
    Condition: {
      DateLessThan: { "AWS:EpochTime" => expire_time },
      DateGreaterThan: { "AWS:EpochTime" => start_time }
    }
  ]
}

signer = Aws::CloudFront::CookieSigner.new(
  key_pair_id: ENV['AWS_CLOUDFRONT_KEY_PAIR_ID'],
  private_key_path: ENV['AWS_CLOUDFRONT_PRIVATE_KEY_PATH']
)
signer.signed_cookie('https://local.cloudfront.net/sample/*',
  policy: policy.to_json
).each do |key, value|
  cookies[key] = {
    value: value,
    domain: 'cloudfront.net',
    path: '/',
    secure: false
  }
end
```

これで cloudfront.net に署名付Cookieが設定されて、ローカルから xxxxxxxxx.cloudfront.net のコンテンツにアクセスできる。。。 と思いきやCookieが設定されないではないですか！

## Public Suffix List (PSL) とは？

色々調べてようやくつきとめたのが Public Suffix の存在。別名 Effective Top Level Domain (eTLD)。

> A "public suffix" is one under which Internet users can (or historically could) directly register names. Some examples of public suffixes are .com, .co.uk and pvt.k12.ma.us. The Public Suffix List is a list of all known public suffixes.
Public Suffixはその下にインターネットユーザーが直接名前を設定できるドメインです。例えば、.com、.co.uk、pvt.k12.ma.usがその例です。

> Avoid privacy-damaging "supercookies" being set for high-level domain name suffixes
プライバシーを侵害するSupercookieの設定を避けるためにも使われます。
https://publicsuffix.org/

要するに、.com や .co.uk なんて不特定多数に使われるドメインでCookieの読み書きできたらプライバシー上問題なので、Public Suffix Listに乗っているドメインにはCookieは設定できないよ、ということです。

それを踏まえて、Listを見てみると。。。

**cloudfront.net**

ありました。cloudfront.net は .com や .co.uk と同じレベルにあるということです。

原因が分かったので、今度は hosts を local.xxxxxxxxx.cloudfront.net として、 Cookieの設定ドメインを xxxxxxxxx.cloudfront.net にして、無事成功。

考えてみれば当然のことなのですが、cloudfront.net という名前からは意外と気づきませんでした（未熟）。Publix Suffixは膨大なリストなのでクラウド系のサービス使うときはチェックしてみてください。
NPAPI非対応でBluemix InfrastructureのVPNが繋がらない！時の対処法【Mac】

#はじめに
Bluemix InfrastructureのVPNが[VPN接続用のサイト](https://www.softlayer.com/jp/VPN-Access)からはうまく繋がらないことがあります。
その原因の1つに[FirefoxではNPAPIのサポートが制限される](https://java.com/ja/download/help/firefox_java.xml)ことが挙げられます。([Chromeも同様](https://www.java.com/ja/download/faq/chrome.xml))

対象方法は様々にあると思いますが、ここでは**MotionPro**というアプリケーションを使って、ブラウザ上のVPNサイトは使わずにVPNに接続する方法を解説します。
正直、プラグイン云々抜きにして、これを使えるようにしておくと、めっちゃ楽。

[KnowledgeLayer](http://knowledgelayer.softlayer.com/articles/standalone-vpn-clients-windows-linux-and-mac-os-x)にアクセスし、解説に従って
http://speedtest.dal05.softlayer.com/array/ArrayMotionProSetup_MacOS_v1.1.2.dmg
をダウンロードします。（MACの場合）
ダウンロードしたファイルを展開します。
（写真の”MotionPro.pkg”をダブルクリックしてその後のガイドに従います
MicrosoftRemoteDesktopも一緒についてきますので、左のアイコンを右にドラッグ＆ドロップしたらこちらも利用可能となります）
![MotionPro.png](https://qiita-image-store.s3.amazonaws.com/0/141025/b9824c03-4e6b-56b7-8e24-174885878179.png)

下の画像のような画面が出てくるので、空いている部分を2本指クリックして、出てくる「追加」をクリックします。
（画面の一行目はBluemixInfrastructureの東京データセンターにVPN接続するための設定です）
![MotionProTop.png](https://qiita-image-store.s3.amazonaws.com/0/141025/fbe3a3ca-a0c7-f73f-15a1-7fa1030022fc.png)

プロファイルに必要な情報を入力します。
「保存パスワード」のチェック欄にチェックを入れると、パスワードも保存できます。
終わったら保存ボタンを押します。
保存したら該当するVPNのサイト名をダブルクリックするとVPN接続できます。
![プロファイル.png](https://qiita-image-store.s3.amazonaws.com/0/141025/43f3f7d0-12e5-2a49-babb-6a7432b3b036.png)

##※1：ユーザー名とパスワードがわからない
Bluemix Infrastructure上部の自分の名前を押してユーザープロファイルを編集します。
そこに書かれているVPN Usernameと任意で入力したパスワードを利用します。
![VPN.png](https://qiita-image-store.s3.amazonaws.com/0/141025/2abdd663-01f1-70b2-7916-6f10a85786f7.png)
「アカウント」ー「ユーザー」ー「VPNアクセス」でSSLVPNが使えるようにするのを忘れずに）


##※2：ホスト名（IP）がわからない
ターミナルで以下のコマンドを入力しましょう
```nslookup <VPNサイトURL>```
<VPNサイトURL>のところには以下のどれか自分が使っているデータセンターを入力しましょう。
(※2017年4月現在に[こちら](http://knowledgelayer.softlayer.com/articles/standalone-vpn-clients-windows-linux-and-mac-os-x)に載っていたデータセンターです)
**東京：vpn.tok02.softlayer.com**
    
vpn.ams01.softlayer.com
vpn.ams03.softlayer.com
vpn.dal01.softlayer.com
vpn.dal05.softlayer.com
vpn.dal06.softlayer.com
vpn.dal07.softlayer.com
vpn.dal09.softlayer.com
vpn.sea01.softlayer.com
vpn.wdc01.softlayer.com
vpn.wdc04.softlayer.com
vpn.hou02.softlayer.com
vpn.sjc01.softlayer.com
vpn.sjc03.softlayer.com
vpn.sng01.softlayer.com
vpn.atl01.softlayer.com
vpn.chi01.softlayer.com
vpn.den01.softlayer.com
vpn.lax01.softlayer.com
vpn.mia01.softlayer.com
vpn.nyc01.softlayer.com
vpn.hkg02.softlayer.com
vpn.lon02.softlayer.com
vpn.sao01.softlayer.com
vpn.mil01.softlayer.com
vpn.mel01.softlayer.com
vpn.tor01.softlayer.com
vpn.mex01.softlayer.com
vpn.fra02.softlayer.com
vpn.par01.softlayer.com
vpn.syd01.softlayer.com
vpn.che01.softlayer.com
vpn.mon01.softlayer.com


ここまで！お疲れ様でした。
Bitbucket > 新しいUI (2017年4月24日)

```txt:動作環境
Windows 8.1 Pro (64bit)
Google Chrome バージョン 57.0.2987.133
```

Chromeにてbitbucketのレポジトリを見た時「新しいUIを試しますか?」と聞かれて、「いいえ」を選択した。

後で、新しいUIを選択する方法を探したが、なかなか見つからない。

https://blog.bitbucket.org/2017/04/11/bitbucket-cloud-gets-a-new-navigation-experience/
によると以下の手順で新しいUIを試せるようだ。

> If you can’t wait to try the new UI, you can still turn it on! [Visit the Labs page](https://bitbucket.org/account/admin/features/?_ga=1.127121933.1891206915.1488193649) and enable “Bitbucket UI refresh”.

上記のリンク先に行くと「Bitbucket UI refresh BETA」の機能がDisabledになっており、それをEnabledにすることで、新しいUIになった。

新しいUIは横長のブラウザ表示が前提に設計されていて、僕のように1920の横幅を2つのブラウザで閲覧するタイプでは設計が崩れる。
左側の横長のナビゲーションは境界部分を左側にドラッグすることでアイコン表示に変更できる。

`[Turn off new nav]`を選択して、新しいUIを切ることができる。

新しいUIではレポジトリの検索や、新規作成の操作が整理されている。このあたりは使い勝手が良くなったかもしれない。

(追記2017/04/24)
新しいUIはアイコンが直感的でない感じがする。ファイルリスト表示が`<>`というのは記憶が必要。
ダウンロードのアイコンの方がファイルリストの感じがする。
SourceTreeのアイコンもそうだが、自分とは違う感覚の人が設計しているのだろう。
Material-UIのRaisedButtonでラベルが見切れたときに三点リーダを表示する

※本記事の内容は[Material-UI v0.16.7](http://www.material-ui.com/v0.16.7/#/components/raised-button)にもとづいています。

## RaisedButtonの構造
RaisedButtonは、下記のようなHTML構造になっている。

```
<div>・・・①
  <button>・・・②
    <div>・・・③
      <div>・・・④
        <span>「ラベル文字列」</span>・・・⑤
      </div>
    </div>
  </button>
</div>

```

## RaisedButtonのスタイル関連のプロパティ
RaisedButtonにはスタイルを指定するプロパティが複数存在する。
表にまとめると下記の通り。

|プロパティ名|説明|HTML構造における対応箇所|
|:---:|:---|:---:|
|buttonStyle|button要素のインラインスタイルを上書きする|②|
|labelStyle|ボタンのラベル要素のインラインスタイルを上書きする|⑤|
|overlayStyle|ボタンオーバーレイ時のインラインスタイルを上書きする|④|
|rippleStyle|ボタン押下時の波紋のインラインスタイルを上書きする|クリック時に③と④の間に生成されるspan|
|style|ルート要素のインラインスタイルを上書きする|①|


## RaisedButtonのデフォルト状態での描画
RaisedButtonに対して何もスタイルを指定しないと下図のようなり、画面幅を縮めた場合などにラベルが入り切らない。
![スクリーンショット 2017-04-17 17.24.29.png](https://qiita-image-store.s3.amazonaws.com/0/29971/d9cd6a91-d37b-0c55-e859-176e72011908.png "スクリーンショット 2017-04-17 17.24.29.png")


```javascript:default.js
<RaisedButton
  label="ラベルラベルラベルラベル"
  primary={true} />

```

## RaisedButtonのラベルがはみ出たときに3点リーダにする
下図のように、3点リーダに置き換えるには少し工夫が必要になる。
![スクリーンショット 2017-04-17 17.16.59.png](https://qiita-image-store.s3.amazonaws.com/0/29971/0cdb26a1-1b76-0715-562f-1825dd2ac69e.png "スクリーンショット 2017-04-17 17.16.59.png")

ポイントは下記3つ
- ルート要素（①）にwidthを指定し、minWidthを解除する（親要素に幅を合わせる）
- ③の要素にoverflow, white-space, text-overflowを指定する
- ラベル要素（⑤）にpadding-left, padding-rightを指定する（キレイに見せるため）

③に関しては、RaisedButtonのプロパティで指定できないので、インラインではなくcssに切り出す。
最終的なソースコードは下記。

```javascript:ellipsis.js
<RaisedButton
  label="ラベルラベルラベルラベル"
  primary={true}
  style={{width: '100%', minWidth: 0}}
  labelStyle={{paddingLeft: 0, paddingRight: 0}}
  className="ellipsisButton" />
```

```css:layout.css
.ellipsisButton button div div {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
```
PlayFrameworkで画像をインライン化

# PlayFrameworkで画像をインライン化
リクエスト数課金があるプロダクトを利用するため、CSS Spliteを導入していないWEBサイトの費用が嵩みそうなので、imgタグのsrcをbase64エンコードした画像データに変更してリクエスト数を減らす。
<pre>
package helpers

import org.apache.commons.codec.binary.Base64
import com.google.common.io.ByteStreams

object AssetObj {
  def imageBase64(path: String, ext: String = "png") = {
    try {
      val url = this.getClass().getClassLoader().getResource(s"public/${path}")
      val is = url.openStream()
      try {
        val arr = ByteStreams.toByteArray()
        getBase64(arr, ext)
      } finally {
        is.close()
      }
    } catch {
      case e: Exception => routes.Assets.at(path).toString
    }
  }
  protected def getBase64(source: Array[Byte], ext: String) = {
    val img = new String(Base64.encodeBase64(source))
    s"data:image/${ext};base64,${img}"
  }
}
</pre>
viewで下記のように使える。
<pre>
&lt;img src="@helpers.AssetObj.imageBase64("images/test.png")" alt="test" /&gt;
</pre>
S3を使ってVagrantのBoxを管理する

# 背景
以前は3rd partyのVagrant Boxと一緒にAnsibleのplaybookを同梱して、開発環境を構築/配布していた。
しかし、プロビジョニングする物が増えてきたため、初回構築時のプロビジョニング時間が馬鹿にならなくなってきた。
時間節約のために、プロビジョニング済みのBoxをS3にUPして配布してしまうのが楽だろうと判断した。
※Ansibleのplaybookは変わらず同梱する。

# 問題
S3にアップロードしたBoxのURLを`Vagrantfile`にそのまま記載しただけだと、Boxのバージョニングが行えない。
どうすっかなー。とりあえず公式ドキュメントを漁る。
https://www.vagrantup.com/docs/boxes/format.html

ここの`Box Metadata`が正にそれ。

# どうやったか
## Vagrantfile
Vagrantfileはこんな感じでS3にUPしたJSONファイルを指定しておく。

```ruby:Vagrantfile
config.vm.box = "local-development"
config.vm.box_url = "https://s3-ap-northeast-1.amazonaws.com/local-development/box.json"
config.vm.box_check_update = true
```

この時、`box_check_update`をtrueにしておくと、新しくBoxをS3にUPした際、勝手にアップデートが始まるのでおすすめ。

## S3
Vagrantfileが参照する、JSONファイルはこんな感じ。
BoxもS3のバケットの中に入れておく。

```json:box.json
{
  "description": "Centos7 x86_64",
  "short_description": "CentOS7",
  "name": "local-development",
  "versions": [{
    "version": "1.0.0",
    "status": "active",
    "description_html": "<p>CentOS7 x86_64</p>",
    "description_markdown": "CentOS7 x86_64",
    "providers": [{
      "name": "virtualbox",
      "url": "https:\/\/s3-ap-northeast-1.amazonaws.com\/local-development\/box-1.0.0.box"
    }]
  }]
}
```

BoxのバージョンをUPする際は、`version`と`url`を変えてやれば良い。
これでくそ長いプロビジョニングに付き合わせることなく、Boxのバージョニングもよろしくやれて楽チンダネー。
[JAWS-UG CLI] IAM #79 IAMポリシー(カスタマ管理)の削除


.. 後始末4. IAMポリシーの削除

AWS CLIを利用して、IAMポリシを削除してみます。


前提条件
========


IAMへの権限
-----------

- IAMに対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.70 Python/2.7.12 Linux/4.4.11-23.53.amzn1.x86_64 botocore/1.5.33

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======

まず変数の確認をします。

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>

変数が入っていない、適切でない場合は、それぞれの手順番号について作業を
行います。


0.1. プロファイルの確認
-----------------------

プロファイルの一覧を確認します。

```bash:コマンド:
cat ~/.aws/credentials \
       | grep '\[' \
       | sed 's/\[//g' | sed 's/\]//g'
```

結果(例):

      iamFull-prjz-mbpr13
      <IAMのフル権限を許可されたプロファイル>

```bash:変数の設定:
export AWS_DEFAULT_PROFILE='<IAMのフル権限を許可されたプロファイル>'
```


再確認
--------------

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>


1. 事前作業
===========


1.1. IAMポリシー名の指定
------------------------

ポリシー名を指定します。

```bash:変数の設定:
IAM_POLICY_NAME='<削除するIAMポリシー名>'
```


1.2. IAMポリシーの確認
----------------------

ポリシのバージョンを取得します。

```bash:コマンド:
IAM_POLICY_VERSION=$( \
        aws iam list-policies \
          --max-items 1000 \
          --query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].DefaultVersionId" \
          --output text \
) \
        && echo ${IAM_POLICY_VERSION}
```

結果(例)

      v1

ポリシの内容を見てみましょう。

```bash:コマンド:
aws iam get-policy-version \
        --policy-arn ${IAM_POLICY_ARN} \
        --version-id ${IAM_POLICY_VERSION}
```

結果(例):

      (略)


1.3. ARNの取得
--------------

ARNを取得します。

```bash:変数の設定:
IAM_POLICY_ARN=$( \
        aws iam list-policies \
          --max-items 1000 \
          --query "Policies[?PolicyName==\`${IAM_POLICY_NAME}\`].Arn" \
          --output text \
) \
        && echo "${IAM_POLICY_ARN}"
```

結果(例):

      arn:aws:iam::XXXXXXXXXXXX:policy/<削除するIAMポリシー名>


2. 本作業
=========


IAMポリシーの削除
-----------------

```bash:コマンド:
aws iam delete-policy \
        --policy-arn ${IAM_POLICY_ARN}
```

結果(例):

      (戻り値なし)


3. 事後作業
===========

ポリシーが無いことを確認します。

```bash:コマンド:
aws iam get-policy \
        --policy-arn arn:aws:iam::${AWS_ID}:policy/${IAM_POLICY_NAME}
```

結果(例)

      An error occurred (NoSuchEntity) when calling the GetPolicy operation: Policy arn:aws:iam::XXXXXXXXXXXX:policy/<削除するIAMポリシー名> does not exist or is not attachable.


完了
====
[JAWS-UG CLI] IAM #78 IAMロールの削除




前提条件
========


IAMへの権限
-----------

IAMに対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.70 Python/2.7.12 Linux/4.4.11-23.53.amzn1.x86_64 botocore/1.5.33

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======

まず変数の確認をします。

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>

変数が入っていない、適切でない場合は、それぞれの手順番号について作業を
行います。


0.1. プロファイルの指定
-----------------------

プロファイルの一覧を確認します。

```bash:コマンド:
cat ~/.aws/credentials \
       | grep '\[' \
       | sed 's/\[//g' | sed 's/\]//g'
```

結果(例):

      iamFull-prjz-mbpr13
      <IAMのフル権限を許可されたプロファイル>

```bash:変数の設定:
export AWS_DEFAULT_PROFILE='<IAMのフル権限を許可されたプロファイル>'
```


最終確認
--------------

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>


1. 事前作業
===========


1.1. IAMロール名の指定
----------------------

```bash:変数の設定:
IAM_ROLE_NAME='CodeBuildServiceRole'
```


1.2. IAMロールの確認
--------------------

```bash:コマンド:
aws iam get-role \
         --role-name ${IAM_ROLE_NAME}
```

結果(例):

      {
          "Role": {
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "sts:AssumeRole",
                        "Principal": {
                            "Service": "codebuild.amazonaws.com"
                        },
                        "Effect": "Allow",
                        "Sid": ""
                    }
                ]
            },
            "RoleId": "AROAXXXXXXXXXXXXXXXXX",
            "CreateDate": "2017-04-17T01:23:45Z",
            "RoleName": "CodeBuildServiceRole",
            "Path": "/",
            "Arn": "arn:aws:iam::XXXXXXXXXXXX:role/CodeBuildServiceRole"
          }
      }


2. 本作業
=========


IAMロールの削除
---------------

```bash:変数の確認:
cat << ETX

        IAM_ROLE_NAME: ${IAM_ROLE_NAME}

ETX
```

```bash:コマンド:
aws iam delete-role \
        --role-name ${IAM_ROLE_NAME}
```

結果(例):

      (戻り値なし)


3. 事後作業
===========


IAMロールの不存在確認
---------------------

IAMロールが存在しないことを確認します。

```bash:コマンド:
aws iam get-role \
         --role-name ${IAM_ROLE_NAME}
```

結果(例):

      An error occurred (NoSuchEntity) when calling the GetRole operation: Role not found for CodeBuildServiceRole


完了
====
[JAWS-UG CLI] IAM #77 IAMポリシーのデタッチ


AWS CLIを利用して、IAMロールからポリシーを削除してみます。


前提条件
========


IAMへの権限
-----------

IAMに対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

結果(例):

      aws-cli/1.11.70 Python/2.7.12 Linux/4.4.11-23.53.amzn1.x86_64 botocore/1.5.33

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======

まず変数の確認をします。

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>

変数が入っていない、適切でない場合は、それぞれの手順番号について作業を
行います。


0.1. プロファイルの指定
-----------------------

プロファイルの一覧を確認します。

```bash:コマンド:
cat ~/.aws/credentials \
       | grep '\[' \
       | sed 's/\[//g' | sed 's/\]//g'
```

結果(例):

      iamFull-prjz-mbpr13
      <IAMのフル権限を許可されたプロファイル>

```bash:変数の設定:
export AWS_DEFAULT_PROFILE='<IAMのフル権限を許可されたプロファイル>'
```


最終確認
--------------

```bash:変数の確認:
cat << ETX

        AWS_DEFAULT_PROFILE: (0.1) ${AWS_DEFAULT_PROFILE}

ETX
```

結果(例):

      AWS_DEFAULT_PROFILE: (0.1) <IAMのフル権限を許可されたプロファイル>


1. 事前作業
===========


1.1. IAMロール名の指定
----------------------

```bash:変数の設定:
IAM_ROLE_NAME='<対象となるIAMロール>'
```


1.2. ロールポリシの確認
-----------------------

```bash:コマンド:
aws iam list-attached-role-policies \
        --role-name ${IAM_ROLE_NAME}
```

結果(例):

      {
        "AttachedPolicies": [
          {
            "PolicyName": "<削除対象のIAMポリシー>",
            "PolicyArn": "arn:aws:iam::XXXXXXXXXXXX:policy/<削除対象のIAMポリシー>"
          }
        ]
      }


1.3. IAMロールポリシーの決定
----------------------------

```bash:変数の設定:
IAM_POLICY_NAME='<削除対象のIAMポリシー>'
```


2. ロールポリシーの適用
=======================


ロールポリシーの適用
--------------------

ロールポリシーをIAMロールから削除します。

```bash:変数の確認:
cat << ETX

        IAM_ROLE_NAME:  ${IAM_ROLE_NAME}
        IAM_POLICY_ARN: ${IAM_POLICY_ARN}

ETX
```

```bash:コマンド:
aws iam detach-role-policy \
        --role-name ${IAM_ROLE_NAME} \
        --policy-arn ${IAM_POLICY_ARN}
```

結果(例):

      (戻り値なし)


3. 事後作業
===========


ロールポリシーの確認
--------------------

IAMロールのロールポリシーを確認します。

```bash:コマンド:
aws iam list-attached-role-policies \
        --role-name ${IAM_ROLE_NAME}
```

結果:

      {
          "AttachedPolicies": [], 
      }


完了
====