OmniAICreator/Qiita-1.07M huggingface dataset:
tomcatのjspでjava8を使えるようにする。


javaをjava8にあげて、jsp内でlambdaを使おうとしたら怒られた。ググってみたら、jspで使用するコンパイラの設定が必要
とのことでした。

参考というかそのままですが。
http://docs.escenic.com/ece-tech-notes/5.7/jsp_servlet_configuration.html

考えてみれば当たり前ですが、忘れがちなのでメモ。

TOMCAT_HOME/conf/web.xml のjsp servletにcompilerSourceVMとcompilerTargetVM設定を追加。

```TOMCAT_HOME/conf/web.xml
   <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
        <!-- ここから下の2項目を追加 -->
        <init-param>
            <param-name>compilerSourceVM</param-name>
            <param-value>1.8</param-value>
        </init-param>
        <init-param>
            <param-name>compilerTargetVM</param-name>
            <param-value>1.8</param-value>
        </init-param>
    </servlet>
```
StackOverflow(JP&本家)のFAVをRSS化する方法

[Qiitaのストック一覧をRSS化する方法](http://qiita.com/typista/items/35ddedc4c8cdec989857)、[jsdo.itのfavをRSSで一覧化する方法](http://qiita.com/typista/items/c525e886729803ef7247)に続き、今度はStackOverFlowのFAVをRSS化する方法です。

[RSS Creater](http://rssc.dokoda.jp/)にアクセスして、RSS化したいユーザのURLを入力し、下記のXPathを入力します。

JPは例えば[http://ja.stackoverflow.com/users/168/typista?tab=favorites](http://ja.stackoverflow.com/users/168/typista?tab=favorites)です。

```:XPath(JP)
//*[@id="user-tab-favorites"]//*[@class="user-questions"]///h3
```

本家は例えば[http://stackoverflow.com/users/3851255/typista?tab=favorites](http://stackoverflow.com/users/3851255/typista?tab=favorites)です。

```:XPath(本家)
//*[@id="user-tab-favorites"]/div/div[@class="user-questions"]/div/*[@class="summary"]/h3
```
Scala勉強に役立つ書籍まとめ

Scala勉強に役立つ書籍まとめ
=======

## 初心者向け

- Javaプログラマならこの辺りを読むと良い。

[速攻理解!JavaプログラマのためのScalaプログラミング](http://www.amazon.co.jp/%E9%80%9F%E6%94%BB%E7%90%86%E8%A7%A3-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEScala%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E7%9F%B3%E9%BB%92-%E5%B0%9A%E4%B9%85/dp/4798033669)

[オブジェクト指向プログラマが次に読む本　－Scalaで学ぶ関数脳入門](http://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%8C%E6%AC%A1%E3%81%AB%E8%AA%AD%E3%82%80%E6%9C%AC-%EF%BC%8DScala%E3%81%A7%E5%AD%A6%E3%81%B6%E9%96%A2%E6%95%B0%E8%84%B3%E5%85%A5%E9%96%80-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%86%E3%82%AF%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%E3%82%A2%E3%83%BC%E3%83%88/dp/4774144363/ref=pd_sim_b_9?ie=UTF8&refRID=0SGA9DN2DZVV6B0DS2CJ)

## 中級者向け

- Scalaの特徴を活かしたコードを書きたくなってきたらこれを読むと良い。

[SCALAプログラミング入門](http://www.amazon.co.jp/SCALA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80-%E3%83%87%E3%82%A4%E3%83%93%E3%83%83%E3%83%89%E3%83%BB%E3%83%9D%E3%83%A9%E3%83%83%E3%82%AF/dp/4822284239/ref=pd_sim_b_6?ie=UTF8&refRID=0SGA9DN2DZVV6B0DS2CJ)

## 上級者向け

- Scalaを深く知りたくなったらこれを読むと良い。

[Scalaスケーラブルプログラミング](http://www.amazon.co.jp/Scala%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%A9%E3%83%96%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E7%AC%AC2%E7%89%88-Martin-Odersky/dp/4844330845/ref=pd_sim_b_1?ie=UTF8&refRID=0DFZZ7QHD2QR6K5F4DVX)

## その他

- Scalaの書き方が分からなくて困ったらこれを読むと良い。

[Scala逆引きレシピ](http://www.amazon.co.jp/dp/4798125415/ref=pd_lpo_sbs_dp_ss_2?pf_rd_p=187205609&pf_rd_s=lpo-top-stripe&pf_rd_t=201&pf_rd_i=4798033669&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=0N8KN6WSXR6FYCD0AD2M)
ES6 アロー関数 で underscore.js（の部分適用）が不要になる

## アロー関数

ES6の[アロー関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions)を使うと、無名関数を短く書くことができます。

無名関数とアロー関数を例を使って比較してみます。

### 無名関数の例

```js
var getLength = function(s){ return s.length }
```

### アロー関数の例

上の無名関数を次のように書けます

```js
var getLength = s => s.length
```

- **function**と書く必要がない
- 本文が1行の場合は**return**を書く必要がない

詳しい構文はMDNを読んでください。
C#の[ラムダ式](http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_01/rapidmaster_01.html)と大体一緒です。

## 何が嬉しい？

対象の配列から干支か星座だけを取り出す関数を例にします。

```js
// 干支、星座の定義
const eto = ['ne', 'ushi']
const constellations = ['aries', 'taurus']

// 辞書に含まれる名前だけを取り出す関数
function contains(dictionary, word){
  return dictionary.indexOf(word) !== -1
}

// 干支だけ取りだすには・・・
['ne', 'aries'].filter(function(word){
  return contains(eto, word);
})
```

上の**干支を取り出す処理**は、Underscore.jsの[partial](http://underscorejs.org/#partial)を使って、事前にcontains関数の第一引数をバインドすることで、短く簡潔に書けます。

```js
const isEto = _.partial(contains, eto);

['ne', 'aries'].filter(isEto)
```

アロー関数を使うと、Underscoreを使わなくても

```js
['ne', 'aries'].filter(word => contains(eto, word))
```

短く書くことができます。

## 部分適用のつらさ

### 部分適用のメリット

もとの処理では、filterで使う無名関数外で定義した変数`eto`を参照しています。
部分適用を使うと、`eto`への参照と、**干支を取り出す処理**を分離できます。
**干支を取り出す処理**は、修正する際に考えることが減るため、より安全に修正できます。

また、部分適用を使うことで、引数の多い複雑な関数をラップして、使いやすい引数の短い関数を提供することができます。

### _.partialでの部分適用のデメリット

_.partialを使って部分適用を行った場合、デバッグ時のコールスタックにpartialの呼び出しが挟まります。
コールスタックをたどって、呼び出し元を探すのが大変になります。
これは部分適用をライブラリとして実現しているため、回避不能です。

### Function.prototype.bindでの部分適用のデメリット

JavaScriptが言語レベルでサポートしている部分適用に[Function.prototype.bind](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)があります。
これを使うと、コールスタックには関数呼び出ししか乗りません。
デバッグが大変になることを回避できます。

たとえば

```js
const isEto = contains.bind(null, eto);

['ne', 'aries'].filter(isEto)
```

しかし、第一引数のnullが嫌な感じです。
第一引数なのが嫌です。もっとも重要な位置に、意味のない値を書くのが嫌です。

しかし、第一引数は関数内から参照するthisを指定する時には必要です。
thisは他の引数よりは重要な値ですので、第一引数にいるのは妥当に思えます。
Function.prototype.bindを使う場合、nullをなくす方法はありません。

### 部分適用が適用されるタイミング

部分適用自体の注意点です。
値が適用されるタイミングは、関数の実行時ではありません。

```js
const x = 0
const logX = console.log.bind(console, x)
	
x = 1
logX() // 0
```

部分適用では、bindを実行した時の値がバインドされます。
クロージャのように、関数実行時の値にはなりません。

たとえば、次の例では...

```js
const count = 0;

$('#count_button').on('click', function(){ count++ })
$('#inspect_button').on('click' console.log.bind(console, count))
```

いつ`#inspect_button`ボタンを押しても`0`を表示します。
これは、予想していない動作かもしれません。

### まとめ

部分適用には

- _.partialではコールスタックが汚れる
- Function.prototype.bindでは`null`の記述が気にくわない
- 変数ではなく値が適用される（ことが予想外になることがある）

というデメリットがあります。
単に書く量を減らすために部分適用を使うことはおすすめできません。

## 部分適用せずにアロー関数を使う

```js
['ne', 'aries'].filter(word => contains(eto, word))
```

アロー関数は素敵です。無名関数に比べて悪い点はありません。
かつ今までより短くかけます。

## アロー関数のつらさ

IE11では動きません。
IE11は滅ぼしましょう！
Erlangメモ２

[`crypto:hash/2`](http://www.erlang.org/doc/man/crypto.html#hash-2)
`hash(Type, Data) -> Digest`
`Type = md4 | hash_algorithms()`


```
1> crypto:hash(md5, "/home").
<<72,88,218,181,180,172,22,173,43,125,39,70,152,194,83,42>>
```
---
`handle_info(Info, State) -> Result`

---
The runtime system is started using a **boot script**.
Which boot script to use is specified by the command line flag **-boot**.
`% erl -boot start_all`

The command line flag -init_debug makes the init process write some debug information while interpreting the boot script:

```erlang
$ erl -init_debug
{progress,preloaded}
{progress,kernel_load_completed}
{progress,modules_loaded}
{start,heart}
{start,error_logger}
...
```
---

**`gen_serverのhandle_info/2`**
私達のインターフェースに合わないメッセージは上手く扱えないことに関して私が言ったことは覚えていますよね。 そこで handle_info/2 の登場です。 handle_cast/2 にとてもよく似ていて、事実同じタプルを返します。 違いは、コールバックが、 ! 演算子で直接送られてきたメッセージや、 init/1 の timeout のような特別なメッセージ、モニターの通知や 'EXIT' シグナルのためだけに存在する、ということです。
RMeCabのインストール

Mavericks に RMeCab 0.996 をインストールする方法。
( https://sites.google.com/site/rmecab/home/rmecab_0-9998 の手順に従う )

# MeCab 0.996 のインストール

https://code.google.com/p/mecab/downloads/list から mecab-0.996.tar.gz をダウンロードしておく。

```
$ tar zxvf mecab-0.996.tar.gz
$ cd mecab-0.996
$ ./configure --with-charset="utf-8"
$ make
$ sudo make install
```

# 辞書ファイル(ipadic)のインストール

https://code.google.com/p/mecab/downloads/list から mecab-ipadic-2.7.0-20070801.tar.gz をダウンロードしておく。

```
$ tar zxvf mecab-ipadic-2.7.0-20070801.tar.gz
$ cd mecab-ipadic-2.7.0-20070801
$ ./configure --with-charset="utf-8"
$ make
$ sudo make install
```

# MeCab のテスト

1. mecab コマンドを実行
2. 「すももももももももものうち」と入力
3. エンター

```
$ mecab
すももももももももものうち
すもも  名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
もも    名詞,一般,*,*,*,*,もも,モモ,モモ
も      助詞,係助詞,*,*,*,*,も,モ,モ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
うち    名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS
```

# RMeCab のインストール

RStudio を実行して、Console ウィンドウで以下を実行

```
> install.packages ("RMeCab", repos = "http://rmecab.jp/R")
> library(RMeCab)
```

# RMeCab のテスト

```
> RMeCabC("すももももももももものうち")
[[1]]
    名詞 
"すもも" 

[[2]]
助詞 
"も" 

[[3]]
  名詞 
"もも" 

[[4]]
助詞 
"も" 

[[5]]
  名詞 
"もも" 

[[6]]
助詞 
"も" 

[[7]]
助詞 
"の" 

[[8]]
  名詞 
"うち" 
```
Rの基礎(解析するデータの準備)

RStudio で解析する

# データを入力

## 選択式アンケートの場合

選択肢が1,2,3の設問で、それぞれ以下の回答数になっている場合

|選択肢番号|回答数|
|---|---|
|1|3|
|2|10|
|3|5|


オブジェクトhogeに、↑の状態をセットする。

```
> hoge =  c( 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 )
```

もしくは

```
> hoge = rep(1:3, c(3, 10, 5 ) )
```

見やすく整形
```
table( hoge )
```

## CSVファイルの取り込み

Environment の [Import Dataset]で、CSVファイルを読み込む。

```
pair,date,start,max,min,last
01,2013/01/01,86.7,91.41,86.53,91.09
01,2012/12/01,82.38,86.77,81.72,86.74
01,2012/11/01,79.76,82.83,79.07,82.47
01,2012/10/01,77.95,80.37,77.79,79.76
01,2012/09/01,78.32,79.22,77.09,77.94
01,2012/08/01,78.11,79.66,77.91,78.38
01,2012/07/01,79.9,80.09,77.95,78.1
01,2012/06/01,78.3,80.61,77.64,79.79
01,2012/05/01,79.8,80.6,78.2,78.3
01,2012/04/01,82.95,83.29,79.73,79.81
01,2012/03/01,81.13,84.18,80.58,82.85
02,2013/01/01,114.52,123.86,113.55,123.57
02,2012/12/01,106.94,114.68,105.98,114.44
02,2012/11/01,103.35,107.65,100.32,107.1
02,2012/10/01,100.18,104.59,99.79,103.35
02,2012/09/01,98.55,103.86,97.99,100.22
02,2012/08/01,96.1,99.18,94.9,98.59
02,2012/07/01,101.26,101.26,94.1,96.08
02,2012/06/01,96.82,101.61,95.54,101.07
02,2012/05/01,105.66,106.55,96.5,96.82
```

## 取り込んだCSVデータを利用する

ファイル名がオブジェクト変数名として扱われる


## 取り込んだCSVファイルからデータを抽出して新しいオブジェクトを作成する

例えば、上記のCSVファイル名がfooの場合、pair列の値が2のレコードのmax列を抽出して、barというオブジェクトを作成する場合。

```
> bar = with( foo, max[ pair==2 ] )
```

## 取り込んだCSVデータの部分抽出

(CSVファイル名がfooと仮定)

### 1つのデータを選択

[3行目、4列目]のデータを確認する

```
> foo[3,4]
```

[3行目、4列目]のデータをオブジェクト変数pooに代入する。

```
> poo = foo[3, 4]
```

### 1列のデータを選択

4列目のデータを確認する

```
> foo[,4]
```

[4列目]のデータをオブジェクト変数pooに代入する。

```
> poo = foo[,4]
```

### 複数列のデータを選択

3列目と4列目のデータを確認する

```
> foo[,3:4]
```

3列目と4列目のデータをオブジェクト変数pooに代入する

```
> poo = foo[,3:4]
```


# データを修正


```
> fix( オブジェクト )
```
[ffmpeg] 音声形式の変換方法まとめ

# 条件

* 入力ファイル
 * CD形式の音声 44.1kHz Stereo 16bit
* ffmpeg
 * ffmpeg version 2.4.git　(Linuxでソースコードからコンパイルしたもの)
 * 必要に応じてコーデックのライブラリもインストールしていること

# WAVからFLACへ変換

```shell
ffmpeg -i "input.wav" -vn -ar 44100 -ac 2 -acodec flac -f flac "output.flac"
```

FLAC形式にすれば、音を劣化させずに容量を節約できます。
曲にも依りますがおよそ7割程のサイズになります (wav:50MB→flac:35MB程度)

# WAVからMP3へ変換

```shell
ffmpeg -i "input.wav" -vn -ac 2 -ar 44100 -ab 256k -acodec libmp3lame -f mp3 "output.mp3"
```

ビットレートはabオプションで指定します。個人的な感覚ですが、音の違いが判ったは160kと192kまででしたので、それより少し上でキリが良い数値の256kを使ってます

# WAVからWindows Media形式へ変換

```shell
ffmpeg -i "input.wav" -vn -ac 2 -ar 44100 -ab 128k -acodec wmav2 -f asf "output.wma"
```

Windows Mediaの拡張子は wma または asf となりますが、どちらも同じファイルです

# WAVからOgg Vorbis形式へ変換

```shell
ffmpeg -i "input.wav" -vn -ac 2 -ar 44100 -ab 128k -acodec libvorbis -f ogg "output.ogg"
```


# WAVからAAC形式へ変換

```shell
ffmpeg -i "input.wav" -vn -ac 2 -ar 44100 -ab 128k -acodec libfaac -f mp4 "output.m4a"
```

コーデックにlibfdk_aacが使用できる場合、こちらの方が音質が良くなりますが、一部のプレイヤでは再生できなくなるようですのでご注意ください。質を上げるためにオプションに"-profile:a aac_he -afterburner 1"を追加します。このオプションを指定しないと、話し声向けのプロファイルでエンコードされてしまい、音が悪くなってしまいます

```shell
ffmpeg -i "input.wav" -vn -ac 2 -ar 44100 -ab 128k -acodec libfdk_aac  -profile:a aac_he -afterburner 1 -f mp4 "output.m4a"
```

# MP3からWAVへ変換

```shell
ffmpeg -i "input.mp3" -vn -ac 2 -ar 44100 -acodec pcm_s16le -f wav "output.wav"
```

# 補足

* ar のオプションは省略すると入力ファイルと同じサンプリングレートでエンコードされます
* 最近のffmpegでは、オプションが変わっているようです。"ab"は"b:a"のような形になります。オプションの警告が出た場合は、それに従ってください
CiNii Articlesのコントラストを上げるStylish

Google Chrome 用の Stylish用のStyle

```

  /* 色のカスタマイズ */

  // 検索結果の奇数行の背景色のグレーを薄くする ( #f0f0f0 -> #f5f5f5 )
  .oddlineS{
    background-color: #f5f5f5 !important;
  }

  // 検索結果の、著者,サマリー,ジャーナルの色を黒くする ( #666 -> #000 )
  .item_authordata{
    color : #000 !important;
  }

  .item_summry{
    color : #000 !important;
  }

  .item_journaldata{
    color : #000 !important;
  }


```

Firefoxで使う場合は以下のコード

```
@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("ci.nii.ac.jp") {

{  /* 色のカスタマイズ */

  .oddlineS{
    background-color: #f5f5f5 !important;
  }

  .item_authordata{
    color : #000 !important;
  }

  .item_summry{
    color : #000 !important;
  }
  }
}

```
rspecのbefore(:all)の注意点


rspecでbefore(:all)使うときには気を付けようねというお話。

## before(:all)とbefore(:each)の違い

* before(:all)はcontext/describe ブロックが始まる時に一度だけ実行される
* before(:each)は各スペック内のitの前に実行される

## before(:all)の注意点
通常、各スペックは独立してテストしたい。
でも、before(:all)を使うとそれができなくなる。

```rb
describe User, 'something' do
  before :all do
    @user = User.make
  end

  it 'should so something' do
    # ...
  end

  it 'should so something else' do
    # ...
  end
end
```

例えば上記の例の場合、@userは一度しか作られない。なのでそのレコードに対して一度変更を加えると、次のテストでもその変更が引き継がれ、独立したテストができなくなる。

加えて、before(:all)で作成されたデータは、[テストが終わった後もロールバックされず](https://www.relishapp.com/rspec/rspec-rails/docs/transactions)、データベースに残ってしまう。なので、before(:all)でデータを作成した後は、after(:all)でデータベースをきれいにする必要がある。

## before(:each)を使おう
というわけで、データを作成する際にはbefore(:all)は使わないほうが無難。
基本的にはbefore(:each)を使う。

それが難しい場合には、Database Cleanerを用いる。

```rb
after(:all) do
  DatabaseCleaner.clean_with(:truncation)
end
```

以上、before(:all)を使う際には気を付けましょうというお話でした。

## 参考
* [Using before(:all) in RSpec will cause you lots of trouble unless you know what you are doing](http://makandracards.com/makandra/11507-using-before-all-in-rspec-will-cause-you-lots-of-trouble-unless-you-know-what-you-are-doing)
* [Cleaning up after before(:all) blocks](http://renderedtext.com/blog/2012/10/10/cleaning-up-after-before-all-blocks/)
ruby-graphviz-mindmap で DSL から Mindmap を生成する #mindmap #graphviz #ruby

## :deciduous_tree: 概要
ruby-graphviz-mindmap で DSL から Mindmap を生成します

## :deciduous_tree: 前提
graphviz をインストールしていること

## :deciduous_tree: インストール

~~~bash
$ gem install ruby-graphviz-mindmap
~~~

## :deciduous_tree: DSL から マインドマップを生成
### プログラム
~~~ruby
require 'ruby-graphviz-mindmap'
map = GraphViz::MindMap.build "games", overlap: false
map.node 'Programming Languages', color: :red, shape: :box do
  node 'OO' do
    node 'Java'
    node 'Ruby'
  end

  node 'Functional', color: :blue do
    inherit!
    node 'Haskell'
    node 'Scala'
    node 'Elixir'
  end
end

File.open('programming_languages.dot', 'wb'){|f| f << map.to_dot }
~~~

### dot ファイル出力
~~~bash
% ruby mindmap.rb
~~~

### png 生成出力
~~~bash
% neato -Tpng programming_languages.dot -o programming_languages.png
~~~

## <i class="fa fa-image" style="font-size:1em;"></i> 出力画像を確認

![programming_languages.png](https://qiita-image-store.s3.amazonaws.com/0/43480/fda6a26a-e532-385d-58a9-30352bfac4a1.png)

## :worried: 雑感
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Gviz](https://github.com/melborne/Gviz) でいいんじゃね？感 :worried:

## :books: 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [ruby-graphviz-mindmap GitHub](https://github.com/joshsz/ruby-graphviz-mindmap)
マウスオーバーで灰色マスクとテキスト表示

HTML
```
<div class="banner banner-view">
    <img src="images/018/01.png" />
        <a href="#" class="info">
        <div class="mask">
            <h2>せどりPlan</h2>
            <p>おすすめグッズや役立つ情報ブログ</p>
        </div></a>
</div>
```

CSS
```
<style type="text/css">

/*バナー全体のサイズ*/
.banner {
    width: 300px;
    height: 200px;
    overflow: hidden;
    position: relative;
    text-align: center;
}

/*マウスオーバーするマスク*/
.banner .mask{
    width: 300px;
    height: 200px;
    position: absolute;
    overflow: hidden;
    top: 0;
    left: 0
}

/*見出し*/
.banner h2 {
    color: #fff;
    text-align: center;
    position: relative;
    font-size: 17px;
}

/*テキスト*/
.banner p {
    font-size: 12px;
    position: relative;
    color: #fff;
    text-align: center
}

/*黒にする*/
.banner-view .mask {
    opacity: 0;
    background-color: #000;
    transition: all 0.3s ease-in-out;
}

/*マウスオーバーしたとき　不透明度を下げる**/
.banner-view:hover .mask {
    opacity: 0.8;
}

</style>
```
RubyからAmazon CloudSearchを操作する（AWS SDK Version2版）

こんにちは@joytomoです。
全文検索エンジンと言えば近頃はElasticsearchが元気ですが、
いろいろあって今回はAmazon CloudSearchを使ってみました。

AWS SDKは昨年メジャーアップデートがあり、
それ以降のCloudSearch周りの日本語資料があまり見つからないので、
個人的なメモも兼ねて導入部分を紹介します。

#CloudSearchの設定

早速AWSコンソールからからCloudSearchを開いてみましょう。
他のAWSのサービスと同様に、メニューバーの「Service」から選択して開くことができます。
![スクリーンショット 2015-03-06 2.42.10.png](https://qiita-image-store.s3.amazonaws.com/0/10283/c626c55a-7839-89c4-0a72-99b0e35c9565.png)

この画面では手動で「Domain」を作成したり、「Index Fields」の構成を行ったりできます。
DomainというのはRDBで言うところのテーブルで、Index Fieldsはテーブル定義みたいなものです。

今回はRubyのSDKからDomainを作ったりするのが目的なので、
この画面での操作方法は割愛します。


ではSDKからAWSにアクセスするため、
ACCESS_KEYとSECRET_ACCESS_KEYを発行していきましょう。

この辺りは既知の方も多いと思いますので詳細は省きますが、
Security Credentialsを開いてユーザを発行しましょう。
![スクリーンショット 2015-03-06 2.46.30.png](https://qiita-image-store.s3.amazonaws.com/0/10283/f6613dbd-9399-65c1-350e-a005589f60b4.png)

ユーザを作成するとACCESS_KEYとSECRET_ACCESS_KEYが発行されます。
続いて、Usersのリストから今作成したユーザを開き、ポリシーを追加します。
まずAttach Policyをクリックしましょう。
![スクリーンショット 2015-03-06 2.44.15.png](https://qiita-image-store.s3.amazonaws.com/0/10283/0f67b394-3fb9-22ae-35cc-8ca663f6ee7a.png)

「CloudSearchFullAccess」を選択します。
![スクリーンショット 2015-03-06 2.44.35.png](https://qiita-image-store.s3.amazonaws.com/0/10283/1d2e0b0e-19e6-b745-bbb6-a9baa804cf60.png)

するとポリシーが追加されました。
![スクリーンショット 2015-03-06 2.44.52.png](https://qiita-image-store.s3.amazonaws.com/0/10283/e7456087-276a-dc25-c4ee-5080ab91ab82.png)

これでSDKからCloudSearchにアクセスする準備は完了です。

#Rubyから操作する

まずは準備です。gemのaws-sdkをインストールします。

```
$gem install aws-sdk
```

では早速スクリプトを書いていきます。
まずはDomainを作ってみましょう。

```createCloudSearchDomain.rb
# encoding: utf-8
require 'aws-sdk-core'

cloudsearch = Aws::CloudSearch::Client.new(
  region: 'ap-northeast-1', #Tokyoリージョンです
  access_key_id: 'ACCESS_KEY',
  secret_access_key: 'SECRET_ACCESS_KEY'
)

resp = cloudsearch.create_domain(
  domain_name: "testdomain",
)
puts resp.successful?
```

ACCESS_KEYとSECRET_ACCESS_KEYは先程作成して設定したものを代入してください。
ではこれを流してみます。

```
$ruby createCloudSearchDomain.rb
true
```

responseがtrueになってます。
AWSコンソールを確認すると...
![スクリーンショット 2015-03-06 3.21.16.png](https://qiita-image-store.s3.amazonaws.com/0/10283/e38a39ee-3973-6ce0-18c7-d16bf0e5a1cd.png)
ちゃんとDomainが新たにできていました。
これでひとまずRubyからAmazon CloudSearchを操作するのは出来そうです。

ひとまず今回は以上で！
CloudTrail のログを検索できるサーバーを構築する Ansible playbook (MongoDB)



CloudTrailのログの検索するサーバーの構築についての方法は、 [j3tm0t0さんのブログ](http://d.hatena.ne.jp/j3tm0t0/20131120/1384946995) を参考にさせていただきました。
とても勉強になりました。ありがとうございます。


## 1.インスタンスの準備

CentOS6 か AmazonLinux のサーバーを立ち上げて ssh ログインを可能にしておきます。

## 2.playbookの準備

できた playbook はこちらにおいてあります。
 [Githubのリポジトリ](https://github.com/simeji/ansible-playbooks)
(今回のものはroleなどに切り分けておりません。。)

上記のリポジトリから、ansible-playbook を clone してしてきて、実行します。
対応 OS は **CentOS6** or **AmazonLinux** です。


## 3.playbookの実行

2 で clone してきたディレクトリに入り playbook を実行します。

```bash
git clone https://github.com/simeji/ansible-playbooks.git
cd ansible-playbooks
```

#### AmazonLinuxの場合

```bash
ansible-playbook cloudtrail-search-amazonlinux.yml
```

#### CentOS6の場合

```bash
ansible-playbook cloudtrail-search-centos6.yml
```

#### 共通部分

* APIキー
* Secret
* CloudTrailのログの検索対象 S3バケット+ディレクトリ 

の 3つのプロンプトが出てくるので入力します。
※実行してみればなんとなくわかると思います。

```bash
Please enter your aws_access_key_id: xxxxxxx
Please enter your aws_secret_access_key(secret): <入力しても表示されません>
Please enabled CloudTrail s3 path: <S3の検索対象ログ格納パス>
　※s3:// はいりません。2015年2月のログを全部検索したいなら、  バゲット名/AWSLogs/7xxxxxxx5x3/CloudTrail/ap-northeast-1/2015/02
　のように入力します。
```

すると、ログがダウンロードされてMongoDBにインポートされた状態にまでなります。

## 4.ログの検索

playbookを実行した後はそのサーバーに ssh でログインして、 クエリを投げます。たとえばSecurityGroup関連などの調査したい時で、なんとなくで検索するときなどは、$regexを利用して下記のようにしたりもできます。

```mongo
> db.cloudtrail.find( {"eventName": { "$regex": "Security"} });
```

※ほかにも色々できますのでクエリなどについての詳しいことは [MongoDB公式ドキュメント](http://docs.mongodb.org/manual/reference/operator/) を参考にしてください。


## まとめ

これでちょっとした時に検索する環境が簡単に出来上がります。
S3直接見るより検索しやすいし、結構気になった時にちょこっと立ち上げてすぐ環境をつくって、いらなくなった時に捨てれるので、便利かなと思いました。
シンプルなルーティングがしたかった

[Slim](http://www.slimframework.com/)とかあるけど、僕は別に好きじゃないんだ。

## はじめに

要はWebアプリってHTTPリクエストから任意の函数を起動できりゃいいのだけれども、函数の実体は単なるデータに過ぎないわけで、ルーターの仕事はメソッドとPathから固有の値を返してくりゃ、それだけでいい。

そんなこんなで[Teto Routing](https://github.com/BaguettePHP/TetoRouting)を作った。以下のようなコマンドでインストールできる。

```
composer require zonuexe/simple-routing
```

ルーターをプロジェクトに組み込む方法は[インスパイヤされて掲示板を作りたくなった(3)](http://qiita.com/tadsan/items/498710c5199349e6d7a8)に書いた。

ルーティング定義
-------------

```php
//    Method      Path           ReturnValue  Param => RegExp     extension (format)
$routing_map = [
    ['GET',      '/',            'index'  ],
    ['GET|POST', '/search',      'search' ],
    ['GET',      '/article/:id', 'article',  ['id' => '/^(\d+)$/'], '?ext' => ['', 'txt']],
    ['GET',      '/info',        'feed' ,                           '?ext' => ['rss', 'rdf', 'xml']],
     '#404'       =>             'not_found' // special
];

$router = new \Teto\Routing\Router($routing_map);
$action = $router->match($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
```

`$routing_map`は、ただの入れ子になった配列だ。`'#404' => 'not_found'`だけがちょっと特別で、これはpathがどのパターンにもマッチしなかったときに返す値を指定する。

拡張子マッチ`'?ext' => ['', 'txt']`は奇妙に見えるかもしれないが、`/article/1234`と`/article/1234.txt`のどちらにもマッチする。決して`/article/1234.`にはマッチしない。

`'?ext' => ['*']` でワイルドカード指定することもできる。`/article/1234.txt`にも`/article/1234.xls`にもマッチする。ただし`/article/1234`にはマッチしないので、そのときは`'?ext' => ['', '*']`と書けば良い。

多くの軽量フレームワークやルーターは `$router->get('/article/:id', function($id){ ... });` のようなメソッド呼び出しによるルーティング定義を採用するが、zonuexe/simple-routingでは意図的にそのような形式を採らなかった。

この方式での定義がつらくなるような規模のWebアプリケーションは、相応のフレームワークを採用するべきではなかろうか。[Laravel](http://laravel.com/)とか[CakePHP](http://cakephp.org/)とか。よく知らないけど。

## Actionオブジェクト

`$router->match()`の返り値は[Actionクラス](https://github.com/zonuexe/php-simple-routing/blob/master/src/Action.php)のインスタンスオブジェクトを返す。

`$action->value`でルーティングに定義した返り値が得られるし、`$action->param`でpath中のパラメータの値を連想配列として取得できる。

## 実装例

要は最終的に配列になってればいいので、こうやって書くことも可能。

```php
<?php

$routing = [];

$routing['#404'] = function(){
    // 404の処理
};

$routing[] = ['GET', '/hoge', function(){
    // hogeの処理
}];

$routing[] = ['GET', '/fuga/:id', function($id){
    // fugaの処理
}, ['id' => '/^[1-9]\d*$/']];

$router = new \Teto\Routing\Router($routing);
$action = $router->match($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);

call_user_func_array($action->value, array_values($action->param));
```

ルーターは任意の値を返すことができるので、クロージャーを返すようにすれば、Slimに似た感じの書きかたにもできる。

## もうちょっとした例

[zonuexe/tsukudol-api](https://github.com/zonuexe/tsukudol-api)

## あとがき

こんなことをやってるから、僕の仕事は遅いことに定評がある。
vagrant-awsで立てたインスタンスを手で削除してしまったとき

## そもそも
vagrant-awsでインスタンスを建てる検証をしていたのですが、起動はvagrantでやったものの、停止はAWSの管理コンソールから消してしまっていました。それを忘れていて、もう検証終わったから鍵とかIAMも消しちゃえと消してしまってほったらかしてました。月日が流れ、ふと`vagrant global-status`を叩くと多数のゾンビプロセスが・・・。しかもproviderがawsのものがrunningステータスのままになっていました。

## vagrant haltしてみる
AWSのIDと鍵がないため、エラーになりました。まあそうですよね。鍵情報が残っていれば、haltできるはずです。

```zsh
There are errors in the configuration of this machine. Please fix
the following errors and try again:

AWS Provider:
* An access key ID must be specified via "access_key_id"
* A secret access key is required via "secret_access_key"
```
※ 上記はhaltした際のログが残ってなかったので`vagrant up`したときのものです。たぶん同じ

## vagrant global-status --pruneを使ってみる
調べた所このコマンドでゾンビプロセスが消せるということがわかり、勝ったな、と思っていましたが、結局鍵情報がないため途中で失敗してしまいました。試していないのですが、鍵情報さえあれば、`vagrant global-status`の情報が更新されると思います。

## アンインストールする？
それは最後の手段だろ！ということでパス

## ~/.vagrant.d/data/machine-indexのファイルを消してみる
ここにindexとindex.lockというファイルがありました。json形式のファイルだったため、jqでパースしてみると、こんな感じに

```json
    },
    "b9b5925b43a842a086829654f371a643": {
      "local_data_path": "<project>/.vagrant",
      "name": "test",
      "provider": "virtualbox",
      "state": "aborted",
      "vagrantfile_name": null,
      "vagrantfile_path": "<project>/ci-test",
      "updated_at": null,
      "extra_data": {
        "box": {
          "name": "chef/centos-6.5",
          "provider": "virtualbox",
          "version": "1.0.0"
        }
      }
    },
    "6b2809189e6444079b084c232fbf7300": {
      "local_data_path": "<project>/.vagrant",
      "name": "test",
      "provider": "aws",
      "state": "running",
      "vagrantfile_name": null,
      "vagrantfile_path": "<project>",
      "updated_at": null,
      "extra_data": {
        "box": {
          "name": "dummy",
          "provider": "aws",
          "version": "0"
        }
      }
    },
```
これだ！！！
ということで、両ファイルを削除したところ、すべての仮想マシン情報が出なくなりました。その後、試しにvirtualboxにインスタンスを立ててみたところ、特にエラーもなく使えました。たぶんjson形式で情報を管理しているんでしょうね。
こんなことが起きないようにインスタンスの取り扱いには注意しましょう。他に対処方法があったなら知りたいです。
【小技】sedコマンドで置換する時のオプション

業務でconfigを設定の固有値(IP,FQDN等)だけ変更し、複製しなければならなかったので、sedコマンドで置換し対応した時のメモ。

```sedコマンド例
cat hoge.conf | sed -e 's/hoge/fuga/g' -e 's/test.com/test.test.com/g' > hogehoge.conf 
```

`-e`オプションで繋げることによって、複数の置換を一度に実行できる。

2015/03/18 追記
`-i`オプションを付けることで、リダイレクトせずともファイルの値を置換できる。
プログラミング言語Mokkosu入門 (その2)

# 型
値をその種類に応じて分類したものを型とよびます。例えば整数値は`Int`型に所属しています。Mokkosuでは`let`文で値に名前を付けると出力ウインドウに型が表示されます。

以下のプログラムをコンパイルしてみます。

```
let n = 42;
let t = (2, 3);
fun f = { x -> x * 2 };
fun g = { (x, y) -> x + y };
```

出力ウインドウには以下のように表示されます。

```
n : Int
t : (Int, Int)
f : Int -> Int
g : (Int, Int) -> Int
```

`42`は整数値なので、型には`Int`と表示されます。タプルの型は、要素の型を括弧で囲んで並べたものになります。上の例では整数の2要素タプルなので、型は`(Int, Int)`になります。関数の型は引数の型を`α`戻り値の型を`β`とすると、`α -> β`と表します。上の関数`f`は整数を受け取って整数を返すので`Int -> Int`型になります。関数`g`は引数が正巣のタプル、戻り値は整数なので、`(Int, Int) -> Int`になります。

# ユーザ定義型
型はユーザが定義することもできます。例えば、`Red`、`Blue`、`Green`の3つの値から構成される型`Color`は以下のように定義できます。

```
type Color = Red | Blue | Green;
```

このように定義しておくと、`Red`、`Blue`、`Green`は値としてプログラム中で自由に使えます。以下は`Color`型の値を使って、`Red`を`0`、`Blue`を`1`、`Green`を`2`に対応付ける関数の定義例です。

```
fun color_to_int = { ~Red -> 0; ~Blue -> 1; ~Green -> 2 };
```

プログラム中の`~`は、指定した名前が変数名ではなくタグの名前であることを示しています。コンパイルすると`color_to_int`の型は以下のようになります。

```
color_to_int : Color -> Int
```

自分で定義した型と値が組み込みの型(例えば`Int`型)と同じように扱えていることが分かると思います。

ユーザ定義型の値には引数を持たせることができます。例えば以下の`MaybeInt`のような型を定義できます。

```
type MaybeInt = Success(Int) | Failure;
```

この型を使うと例えば以下のような関数を定義できます。

```
fun div = { (_, 0) ? -> Failure; (x, y) -> Success(x / y) };
```

関数`div`は割り算をする関数です。ただし`0`で除算しようとすると`Failure`という値を返し、割り算に成功した場合は`Success(Int)`という値を返します。

# 自然数の定義
ユーザ定義型を使う練習の一環として、ユーザ定義型で自然数を定義してみましょう。自然数は以下のように定義することができます。

```
type Nat = Zero | Succ(Nat);
```

このように、定義の中で自分自身の型を使うことができます。この定義を使うと例えば自然数の`3`は、

```
let three = Succ (Succ (Succ (Zero)));
```

のように表すことができます。

さて、`Nat`に関する関数をいろいろと定義していきましょう。

まずは、`Nat`型の値を`Int`型の値に変換する関数`nat_to_int`です。

```
fun nat_to_int = {
  ~Zero -> 0;
  ~Succ(n) -> 1 + nat_to_int n
};
```

次は、`Nat`同士の足し算です。

```
fun nat_add = {
  (n, ~Zero) -> n;
  (n, ~Succ(m)) -> Succ (nat_add (n, m))
}; 
```

`nat_to_int`と`nat_add`関数を使うと、以下のようなプログラムが記述できます。

```
let two = Succ (Succ (Zero));
let three = Succ (Succ (Succ (Zero)));

let five = nat_add (two, three);

println (nat_to_int five);
```

# 練習問題
## 問題1
`Int`型の値を`Nat`型の値に変換する関数を定義してください。

## 問題2
`Nat`型同士の掛け算を定義してください。

## 問題3
`Nat`型の累乗を定義してください。

## 問題4
`Nat`型の階乗を求める関数を定義してください。

## 問題5
`Nat`型の引き算を定義してください。

## 問題6
2つの`Nat`型を割ってその商を求める関数を定義してください。

## 問題7
2つの`Nat`型を割ってその余りを求める関数を定義してください。

## 問題8
2つの`Nat`型の値を受け取って値が大きい方を返す関数を定義してください。

## 問題9
2つの`Nat`型の値を受け取って値が小さい方を返す関数を定義してください。

## 問題10
2つの`Nat`型の値の最小公倍数を求める関数を定義してください。
Facebook連携　〜② アプリ登録 〜

***
【目的】
前回から日が経ちましたが、開発者登録が無事に完了したので、今回はアプリを登録したいと思います。
***
####**1.アプリ管理画面を表示する**
　開発者登録をすると、Facebookの左サイドメニュに「管理者」メニューが表示されます。
そこから「アプリを管理する」をクリックします。
![スクリーンショット 2015-03-06 1.13.36.png](https://qiita-image-store.s3.amazonaws.com/0/70430/66b6f478-837a-f9ab-69ef-1e920d1aacd7.png)
　
###**2.アプリを登録していきます。**
　管理者画面の上部にある「My Apps」からアプリを登録を行っていきます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/24589c76-5728-d1fe-9a36-eb2e35e5d82e.png" width="300"/>


「新しいアプリを追加」からiOSを選択します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/6681cadd-97dc-6da1-b609-551524c22462.png" width="300"/>

アプリの名称を任意に設定します。
ここでは、”sample"と入力して、「Create New Facebook App ID」とクリックします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/3bdc1506-7408-114a-d322-1e215b34913e.png" width="300"/>

作成するアプリにあったカテゴリを選択します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/abefe27e-8122-c9f2-98f4-115370720592.png" width="300"/>

アプリの登録が完了しました。
完了画面には、Facebookを開発するための設定方法が記載されていますが、今回はとりあえず一番下までいって「Bundle Identifier」の
設定だけして終了したいと思います。
事前にXcodeでアプリを作成しおき、「Bundle Identifier」を確認します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/8ab4ac47-99aa-8a8c-dc57-987388f8313e.png" width="400"/>


「Bundle Identifier」を入力して、次の画面に遷移します。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/3880319c-c69b-cfd0-b673-f6b5529c849b.png" width="300"/>


画面に記載されている内容をよく見ておいてください。
今回は左上の「Skip Quick Start」を押して「Dashboard」画面にいきました。

ここでは、「App ID」が確認できます。先ほどの入力した「Bundle Identifier」の変更も左サイドメニューの「Settings」
からも行うことができます。

***
【結果】
無事にアプリの登録が完了しましたので、Objective-cからFacebookの連携をしていきたいと思います。

よくわからずやっていますので、ご指摘等はコメントをいただけると助かります。
***
NumberUtilsのisNumberとisDigitの違い

Webページの入力フォームやAPIのパラメータなどが数値かどうか判定したい時は多々ある。
そんな時いつも、何使うんだっけ、NumberUtilsのあれだよほら、クラス名と2つのメソッド名までは出てくるのだが、どっちがどういうのなんだっけ？となってしまうので備忘録として残しておくことにする。

##NumberUtilsクラスを使う
`org.apache.commons.lang.math.NumberUtils`は`commons-lang`等に含まれている。
maven の場合は以下を`pom.xml`に記述することで使用可能となる。

```xml
<dependency>
	<groupId>commons-lang</groupId>
	<artifactId>commons-lang</artifactId>
	<version>2.6</version>
</dependency>
```

##NumberUtils.isNumberとNumberUtils.isDigitの違い


#### *NumberUtils.isNumber(String str)*

```java
public static boolean isNumber(String str)
```
10進数以外も数値であればtrueを返す

ポイント：**javaが数値として解釈できるものであればtrue**

つまり2進数でも16進数でもjavaが解釈できるので数値である

#### *NumberUtils.isDigit(String str)*

```java
public static boolean isDigits(String str)
```
ざっくり言うと、10進数の整数ならtrueを返す

ポイント：**整数(自然数と0)ならばtrue**

`digit`の意味通り、指で数えられるような数値

##まとめ
人間も2進数や16進数を解釈しようと思えば出来なくはないですが、
大根買うのに使わないよね！、という前提で大抵は`NumberUtils.isDigit`を使って
`(人間が入力した)数値かどうか`のチェックをすればよいのではないかと思います。

##おまけ
`StringUtils.isNumeric(CharSequence cs)`ってのもあるようです。

```java
public static boolean isNumeric(CharSequence cs)

StringUtils.isNumeric(null)   = false
StringUtils.isNumeric("")     = false
StringUtils.isNumeric("  ")   = false
StringUtils.isNumeric("123")  = true
StringUtils.isNumeric("12 3") = false
StringUtils.isNumeric("ab2c") = false
StringUtils.isNumeric("12-3") = false
StringUtils.isNumeric("12.3") = false
StringUtils.isNumeric("-123") = false
StringUtils.isNumeric("+123") = false
```
npmのモジュールを依存しているモジュールごとpack

社内環境などのproxy環境下でregistryからのnpm installが403で一切できなかったのでなんとか依存モジュールを含めたpackageを生成できないか試行錯誤してみた。

## packageの生成

### 目的のモジュールをnpm installする
※ここではネットワークに接続する必要あり=家でやる

追記>>>
これができないとなると全ての依存モジュールでpackを繰り返すことになる。
<<<

### モジュールのpackage.jsonの修正
例）gulp.js

```package.json
  "dependencies": {
    "archy": "^1.0.0",
    "chalk": "^0.5.0",
    "deprecated": "^0.0.1",
    "gulp-util": "^3.0.0",
    "interpret": "^0.3.2",
    "liftoff": "^2.0.1",
    "minimist": "^1.1.0",
    "orchestrator": "^0.3.0",
    "pretty-hrtime": "^0.2.0",
    "semver": "^4.1.0",
    "tildify": "^1.0.0",
    "v8flags": "^2.0.2",
    "vinyl-fs": "^0.3.0"
  },

//下記を追記

  "bundledDependencies": [
    "archy",
    "chalk",
    "deprecated",
    "gulp-util",
    "interpret",
    "liftoff",
    "minimist",
    "orchestrator",
    "pretty-hrtime",
    "semver",
    "tildify",
    "v8flags",
    "vinyl-fs"
  ],
```

### npm pack
terminal cmd.exeなりでモジュールのディレクトリ(package.jsonがあるディレクトリ)に移動。
(gulp.jsなら node_modules/gulp）

```Terminal
npm pack
```
これでpackage.tgzができる。
展開すればnode_modulesが含まれていることがわかる。

## proxy環境下でインストールする

```Terminal
npm install ./package.tgz
```
これで無事にインストールされる~~予定。明日試す~~。

### 追記:インストールできました。
Androidアプリ：製品版APK登録後、クローズド・ベータとして配る

Androidアプリを作成し、Play Storeに登録しようとDeveloper Consoleの流れで製品版APKをアップロードしてしまった。けれど、実はクローズドベータとして配布したかった。そんな、あなた向けの記事です。これ、実は製品版アプリとして公開してしまう前ならクローズド・ベータに変更が可能なんです。

Developer Consoleに戻ってみましょう。製品版のAPKとして登録したアプリをベータ版に移行できますね？

![migrate_to_beta.png](https://qiita-image-store.s3.amazonaws.com/0/35954/4d28df31-a05d-bcc6-032a-a6f653c551d6.png)

その後はクローズドベータとして配布すればOKです。GoogleグループやGoogle+のサークルを使って特定のユーザーにのみ配布できます。

![adding_tester_group.png](https://qiita-image-store.s3.amazonaws.com/0/35954/4b9fd94a-2b94-dccb-33f9-47a337972529.png)

まずは最初の図のようにAPKを移行して、製品版 APKを空にしておき、ベータ版のAPKしかない状態にしてからアプリを公開しましょう。製品版APKを移行せずにアプリを一度でも公開すると、新しいアプリとしてパッケージを作成して再登録するしかなくなります。気を付けましょう。
iptablesで正しくポートマッピング

# iptablesでポートマッピング
ConoHaを使い始めました．ConoHaは，インスタンスの前段に仮想ルータがないので，iptablesなどでセキュリティを確保する必要があります．iptablesは，設定に抜けが出てしまいそうで，結構苦手です．

さて，ConoHaに限らず，クラウド上のインスタンスは，不正な接続をなされないように，適切にファイアウォールを設定する必要があります．特にSSHなどは，意図しない接続を排除するよう，注意深く設定する必要があります．私は，22番ポートを2222番ポート[^1]にポートマッピングして，SSH接続をできるようにしています．完全に手抜きなので，よくないですね．

ConoHaでポートマッピングを行うためには，iptablesのNAT機能を使用することが，最も確実な方法だと思います[^2]．本記事では，同一ホスト内で，2222ポートに着信した通信を，22番ポートで待ち受けているsshdにリダイレクトすることを考えます．[80番ポートへ届いたパケットをiptablesでローカルの上位ポートに転送する](http://qiita.com/kawaz/items/ed0030cb29c7d0497b63)を参照すると，natテーブル上にREDIRECTターゲットへジャンプするルールを作成すれば，所望のポートマッピングを実現できます．しかし，このルールのみだと，22番ポートへの直接アクセスを許してしまします．

iptablesでポートマッピングを行いながら，マッピング先への直接アクセスを禁止する方法は，実はあまり知られていないようです．[iptables redirect 80 to 8080 but block public 8080 access](http://stackoverflow.com/questions/11065124/iptables-redirect-80-to-8080-but-block-public-8080-access)や[iptables: how to allow traffic from redirected port](http://unix.stackexchange.com/questions/83120/iptables-how-to-allow-traffic-from-redirected-port)では，マッピング先へのアクセスを禁止する方法がいくつか提示されていますが，mangleテーブルを利用したり，存在しないサービスにマップしたりと，まあ，その，やりたくない方法を使っています．なので，ここに，納得できる設定法を示します．

# 設定例
マッピング先への直接アクセスを禁止し，リダイレクトされたアクセスの場合は許可するルールは，次のようなコマンドで作成することができます．

```
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-ports 22
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctorigdstport 2222 -j ACCEPT
```

1行目は，ポートマッピングの設定です．この設定により，2222番ポートに着信したパケットは，**宛先ポート番号のみ**22番に書き換えられます．ポート番号が書き換えられた後，パケットフィルタリングが行われますが，宛先ポート番号しか書き換えられないため，通常の記法だと直接22番ポートに着信したパケットと区別がつきません．2行目は，ポート番号が2222番から22番に書き換えられたパケットを許可するルールです．ポート番号が書き換えられたパケットに限定するために，conntrackモジュールのctorigdstportオプションを使用しています．[iptablesのドキュメント](http://www.netfilter.org/documentation/HOWTO//netfilter-extensions-HOWTO-3.html#ss3.3)によると，ctorigdstportは，書き換え前のポート番号を指定するオプションです．次に，iptablesによる処理の流れを示します．

![iptables_portmapping.png](https://qiita-image-store.s3.amazonaws.com/0/35580/8347545a-6b60-8921-a772-1a589c20e0a4.png)

# まとめ
ctorigdstportは，ぐぐってもまともな資料がでできませんが，ポートフォワーディングするときには非常に有用なオプションです．

# 失敗設定
次の設定だと，22番でも2222番でも接続できません．

```
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-ports 22
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
```

次の設定だと，22番でも2222番でも接続できてしまいます．

```
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j REDIRECT --to-ports 22
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
```

[^1]: この番号はフィクションです．実際，2222番ポートは，Vagrantなどの有名なツールで，22番ポートの代替として使用されています．したがって，22番の大体ポートとして広く認知されているので，2222番ポートを使用しても，隠していることになりません．
[^2]: ```ssh localhost -L 22:localhost:2222```とかやだなあ．．．inetdを使う方法もあるらしいけど．．．
CollectionView 〜① Single View Applicationから

***
【目的】
iOS6から使用ができるようになったCollectionViewを使ってみます。
***
####**1.プロジェクトを作成**
　Single View Applicationを選択してプロジェクトを作成する。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/d74a0913-91ba-07c0-9903-20359d7686fe.png" width="300"/>

###**2.Storyboard上で「UICollectionView」を配置する**
Object LibraryからCollectionViewを選択してViewにドラッグする。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/daf827e9-6c91-413c-48b1-a73e38e00bb9.png" width="50" />

結果、このようになります。（AutoLayoutの設定も忘れずに）
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/723748aa-35b9-78fb-5310-a3b00ddf77ba.png" width="400"/>

次にセルの識別子(Identifier) を設定します。
ここでは、単純に”Cell”としておきます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/9d428101-5570-572b-0eaa-5bbb30092260.png" width="300"/>

AutoLayoutの設定も忘れずに・・・。

###**3.「ViewController」と接続する**
UICollectionViewを使用するためにViewControllerと紐づけます。
Assistant editorで、storyboardとViewController.hを表示し、ドラッグして接続します。
また、UICollectionViewはセルをどのように表示するか要求をしてきます。その要求をしょりするUICollectionViewDataSourceも使用できるようにしておきます。
同じようにUICollectionViewのイベントを処理するUICollectionViewDelegateも使用できるようにしておきます。

```objc:.h
@interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegate>
#pragma mark - プロパティ
// コレクションビュー
@property (weak, nonatomic) IBOutlet UICollectionView *myCollectionView;

@end
```
```objc:.m
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // データの要求を受け取る先を自分自身に設定する
    self.myCollectionView.dataSource = self;
    // イベントの受け取り先を自分自身に設定する
    self.myCollectionView.delegate = self;
}
```
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/f2ec2963-628f-d6e0-90de-a75e345dc9eb.png" width="200"/>

###**4.「UICollectionViewDataSource」の要求に対して対応していきます。**
まずは、セクションの数をいくつにするか答えます。

```objc:.m
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 2;
}
```

次にセルの数を幾つにするか答えます。
ここでは、１つ目のセクションは２つのセルを作成して、２つ目のセクションは４つ作成することします。

```objc:.m
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    if (section == 0) {
        return 2;
    }
    else{
        return 4;
    }
}
```

最後に表示するセルを設定します。

```objc:.m
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSString * cellIdentifier = @"Cell";
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
    if (indexPath.section == 0) {
        // １つめのセクションは、背景色を赤にする
        cell.backgroundColor = [UIColor redColor];
    }
    else{
        // ２つ目のセクションは背景色を緑にする
        cell.backgroundColor = [UIColor greenColor];
    }
    return cell;
}
```

実行するとこのようになります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/95e87792-6dfc-f611-ef3b-6b3fe8b1f71c.png" width="300" />

***
【結果】
基本的にはUITableViewと同じような考え方で、作ることができました。
次回以降は、これをベースにいろんなことをしていきたいと思います。

何かあれば、コメントをいただけると嬉しいです。
***
Mac OS 10.10 で Titanium が起動できなかった時の対処


## 状況
久々にTitaniumを起動しようとしたらエラーがでて起動できなかった。
考えてみたら、OSをバージョンアップしてから起動してないような気もしたのできっとバージョンアップ関連だろうと思った。

起動するとダイアログに以下のようなメッセージが。

```
See the log file
/Applications/Titanium Studio/configuration/1425568791796.log.
```

ログを見てくれと言われたので見たらこんな感じ

```
!SESSION 2015-03-06 00:19:50.895 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.6.0_65
java.vendor=Apple Inc.
BootLoader constants: OS=macosx, ARCH=x86, WS=cocoa, NL=ja_JP
Framework arguments:  -keyring /Users/MY_NAME/.eclipse_keyring -showlocation
Command-line arguments:  -os macosx -ws cocoa -arch x86 -keyring /Users/MY_NAME/.eclipse_keyring -consoleLog -showlocation

!ENTRY org.eclipse.osgi 4 0 2015-03-06 00:19:52.490
!MESSAGE Application error
!STACK 1
org.osgi.service.application.ApplicationException: No application id has been found.
	at org.eclipse.equinox.internal.app.EclipseAppContainer.startDefaultApp(EclipseAppContainer.java:262)
	at org.eclipse.equinox.internal.app.MainApplicationLauncher.run(MainApplicationLauncher.java:29)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1450)
```

どうやったら直るのかと思ってGoogle先生に聞いてみたけど上手く解決出来なかった。

* Titaniumを入れ直してみるも同じエラーが出る
* ユーザーディレクトリ配下にある設定やキャッシュ？を消しても変化なし
* ここで指定されているURLからjavaを入れても変化なし
  * http://stackoverflow.com/questions/24023956/eclipse-wont-start-after-installing-mac-os-x-yosemite-mac-os-10-10
* JavaのExtensionsかな？を消してみようとしたけど、そもそも無かった
* MaxOS 10.10用の32bit Javaを探すも見つからず

## 考察

* どうも、32bit版Javaが無い状態で32bit版のeclipseを起動しようとしてるっぽい。
* 64bitのeclipseを落としてきて、Titaniumのプラグインを入れるとか出来るかな？
* そもそも、64bitのTitanium何処かに隠れてないかな。

## 対策

どうもまだ64bit版はリリースされてないけどプレビュー版はあるみたい。
ここから64bit版を落として使用する。
http://preview.appcelerator.com/studio/

とりあえず、これで私は起動出来ました。
ファンクターについて勉強したことの整理

学習の素材は、
[すごいHaskellたのしく学ぼう!](http://www.amazon.co.jp/すごいHaskellたのしく学ぼう-Miran-Lipovača/dp/4274068854)

> この表記は、私見・感想です。

## Functor 型クラス
ファンクターとは、関数で写せる(写像、map over) できるもののことをいう。例えば、リスト、Maybe、木がファンクターとなる。つまり、**ある型aから別の型bへの関数** と **ある型aに適用されたファンクター値** を引数にとり、 **別の型bに適用されたファンクター値** を返すもののことをファンクターという。

また、**ファンクターは文脈を持った値だ** とみなすこともできる。Maybe 値は「計算が失敗したかもしれない」という文脈、リストは「複数の値を同時に取るかもしれない」という文脈。この時、`fmap` はこの文脈を維持したまま、内部の値に対して、関数を適用してくれる（後述）。

```hs:Functor型クラス定義
class Functor (f :: * -> *) where
  fmap :: (a -> b) -> f a -> f b
```

> ある型を `Functor` のインスタンスにしたければ、`fmap` ただひとつ実装すれば良い（追記）のではなく、ファンクター則を守る必要がある。ファンクター則とは、基本的な振る舞いが他のファンクターと一致することを保証するためにプログラマが遵守すべきルール。



## ファンクターのインスタンス
`Maybe` や、リスト、`Either a` などがそれに当たる。

```hs:Maybeのインスタンス定義
instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing
```

```hs:リストのインスタンス定義
instance Functor [] where
fmap = map
```

```hs:Either/aのインスタンス定義
instance Functor (Either a) where
fmap f (Left a) = Left a
fmap f (Right a) = Right (f a)
```

```hs:木のインスタンス定義
instance Functor Tree where
fmap f EmptyTree = EmptyTree
fmap f (Node a left right) = 
        Node (f a) (fmap f left) (fmap f right)

-- 値が再帰的な二分木構造になるかもしれない文脈
data Tree a = EmptyTree
            | Node {value::a,  left::(Tree a), right::(Tree a)} deriving (Show)
```

自作の木( 型引数が `String` )について、`fmap`を適用してみると次のように出力される。

```console
*Main> fmap ("this is " ++) (Node "test" EmptyTree EmptyTree)
Node {value = "this is test", left = EmptyTree, right = EmptyTree}
```

## `fmap` の役割
ファンクターは、文脈の持った値であり、それは箱（に入った値）のようなものと表現することもできる。`fmap` は、この文脈（≒ 箱）を保ったまま、引数に取った関数を中の値に適用することができる。

```hs:「複数の値を同時に取るかもしれない」文脈を保ったまま、中の値に関数が適用される。
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b

Prelude> fmap (++ " world!") ["Hello", "Good-by"]
["Hello world!","Good-by world!"]
```

## `fmap` と関数合成
ある1引数関数の型を表す際、アロー演算子を用いて`a -> b` のように書く。この演算子は中置演算子だが、`(->) a b` と表すこともできる。この時、`(-> a)` もファンクターとなる。ここでの文脈は、 **型 `a` の値を適用すると、値が返ってくる** となる。
`fmap :: Functor f => (a -> b) -> f a -> f b` の`f` を `(-> r)` で置き換えてみると、

```hs
fmap :: (a -> b) -> ((->)r ) a -> ((->) r b)
```
`(->)`  を中置演算子として書き直すと

```hs
fmap :: (a -> b) -> (r -> a) -> (r -> b)
```

となる。`fmap` の実装を見てみると、

```hs
fmap f g = (.)
-- or
fmap f g = (\x = f (g x))
```

であり、これは関数合成そのものとなる。

> 関数合成は、文脈を保って中の値に関数を適用するファンクターの一種、ということが言える。

## `fmap` のまとめ
`fmap` とは、２つの観点で説明することができる。

1. 関数とファンクター値を取って、その関数でファンクター値を写してから返す(`fmap ::  (a->b) -> f a -> f b`)
2. 値から値への関数を取って、ファンクター値からファンクター値への関数を返す(`fmap ::  (a->b) -> (f a -> f b)`)

特に、2番目の観点でファンクターを捉える時、`fmap` することを **関数の持ち上げ(lifting)** と呼ぶ。
Firefoxのcanvas上でフォントの斜体(italic)が効かないなら斜めにして書けばいいじゃない

Firefoxではcanvas上にテキストを描画する際、斜体(italic)の指定が効かない場合があります。
(Firefox 36.0で確認)

Firefoxではcanvas上でフォントの斜体が効かない - Qiita
http://qiita.com/gonshi_com/items/59bfcefe8f67075f446d

つまり、italic体を持つフォントの場合(Arial等)は斜めになりますが、italic体を持たないフォント(ＭＳ Ｐゴシック等)はitalicを指定しても斜めになりません。

```js
var ctx = canvas.getContext('2d');
ctx.font = 'italic 20px';
ctx.fillText('hoge', x, y); // Firefoxだと斜めにならない
```

Firefoxでも斜めに表示したい場合もあるでしょう。そういう時はcanvasを斜めにして書けばいいのです。```setTransform``` を使って
canvasを斜めにします。斜めになっているcanvasに文字を書けば、斜めの文字になります。

```js
ctx.setTransform(1, 0, 0, -1/3, 1, y/3, 0);
ctx.fillText('hoge', x, y); // 変形されたカンバスに出力
ctx.setTransform(1, 0, 0, 1, 0, 0); // 変形を元に戻す
```

```setTransform``` は変換行列を使って座標系の変形を行うメソッドです。

setTransform(a, b, c, d, e, f) - Canvasリファレンス
http://www.htmq.com/canvas/setTransform.shtml

```setTransform``` の引数の詳細についてはリンク先をご覧ください。何をやっているかというと、斜体の傾きは約1/3(ブラウザではy軸は上から下なので-1/3)、傾きの変更によって、y座標に比例してx座標が移動してしまうので位置の調整(第5引数でy/3を指定)しています。

これでitalic体をFirefoxでシミュレートできます。
古臭いソース管理をするプロジェクトで、便利そうな事

GitHubでレビューをやる？
自動ビルド＆リリース？

**そんな物はない！**

資産を管理するのはお前のPCのローカルだ！
だが安心しろSVNはあるぞ！
コミットして良いのは本番環境にリリースした物だけだがな！

ブランチ？そんな軟弱な物はない！
リリースは一発勝負！自分でコピーコマンド叩け！

開発始める前にSVNから資産取ってこいよ？
あ、だけどそれが最新かどうかは分からないから、リリース前に本番環境から既存ソース取ってきてマージしろよ？

リリース漏れや、デグレが起きたらお前のせいだからな！


そんなプロジェクトに配属されてしまった私が使っていた、妙なノウハウを展開します。

### ※環境情報
1. ローカルPCはWindows
2. IDEはEclipse
3. 言語はPHP

# 本番環境から資産コピってくる編

さて、開発が終わったのでリリース資産の準備をしましょう。
まずは開発環境と同じフォルダ構成を作って、自分が更新したファイルだけ入れて置かなきゃな。
その後、本番環境資産と差分比較して、開発に使った資産より本番環境資産が新しくなってたらマージをしておこう。
ふぅ、ファイル更新数が多いし、階層も深いからフォルダ構成を手作業で作ってたらスペルミスや構成ミスも多そうだ。
本番環境からソース取ってくるのも全部は取ってこれないし、１個１個持ってくるのも無理な数だよ...

以下はそんな時のノウハウ

1. Eclipseでファイルを開いている時にAlt + Enterを押してファイルプロパティを開く
2. ￥マーク付きのパスをコピーして、「フォルダ作成くん」というフリーソフトを使ってフォルダをローカルに作っていく
3. フォルダが出来たらそこに自分のソースをコピー
4. Explorerで、作ったフォルダの最上位フォルダを開いて、Shift + 右クリック「コマンドプロンプトをここで開く」を実行
5. コマンドプロンプトで「dir /S /B /A-D > [出力ファイル名].sh」を実行
6. 今開いているフォルダに[出力ファイル名].shが出来るので、それをSakuraエディタ等の文字コード変更できるエディタで開く
7. 名前を付けて保存 で改行コードを LF に変更する。文字コードは UTF-8 を指定。
8. ファイルパスの "￥" を "/" に置換する
9. 本番環境サーバのパス構造に合うように、余計にくっついているWindowsのパスを選択する
10. 選択した文字列と、右の文字列を全体置換する　　"cp -pr --parents "
11. "\n" と右の文字列を全体置換する　　" [コピー先ディレクトリ]/\n"
12. ファイルを保存し、サーバーにアップロードして実行する（実行権限は付けてね）

すると、自分が手を入れたソースだけが、フォルダ構造ごとコピーできる。

これはリリース後のバックアップにもなる。

キモとなるのは「フォルダ作成くん」である。
手作業でフォルダを作ると、ほぼ100%ミスるので、ツールに任せるとよいと思う。

以上です。他にもっと良いやり方あるよって人教えて下さい。
Sonar Web APIを使ってみました

SonarのWebページベースの品質サマリは便利なのですが、すべてのパッケージを対象にとあるソースコード違反（nullチェックしてないよ！とか不要なimport文が残ってるよ！とか）を調べたいときに、ちょっと不便だったり、私はSIerなので、品質サマリはHTMLよりExcelが好きな人が多いので［/issue/search］を要求するクライアントを作ってみました。

リポジトリ
https://github.com/sh-ogawa/sonar-web-service-client

## 使用方法
以下のファイルに、sonarのホスト情報やAPIに渡すパラメータの情報を設定できます。
<pre>
src/main/resources/jp/sh4/ooga/sonar/client/sonar-web.properties
</pre>
sonar-common-optionプロパティに共通の設定をし、
sonar-option-XXにチェックルール（コード違反のチェッククラス）のキーを設定します。
XXの部分は被ってなければ、何でも良いです。
順繰り読み取ってSonar Web APIに対して要求をかけます。

テストクラスに取ったデータをcsvファイルへ出力するテストクラスを入れておいたのでそれを実行していただくと、src/test/resources/out/issue.csvへ出力します。
※出力するデータは私が必要だったデータだけです。他のデータが欲しかったらdtoに入っているので出力方法を変えてください。

ちなみに1回の要求で、SOnar Web API都合で最大500件しか取れないみたいなので、取りきれてない場合はsonar-option-XXをコメントアウトしてください。全部の違反を取ってくるようにしてみました。
Promiseのpolyfill(IE11お前もか!)

もう、Webフロントをお客さんの為に作らなくなって早◯年。
Internet Explorerの事なんてさっぱり忘れていた。
社内の端末は全部Mac一色であり、Windowsノートなんて棚の重石に。

ちょっと社内向けにWebアプリを書いている最中にその事件は起こった。

# zERobYTeさん！IEで動きません!

え？いや、まさか。
さすがにさ、InternetExplorerも知らぬ間に11ですよ。
Windows 10のプレビューとか動いてる時代ですよ。

もう、「動かない」なんてことないでしょー。ご冗談を・・・。

過去の嫌な思い出ばかりが脳内を駆け巡った。

# ちょっPromiseが無い

がーん。

# qに置き換えるか、なんかでPolyfillできんの？

```html
<script src="https://www.promisejs.org/polyfills/promise-6.1.0.min.js"></script>
```

ああ、神様。
この１行で全ては解決した。

# このやりどころの無い怒り

いつまで現場の人たちはこのような残念な環境に耐え続けなければならないのだろう。
ラップコード頑張れとか、Polyfillしつづけろとか、もう精神的に無理なので僕は逃げ続けようと思う。
【Yosemite】Photoshopを立ち上げようとするとJava SE 6をインストールしてと言われた時

「詳しく」を押すとインストール画面にいけるらしいが、押しても真っ白の画面にしか行かなかったのでダウンロード先をメモ

[Java for OS X 2014-001](https://support.apple.com/kb/DL1572?viewlocale=ja_JP&locale=en_US)
ActiveRecordで複数カラムをLIKE検索して、特定のカラムにヒットしたものを優先して並び替えたい

> ActiveRecordで複数カラムをLIKE検索して、特定のカラムにヒットしたものを優先して並び替えたい

と思っていろいろ考えた。

最初は`select`に引数として

`CASE WHEN name LIKE #{quoted_keyword} THEN 1 ELSE 0 END AS match_name`

を指定して `order('match_name desc')` としてみたけど、
検索結果を `count()` するとActiveRecordが勝手に `COUNT(DISTINCT CASE ... AS match_name )`
というInvalidなSQLを組み立てたので、あえなく断念した。
(この場合でも count に引数を指定すればちゃんと動く)

もしやこんなのいけるか〜 と思って
`order()` に↑の `CASE WHEN ...` を引数として指定したら動いた。

以下例

```rb
def search_by_keyword(keyword)
  search_columns = [:name, :email, :profile, :company, :address]
  or_wheres = search_columns.map { |c| arel_table[c].match(keyword) }

  quoted_keyword = ActiveRecord::Base.connection.quote(keyword)
  where(or_wheres.inject(:or))
    .order("CASE WHEN name LIKE #{quoted_keyword} THEN 1 ELSE 0 END desc")
end
```