OmniAICreator/Qiita-1.07M huggingface dataset:
ハシモトさんの頭に広がる宇宙 Terraform とは？

## <i class="fa fa-moon-o" style="font-size:1em;"></i>　概要
Terraform について

## <i class="fa fa-question-circle" style="font-size:1em;"></i> Terraform とは？
Terraform は環境構築を自動化するツールです。
以下のような特徴を持ちます。

### <i class="fa fa-code" style="font-size:1em;"></i> インフラのコード化
コードで記述することで、

* 再利用、再実行が可能
* 履歴管理が可能

になります。このあたりは他の Infrastructure as Code 関連のツールと同様です。

~~~
provider "aws" {
    access_key = "ACCESS_KEY_HERE"
    secret_key = "SECRET_KEY_HERE"
    region = "ap-northeast-1"
}

resource "aws_instance" "example" {
    ami = "ami-bddaa2bc"
    instance_type = "t1.micro"
}
~~~

### <i class="fa fa-calendar" style="font-size:1em;"></i> 実行計画
DRY Run が可能です。
インフラ自動化関連は、動作確認に時間がかかるため DRY Run のサポートは地味に大事です。

### <i class="fa fa-calendar" style="font-size:1em;"></i> 更新箇所の検出
実行計画フェーズがあるおかげで、実行前に変更箇所を確認することが可能です。


### <i class="fa fa-image" style="font-size:1em;"></i> リソースのグラフ化
リソースをグラフ化できます。
以下は、実際に Terraform で Heroku のアプリケーションを作成した際のグラフです。

![ruboty-gacha_graph.png](https://qiita-image-store.s3.amazonaws.com/0/43480/398b335e-89f9-51aa-518f-459e68dec62b.png)

## <i class="fa fa-graduation-cap" style="font-size:1em;"></i> より詳しい情報源
* <i class="fa fa-external-link" style="font-size:1em;"></i> [TerraformでHerokuアプリのセットアップ - SOTA](http://deeeet.com/writing/2014/08/04/terraform-heroku/)
* <i class="fa fa-external-link" style="font-size:1em;"></i> [HashiCorpの新オーケストレーションツールTerraformを試してみた - Developers.IO](http://dev.classmethod.jp/cloud/terraform-first-impression/)
* <i class="fa fa-external-link" style="font-size:1em;"></i> [TERRAFORM VS CLOUDFORMATION – A COMPARISON OF INFRA MANAGEMENT TOOLS](https://ypoonawala.wordpress.com/2014/12/14/terraform-vs-cloudformation-a-comparison-of-infra-management-tools/)

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Terraform Official](https://www.terraform.io/)
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Introduction - Terraform Official](https://www.terraform.io/intro/index.html)
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Documentation - Terraform Official](https://www.terraform.io/docs/)
MongoDB で時刻が xx 時台を検索

こんにちは。
MongoDB で、"timestamp" フィールド（ISODate）が 8 もしくは 9 時台にマッチするドキュメント（例 ```{"timestamp" : ISODate("2000-01-01T08:00:00")}``` ）を、力技で検索してみました。

```
$ mongo mydb
MongoDB shell version: 3.0.3
connecting to: mydb
> db.data.aggregate([
    { $project : {"hour": {"$hour" : "$timestamp"}, doc: "$$ROOT"}},
    { $match : {"hour": {$in: [8, 9]} }},
    { $project : {"doc": 1, _id: 0}}
]).forEach( function(x) { print( tojson(x.doc) ); } )
```

ここでは ```.forEach( function(x) { print( tojson(x.doc) ); } )```を加えることで、```{ "doc" : {...} }``` の中の ```...``` を取り出しています。ただし cursor は最後まで一気に走ります。
EV3RT用mrubyサンプルコード(*.rbファイル読み込み版)


yamanekkoでは、way用のETロボコン向けサンプルコードsample_c4をmruby用に移植したものを2種類公開しています。
これは、mrubyには複数のRubyコードの実行方法があるため、実行方法別のサンプルを用意しているためです。

この記事ではその中から、.rbファイルを読み込んで実行するサンプルについて紹介します。
なお、mrubyの環境構築は[こちら](http://qiita.com/yamanekko/items/c2adb87031bf38bb8a13)を参照してください。

## mruby用サンプルプログラムのビルド(ファイル読み込み版)
こちらは普通のRuby同様、Rubyのコンパイルはしません。EV3RTにRubyコードを呼び出すためにmrubyを組み込んだ部分(いわゆるEV3RTのmake app=xxxやmod=xxx)のみコンパイルが必要になります。

### EV3RTのビルド
C/C++と同様に mod=xxx または app=xxx を使用してmakeしてください。

### EV3へプログラムを転送

転送するファイル

* appまたはuImage
* app_ruby2.rb
* balance.rb
* watch.rb

※ balane2.rb はbalance.rbの別バージョンです。差し替えて利用可能です。

このサンプルプログラムはBluetooth経由でファイルを転送することを想定しています。
/ev3rt/apps/配下にRubyのファイルを置きます。(appと同じ場所です)
EV3RTでBluetooth経由でファイル転送する場合、自動的にここに置かれます。

Bluetoothが使えない場合、SDカードにプログラムをコピーして使うこともできます。
EV3からSDカードを抜いて、PCに差し込んでコピーする場合は、/ev3rt/apps/の中にコピーするようにしてください。

### スタンドアロン形式の場合
スタンドアロン形式でビルドした場合（mod=xxxでビルドした場合）もRubyのファイルは/ev3rt/apps/の中にコピーしてください。
uImageはC/C++同様、SDカードのルートに置いてください。
インストール済みパッケージの一覧（Golang）

こんにちは。
Golang でインストール（```go get```）済みパッケージ一覧を、力技で表示させました。

```console
$ find $GOPATH -name '*.go' | grep -E \/[^\.].+\.go | sed -e 's/^.*src\/\(.*\)\/.*go$/"\1"/' |sort|uniq|grep -v $USER
"bitbucket.org/liamstask/goose/cmd/goose"
"bitbucket.org/liamstask/goose/db-sample/migrations"
"bitbucket.org/liamstask/goose/lib/goose"
"github.com/bitly/go-simplejson"
"github.com/cheggaaa/pb"
"github.com/cheggaaa/pb/example"
"github.com/cheggaaa/pb/example/copy"
"github.com/codegangsta/cli"
 :
 :
```

### 更新（シェルスクリプト）
また上記で表示出力されたパッケージの一つを更新しました（シェルスクリプト）。

```console
$ ./gopackage_update.sh github.com/cheggaaa/pb
[remove and reinstall? (y/n)] y
  :
```

```gopackage_update.sh
#!/bin/sh

[ $# -eq 1 ] || exit 1
package="$GOPATH"/src/$1
ls -ld "$package" || exit 1

printf "[remove and reinstall? (y/n)] "
read -r KEYINPUT
[ "${KEYINPUT}" = "y" ] && { rm -rf "$package"; go get -u "$1"; }
exit $?
```
Sassの利用環境を整える　〜インストール〜(Mac)


#まずターミナルを立ち上げ

ターミナルを立ち上げて元々インスコされてる
Rubyのバージョンをチェック。

コマンドは以下

```
ruby -v
```

※2.0系じゃないとsassをインスコしたときエラーが出たりするので要チェック


#Sassのインストール

インストールにはgemコマンドを使用。
実際にコマンドを打ってみる


※gemとは
Rubyにあらかじめバンドルされているパッケージ管理ツール「Rubygem」のこと



```
#コマンド
sudo gem install sass
```

## ※sudoとは
Macはセキュリティ上、システムに関係するコマンドをユーザー権限で実行できないようになっているので、管理者権限の必要なコマンドを実行する場合は、コマンドの先頭に「sudo」をつける必要がある。
※今回はインストール作業で管理者権限が必要なのでsudoコマンドを入力する


#Mac OS で設定しているパスワードを入力

入力しましょー。
下記が出れば無事インスコ完了

```
Fetching: sass-3.4.13.gem (100%)
Successfully installed sass-3.4.13
Parsing documentation for sass-3.4.13
Installing ri documentation for sass-3.4.13
1 gem installed
```

# 最後にSassのバージョンを確認

下記コマンドで確認すべし

```
sass -v
```

下記が出れば問題なし。終了〜

```
Sass 3.4.13 (Selective Steve)
```

# インストールできないときは

エラーが起きてインストールできなかったりする。
ここでつまづくと泣きたくなるので起こった対処を列挙しておきますー

## SSl通信エラー
```
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (http://api.rubygems.org/specs.4.8.gz)

```
gemに含まれているインストーラーの証明書が古いので、
SSLエラーが起こることがある。
※会社のwindowsで起きた…。

## 対処法

1. rubyインストーラーに同梱されている証明書を新しい証明書に書き換えてインスコ
2. SSL通信をやめて普通にインスコ

①についてはこちらの方が詳しくご説明くださってました。
実際参考にして進めました。ありがたい！！！
http://qiita.com/J_Sugar__/items/af0429ee61e21e0febfc
※windowsだけ起こるのかな…？

②については名著「sassの教科書」のエラー対処に掲載されてました。
こちらも参考にさせていただきました〜。
http://book.scss.jp/code/c2/07.html#p83ssl
Server Sent Events最小限のサンプル（PHP）

`index.html`から呼ばれるPHPの実装：

```php:api.php
<?php

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

while (1) {
    echo 'data: Hello from server! ' . date('Y-m-d H:i:s'), "\n\n";
    ob_flush();
    flush();
    sleep(1);
}
```

`index.html`の実装：

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>index.html</title>
</head>
<body>
    <ul id="eventList">
    </ul>
    <script>
        var es = new EventSource('api.php');

        es.addEventListener('message', function (event) {
            console.log(event.data);

            var newElement = document.createElement("li");
            var eventList = document.getElementById('eventList');

            newElement.innerHTML = "message: " + event.data;
            eventList.appendChild(newElement);
        });
    </script>
</body>
</html>
```

* Apache
* PHP（Apacheモジュール）
* Chrome 43

の環境では特に問題なくできた。

## nginx + php-fpmの場合

nginx + php-fpmの場合、普通にしてるとサーバでバッファリングされてしまうので

`nginx.conf` の `server {}` の中で

```
fastcgi_keep_conn on; # < solution

proxy_buffering off;
gzip off;
```

とすればいい。

http://serverfault.com/questions/488767/how-do-i-enable-php-s-flush-with-nginxphp-fpm
によると

```
header('Content-Encoding: none;');
```

でもいいと書いてあったが、自分の環境ではうまくいかなかった。



## ブラウザ実装状況
http://caniuse.com/#feat=eventsource
Firefox、Chromeはほぼ大丈夫。
Androidは4.4から。
IEは11でもダメ。
centos + node.js + npm + nvm インストール

## 0527 追記
とりあえずサクッとnodejsをインストールの場合は以下(centos 6)
$ sudo yum install epel-release
$ sudo yum install nodejs
$ node -v
ついでにnpmをインストールするのであれば
$ yum install -y npm --enablerepo=epel



# 概要

nodejsのバージョン管理 nvm をまず、インストールし
その後、nvmを使ってnodejsをインストールする


#1. nvm インストール
nvmとは、node.js のバージョンを切り替え容易にできるツール

```
▼ nvmをインストール
$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh

▼nvm コマンドが実行できることの確認
$ nvm help
```

#2. nvmを使ってnode.jsをインストール

```
▼インストール可能なnodeのバージョンリストを一覧表示
$ nvm ls-remote

▼インストール
$ nvm install 0.10.38

▼インストールされたことの確認
$ node -v
``` 

#3. nvm設定

```
▼ デフォルトのnodeのバージョンを設定
$ nvm alias default v0.10.26

▼ ターミナル起動時にnvmコマンドが実行できるように設定
vi ~/.bash_profile

if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi
```

#4. node.js サンプルプログラム

▼helloworld.jsを作る
$ vi helloworld.js

```
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

```
▼実行
$ node helloworld.js

▼ブラウザに以下URLを貼り付けて「Hello World」と出たら成功です
http://127.0.0.1:1337/


good luck!
ActiveSupport だけでも Timecop のように時間を固定できるが、使いにくい

Timecop gem を入れなくても ActiveSupport があれば travel_to メソッドで時間を固定できます。
しかし Timecop と比べてみると、ActiveSupport の方は、ブロックを抜けた後、なぜか一気に元の時間まで戻ってしまうため、全体で時間を固定して一部で一時的に時間を変更するような使い方をするテストが書きづらいです。

```ruby
require "active_support/time"

# ActiveSupport
require "active_support/testing/time_helpers"
include ActiveSupport::Testing::TimeHelpers
Time.current                    # => 2015-05-22 22:21:09 +0900
travel_to("1900-01-01") do
  Time.current                  # => 1900-01-01 00:00:00 +0900
  travel_to("1900-01-02") do
    Time.current                # => 1900-01-02 00:00:00 +0900
    travel_to("1900-01-03") do
      Time.current              # => 1900-01-03 00:00:00 +0900
    end
    Time.current                # => 2015-05-22 22:21:09 +0900
  end
  Time.current                  # => 2015-05-22 22:21:09 +0900
end
Time.current                    # => 2015-05-22 22:21:09 +0900

# Timecop
require "timecop"
Time.current                    # => 2015-05-22 22:21:09 +0900
Timecop.freeze("1900-01-01") do
  Time.current                  # => 1900-01-01 00:00:00 +0900
  Timecop.freeze("1900-01-02") do
    Time.current                # => 1900-01-02 00:00:00 +0900
    Timecop.freeze("1900-01-03") do
      Time.current              # => 1900-01-03 00:00:00 +0900
    end
    Time.current                # => 1900-01-02 00:00:00 +0900
  end
  Time.current                  # => 1900-01-01 00:00:00 +0900
end
Time.current                    # => 2015-05-22 22:21:09 +0900
```
[gcc] 空のC++プログラムをgcc5.1でコンパイルすると7KBのヒープアロケーションが起きる

次の様なC++プログラムのソースをgcc5.1でコンパイルする。

```cpp
int main () {}
```

`g++ ./a.cpp`

valgrindでメモリリークをチェックしてみる。

```
==32488== HEAP SUMMARY:
==32488==     in use at exit: 72,704 bytes in 1 blocks
==32488==   total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==32488== 
==32488== LEAK SUMMARY:
==32488==    definitely lost: 0 bytes in 0 blocks
==32488==    indirectly lost: 0 bytes in 0 blocks
==32488==      possibly lost: 0 bytes in 0 blocks
==32488==    still reachable: 72,704 bytes in 1 blocks
==32488==         suppressed: 0 bytes in 0 blocks
==32488== Rerun with --leak-check=full to see details of leaked memory
==32488== 
==32488== For counts of detected and suppressed errors, rerun with: -v
==32488== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 5)
```

7Kバイト以上ヒープが使われていて、しかも回収はOSに投げている。

gcc5.1以外ではそんな事起きない。
objdump見ても、何も変な事はしていない。
cプログラムとしてコンパイルすると、アロケートされない。
あ、そういえばgcc5.1からlibsupc++が変わったんだったな・・・
ちなみに、私の環境では`-O3`でコンパイルして、この空のプログラムを実行するとsystime以外で4msもかかる。前は0ms以下だった。
ふざけんな。

原因
====

[これ](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64535)

多分だけど、libsupc++はメモリを使いきった時でも例外を補足できるようにあらかじめバッファを確保しているっぽい。
ただ、並列環境で大量にスレッド立ててると、メモリ使いきった時に例外がスレッドの数だけ投げられてくる可能性があるので、それだともっと大きなバッファ必要じゃね？ってなって、だったらヒープの方が良いだろうとgccの開発者達は思ったらしい。

ちなみに、バッファの部分のコードは[ここ](https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/eh_alloc.cc?view=markup&pathrev=219988)にある。
抜粋すると

```cpp
115 	      arena_size = (EMERGENCY_OBJ_SIZE * EMERGENCY_OBJ_COUNT
116 	                    + EMERGENCY_OBJ_COUNT * sizeof (__cxa_dependent_exception));
```

ここでバッファのサイズを計算するとちょうど、valgrindの結果と合う。
でも、流石にオーバーヘッドでかすぎだと思う。

libc++は大丈夫です。
Numeric#to_sの返り値のエンコーディング

先日、いろんなエンコードで動くようなコードを書いている時に気づいたことなのですが、

```rb
p 1.to_s.encoding # #<Encoding:US-ASCII>
```
なんと、このエンコーディングは**US-ASCII**となっていました。

ソースを追いかけてみると、`Fixnum`、`Bignum`、`Float`ともに、US-ASCII固定で値を返していました。実行環境を問わずこの仕様のようです。

# 影響する場面は少ないけれど
もっとも、シフトJIS、EUC、UTF-8、ISO-8859-1など、ASCIIの文字がそのまま表現できる文字コードの場合、これらのコードの文字列とUS-ASCIIの文字列と連結することも普通に出来ますし、上位互換の文字コードが指定された正規表現をASCII文字列に走らせることもできます。またRubyのソースコードはこれらのASCII互換の文字コードで書かないといけないので、実質影響する場面としては、

* UTF-16など、ASCII互換でない文字コードのデータを使っている場合
* メソッドで入力値の文字コードを厳密に判定する場合

など、そこまで多くないとは思います。
アプリケーションキャッシュのマニフェストをPHPで生成してみる

Webページをオフラインでも利用できるようにするために[アプリケーションキャッシュ](http://www.html5rocks.com/ja/tutorials/appcache/beginner/)が使えますが、一度導入し始めるとページを更新する度にmanifestのファイルも更新しなければならなくなるのでメンテナンスが大変です。
そこで、ファイルの更新を自動的に判断できるようにPHPでマニフェストを生成できないかなと思って調べてみたら[同じようなことをやっている人がいました](https://github.com/tx2z/autogenerated-cache.manifest-php)。

…が、このコードには微妙に問題があったのでちょっと変更したものを書いておきます。
具体的にはグローバルで宣言されている`$hashes`に関数内からアクセスできていませんでしたので、グローバル変数を使わず関数の戻り値として実装しました。(PHPのバージョンによるのかも…？PHPあんま詳しくないのでよくわからない)

```php:manifest.php
<?php
// Add the correct Content-Type for the cache manifest
header('Content-Type: text/cache-manifest');

// Write the first line
echo "CACHE MANIFEST\n";

// create file body and returns MD5 hash of all files.
function create_manifest($folder) {

  $hashes = '';

  $dir = new RecursiveDirectoryIterator($folder);
  // Iterate through all the files/folders in the current directory
  foreach (new RecursiveIteratorIterator($dir) as $file) {
    $info = pathinfo($file);

    // If the object is a file
    // and it's not called manifest.php (this file),
    // and it's not a dotfile, add it to the list
    if ($file -> IsFile() && $file != "./manifest.php" && substr($file -> getFilename(), 0, 1) != ".") {
      // Replace spaces with %20 or it will break
      echo str_replace(' ', '%20', $file) . "\n";

      // Add this file's hash to the $hashes string
      $hashes .= md5_file($file);
    }
  }

  return md5($hashes);
}

$allFileHash = create_manifest(".");

echo "# Hash: $allFileHash \n";
?>
```

## 使い方

1. `manifest.php`という名前で保存し、Webサーバーの公開ディレクトリに配置します。
2. HTMLファイルから`<html manifest="manifest.php">`のようにしてこのファイルを参照します。

これでWebページがオフラインでも利用できるようになる上、ファイルの更新は自動的に検知してくれるようになります。

## 注意点

* ブラウザーがページの更新を検知するためにはまずマニフェストファイルの更新を検知する必要があるため、ページの更新内容を確認しようと思ってブラウザーを更新しても、まずマニフェストの更新だけが取得され、もう一度更新を押した時に初めてページが更新されます。
* 特定のファイルを除外するコードは書いていないので、キャッシュできる容量(5MB)を超えている動画ファイルなどがあった場合は正しく動作しません。
* 当然ですが、PHPが動かない環境(Amazon S3など)では使用できません。
* ファイル名を`manifest.php`以外にする場合は、ソースコード中の`manifest.php`という部分をそのファイル名に書き換える必要があります。
drwallet csv download

```js
(function(){
  var downloadCsv = (function() {
      var tableToCsvString = function(table) {
          var str = '\uFEFF';
          for (var i = 0, imax = table.length - 1; i <= imax; ++i) {
              var row = table[i];
              for (var j = 0, jmax = row.length - 1; j <= jmax; ++j) {
                  str += '"' + row[j].replace('"', '""') + '"';
                  if (j !== jmax) {
                      str += ',';
                  }
              }
              str += '\n';
          }
          return str;
      };
      var createDataUriFromString = function(str) {
          return 'data:text/csv,' + encodeURIComponent(str);
      }
      var downloadDataUri = function(uri, filename) {
          var link = document.createElement('a');
          link.download = filename;
          link.href = uri;
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
      };
      return function(table, filename) {
          if (!filename) {
              filename = 'output.csv';
          }
          var uri = createDataUriFromString(tableToCsvString(table));
          downloadDataUri(uri, filename);
      };

  })();
  $.get('/receipts/after_input_data?year=2015&month=5')
    .done(function(data){
      var table = [["トランザクションID","日付","店名","口座","品名", "金額", "カテゴリ","収支"]];
      data.aaData.forEach(function(row){
        var items = data.transactions[row[5]];
        for (key in items) {
          if (items.hasOwnProperty(key)) {
            var item = items[key];
            var io = (item.is_expense) ? "支出":"収入";
            table.push([row[5].toString(),row[0],row[1],row[4],item.name,item.amount.toString(),item.category_name,io]);
          }
        }
      });
      downloadCsv(table);
    });
})();
```

参考:[JavaScript - ブラウザからjsの配列をcsvとしてダウンロードする。 - Qiita](http://qiita.com/ooooooo_q/items/69d67aabf78820d45e46)
RubyOnRailsでサービスを立ち上げた時に使ったgem

Ruby On Railsを使って、Webサービスを立ち上げました。
サービス自体はまだまだこれからですが、
実際にサービスを作る上で利用したgemについてまとめておきます。

:small_blue_diamond: bootstrap-sass

:small_blue_diamond: font-awesome-sass

:small_blue_diamond: sass-rails

:small_blue_diamond: ransack

:small_blue_diamond: kaminari

:small_blue_diamond: carrierwave

:small_blue_diamond: validates_email_format_of

:small_blue_diamond: bcrypt

:small_blue_diamond: nokogiri

:small_blue_diamond: better_errors

:small_blue_diamond: binding_of_caller
JavaScriptの勉強に役立つ書籍まとめ

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

※随時追記します。

## 初心者向け

- JavaScriptはいろいろな本があるけれど、おそらくこの本が一番わかりやすく、いろいろな分野をカバーしていて入門向け。

[プロになるためのJavaScript入門 ~node.js、Backbone.js、HTML5、jQuery-Mobile](http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEJavaScript%E5%85%A5%E9%96%80-~node-js%E3%80%81Backbone-js%E3%80%81HTML5%E3%80%81jQuery-Mobile-Software-Design-plus/dp/4774154385/ref=sr_1_1?s=books&ie=UTF8&qid=1432298428&sr=1-1&keywords=%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEJavaScript%E5%85%A5%E9%96%80)

## 中級者向け

- JavaScriptを使う上で考慮すべき事柄やテクニックがまとまっている2冊。それぞれ微妙に内容は異なりますが、両方とも読むとよいです。

[Effective JavaScript JavaScriptを使うときに知っておきたい68の冴えたやり方](http://www.amazon.co.jp/Effective-JavaScript%E3%80%80JavaScript%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E3%81%8D%E3%81%AB%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%8468%E3%81%AE%E5%86%B4%E3%81%88%E3%81%9F%E3%82%84%E3%82%8A%E6%96%B9-Devid-Herman-ebook/dp/B00EESW7JQ/ref=sr_1_1?s=books&ie=UTF8&qid=1432298462&sr=1-1&keywords=Effective+JavaScript)
[JavaScript Ninjaの極意](http://www.amazon.co.jp/JavaScript-Ninja%E3%81%AE%E6%A5%B5%E6%84%8F-Bear-Bibeault-ebook/dp/B00ESXY9MA/ref=sr_1_1?s=books&ie=UTF8&qid=1432298496&sr=1-1&keywords=javascript+ninja%E3%81%AE%E6%A5%B5%E6%84%8F)

- jQueryのプラグインを書くとき、もしくは読むときに便利です。

[コアjQuery＋プラグイン/jQuery UI 開発実践技法](http://www.amazon.co.jp/%E3%82%B3%E3%82%A2jQuery%EF%BC%8B%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3-jQuery-%E9%96%8B%E7%99%BA%E5%AE%9F%E8%B7%B5%E6%8A%80%E6%B3%95-Programmer%E2%80%99s-SELECTION/dp/4798124281)
コルーチンで、宇宙の　法則が　乱れる！

二つのスクリプトを用意します。

```c#:player.cs
using UnityEngine;
using System.Collections;

public class player : MonoBehaviour {

	void Start () {
		Debug.Log("Player.Start:"+Time.deltaTime);
	}
	
	void Update () {
		Debug.Log("Player.Update:"+Time.deltaTime);
		if (Input.GetMouseButtonDown(0)) {
			StartCoroutine(testCo());
		}
	}

	private IEnumerator testCo(){
		int cnt = 10;
		while (--cnt>0) {
			Debug.Log("**Player.Co:"+Time.deltaTime);
			yield return null;
		}
		yield break;
	}
}

```

```c#:enemy.cs
using UnityEngine;
using System.Collections;

public class enemy : MonoBehaviour {

	// Use this for initialization
	void Start () {
		Debug.Log("Enemy.Start:"+Time.deltaTime);
	}
	
	// Update is called once per frame
	void Update () {
		Debug.Log("Enemy.Update:"+Time.deltaTime);
	}
```

Edit > Project Settings > Script Execution Order
で、player > enemy の順で動作するよう設定します。

![スクリーンショット 2015-05-22 21.35.29.png](https://qiita-image-store.s3.amazonaws.com/0/59911/83bfe7ea-f36d-b4e7-9d7a-0ca5cc9f3d51.png)

実行します
![スクリーンショット 2015-05-22 21.38.30.png](https://qiita-image-store.s3.amazonaws.com/0/59911/7fb14a9b-7789-344a-9ea0-a8bd5f720205.png)

player->enemy||player->enemy||...の順で実行されます。
ここでコルーチンを起動します。
![スクリーンショット 2015-05-22 21.42.55.png](https://qiita-image-store.s3.amazonaws.com/0/59911/0f63390b-3dd4-1ce4-2b57-b79f681daa52.png)

player->playerCo->enemy||player->enemy->playerCo||...の順で実行されます。
コルーチンの初回はオーダー通り（playerから呼ばれた直後）ですが、２回目以降はオーダーが無視されて低い優先で実行されるようです（全てのUpdate後？）。

コントローラー等、スクリプトの優先順位が重要なスクリプトでコルーチンを使う場合は注意しておいたほうが良さそうです。
log4j でアプリケーションの情報ログと各種ライブラリのデバッグログを分ける

バッチアプリケーションなどで、途中経過等を出力するアプリケーション側の情報ログと、フレームワーク等が出力するデバッグログを分ける設定。

log4j.properties に記載します。


```properties
###########################################
# log4j でバッチの情報ログとデバッグログを分ける
###########################################

## アプリケーションの情報ログ
log4j.category.jp.example.batch=INFO, FILE, C
log4j.additivity.jp.example.batch=false

## 各種ライブラリのログ
log4j.category.org.seasar=DEBUG, FILE2, C
log4j.additivity.org.seasar=false

log4j.category.org.apache.axis=INFO, FILE2
log4j.additivity.org.apache.axis=false

log4j.category.org.seasar.extension.jdbc=DEBUG, FILE2
log4j.additivity.org.seasar.extension.jdbc=false

log4j.category.com.google.api.ads.adwords.lib.client.AdWordsServiceClient.requestInfoLogger=INFO, FILE2, C
log4j.additivity.com.google.api.ads.adwords.lib.client.AdWordsServiceClient.requestInfoLogger=false
log4j.category.com.google.api.ads.adwords.lib.client.AdWordsServiceClient.soapXmlLogger=INFO, FILE2, C
log4j.additivity.com.google.api.ads.adwords.lib.client.AdWordsServiceClient.soapXmlLogger=false

## アプリケーションログの出力ファイル設定
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.FILE.Threshold=INFO
log4j.appender.FILE.File=job_exec.log
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE.Append=true
log4j.appender.FILE.BufferedIO=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%-5p %d{MM/dd HH:mm:ss,SSS} %m%n

## ライブラリログの出力ファイル設定
log4j.appender.FILE2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE2.File=job_debug.log
log4j.appender.FILE2.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE2.Append=true
log4j.appender.FILE2.BufferedIO=false
log4j.appender.FILE2.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE2.layout.ConversionPattern=%-5p %d{MM/dd HH:mm:ss,SSS} %m%n

## コンソールの出力設定
log4j.appender.C=org.apache.log4j.ConsoleAppender
log4j.appender.C.Target=System.out
log4j.appender.C.ImmediateFlush=true
log4j.appender.C.layout=org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern=%-5p %d [%t] %m%n

## 基底の設定は、情報ログをアプリケーションログとコンソールへ出力する
log4j.rootLogger=INFO, FILE, C

```

#### See Also

<https://github.com/googleads/googleads-java-lib/blob/master/examples/adwords_axis/src/main/resources/log4j.properties>
海外からの注文エラー

決済にペイパルを使って管理しているECで、海外の特定ユーザーから決済がいつもエラーになります。

エラーコード:10736
メッセージ:A match of the Shipping Address City, State, and Postal Code failed.

<pre>
METHOD: SetExpressCheckout
PAYMENTREQUEST_0_PAYMENTACTION: Sale
PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE: US
PAYMENTREQUEST_0_CURRENCYCODE: JPY
PAYMENTREQUEST_0_SHIPTONAME: ＜アルファベット＋半角スペース＞
PAYMENTREQUEST_0_SHIPTOPHONENUM: ＜数字＋ハイフン＞
PAYMENTREQUEST_0_SHIPTOZIP: 95051
PAYMENTREQUEST_0_SHIPTOSTATE: CA
PAYMENTREQUEST_0_SHIPTOCITY: ＜英数＋.＋半角スペース＞
PAYMENTREQUEST_0_AMT: 7100
MAXAMT: 7100
LOCALECODE: US
SOLUTIONTYPE: Mark
ADDROVERRIDE: 1
ALLOWNOTE: 0
</pre>

この情報でわかる方いらっしゃいますでしょうか。
PHPでstripslashes関数を使うとIPNのValidationがうまくいかない

PayPalのウェブペイメントプラスでクレジット決済を行った後、IPNデータを取得してシステムへのデータ取り込みをPHPで書いているのですが、送られてきたデータが正しいかPayPalに問い合わせるValidationが、VERIFIEDでなくINVALIDで返ってきてしまい、はまりました。

原因は、SHIFT JISの0x5C問題、いわゆる「ダメ文字」というやつで、今回だと「圭」が対象でした。

PayPalのIPNでは、送られてきたでデータをそのままの順序、そのままの内容でPayPalに送り返すことで
通知が正しいもの＝VERIFIEDだと認識されますが、その送り返すデータを作成するときに
stripslashes関数をつかっていたため、ダメ文字の0x5Cが削除されてしまうために、
受信文字列と送信文字列が一致しない結果INVALIDが返却されていました。

<pre>
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= ""&$key=$value"";
}
</pre>

php.iniでmagic_quotesがOFFになっているので、そもそもstripslashes()は呼び出す必要はなかったですね。。

IPNの実装方法についてはこちらに詳しく載っています。
https://developer.paypal.com/docs/classic/ipn/gs_IPN/
プログラミング言語戦争をみても、げっそりしないよ

不思議なことに、特定のプログラミング言語をディスる人が世界中にいる。理解の足りないが故の批判もあるけれど、もっともなものも少なくない。とはいえ、もっともなプログラミング言語批判でも、その批判が何か良いものをもたらすようには見えない。それなのに、炎上したことが、皆の思考を促したと嘯く人もいる。なんだこれ？

しかし、当惑ってのはだいたいにおいて一時的なものだ。私は、肩入れせずに、主だった各プログラミング言語につき10本ずつくらい、そういう記事を読んでみるのがいいと思う。冷めて見渡せば、記事をポストした動機は、たまたま夢見が悪かったとか、そういう事情みたいだ。それがよくわかる。完璧な言語なんて、たぶんなくて、しかも、できることの集合は手続き型言語とでも関数型言語でも同じだ。でも、人々は争う。たぶん、バベルの呪いなんだと思う。でもね、聖書でも、バベルの塔から数百ページめくると、キリストが良いことを言っている。「全世界に出て行って，すべての造られたものにアルゴリズムの素晴らしさを宣べ伝えよ」ってね。彼が「全世界に」とあえて言ったのは「あらゆる言語で」という含みがある。

CもJavaもF#もPHPもhaskellもVBAもjavascriptもscalaもLISPも。SQLだって。色々あるけど、少なくともパーサは僕たちのコードを真剣に読んでくれる。とりあえず、コード書こう。
gitの使い方忘れないように・・・

#Gitの使い方忘れないようにまとめた
というかGitの使い方に癖がありすぎて、使い方もすぐ覚えられないのであくまで自分用にまとめました。

gitってどうやって読むにゃん？？っていう人なら役に立つかもしれません。

まずは大まかなGitの構造と使い方から。

作業ディレクトリに何か変更点が生じた場合、Git環境を構築していると、変更点をGitが感知してくれます。その変更点を自分の作業場からステージングエリアというところに上げて、それを更にコミットすることによって、ローカルレポジトリというところに上げる事ができます。
ローカルレポジトリから更にGitHubなどのリモートレポジトリに上げると、Web環境でのGit管理ができるようになります。

#**　変更内容を保存したい時のすっごい大まかな流れ**

**1.空のレポジトリを作る**　```git init```
作業を始めたいディレクトリで、以下のコマンドを打つと、Gitの空のレポジトリという場所が作成されます。作業始める前にしっかり作っときましょう。


**2.保険のためにbranchを作る**　```git checkout -b hogehoge```
何かやらかすとまずいのでまずはbranch（枝分かれ）を作ります。branchは、原本と同じディレクトリ内容を複製し、そこをいじくることによって原本をいきなりいじくるより安全でしょって考えに基づいて使われます（たぶん）。全く同じディレクトリを複製し、それを編集した後、それを原本に合体させて採用するもよし、イマイチな変更だったらそのbranchはバッサリ切り捨て御免で捨てちゃう、みたいな感じの使い方です。


**3.作業する**
ここで初めて作業を開始します。色々がんばってすごいコードを書いた後は、変更点をGitHubとかにあげたくなりますので（らしいです）、準備段階のステージングエリアに上げましょう。


**4.ステージングエリアに上げる**  ```git add .```
これでcommitが出来る状態になります。忘れるとおこられるし、なにより先に進みません。

**5.コミットする** ```git commit -m "hogeをhugahugaしました"``` 
わかりやすいように、コメント付きで変更内容を保存します。
個人で作業するときでも、ちゃんとしたcommit名を付けた方が後で自分を助けます。

**6.masterのbranchに戻る**```git checkout -b master```
これでmasterに戻れるので、先ほどのbranchでの変更内容を完全に採用する場合はmergeしてください。

**7.合体** ```git merge hogehoge```
これで原本と複製したものが合体されます。一応、hogehoge branchは残るので、煮るなり焼くなり好きにするといいです。

**8.GitHubに上げます** ```git push -u origin master```
このコマンドが、GitHubにある、リモートレポジトリのmaster branchにさっきcommitした内容をアップしますよ！って作業に当たります。
-uオプションは、最初に実行したorigin masterを記憶させるためのものです。以後pushコマンドがオプションなし引数なしで実行されたときに役立ちます。
要するに、これ以降は```git push```するだけで自分の作業ディレクトリのmaster branchの内容が、GitHubリモートレポジトリのmasterブランチに必ずpushされます。ひも付けされるってことですね。


以上で、一通りの使い方になります。
先ほども書きましたが、覚え書きみたいなものなので100%は信用しないほうがいいかもしれません。現時点では自分はこう使ってます、ってだけです。

Gitの何が分かりにくいかって、
「自分が今"どこに居て"、”どのブランチ"の"どのファイル"をGitHubのリモートレポジトリの"master"ブランチに上げる」などいろんな選択肢が取れることですよね。
オプションとかもいっぱいあるので便利なんでしょうけど、初学者には結構とっつきづらいですよね。文句ばかりになりました、すいません、もっと勉強します。。。


////////確認編//////////
```git log```    # => commit状況の確認 
```git status``` # => ステージングエリアの確認


////////削除編//////////
```git reset --hard HEAD``` # => ステージングエリアからファイルを削除する。HEADは今いるブランチで最も新しいものを指す。reset結構危険らしいです。まだ自分もわかりません。
```git revert commitID``` commit自体を削除するコマンド？
apmで不用意にsudoでinstallしない

# Uncaught Error: ENOENT: no such file or directory

UbuntuでAtomに色々とパッケージを入れていたら、こんなエラーが出た。
Uncaught Error: ENOENT: no such file or directory, open '/Users/neilli/.atom/packages/save-session/projects/project.json'

エディタを一回閉じて開きなおした時、直前ファイルを開いておいて欲しいので入れた、「save-session」というpackageでエラーが出ている。

# 原因: "sudo apm install --stars" してた

Windowsでは確認できない現象で、Ubuntuでは環境によってエラー出たり出なかったりで、なんでだろうと思っていた。
しかしどうってことはなく、エラー出る環境ではsudoを使って install 実行していたので、作成されたpackageのフォルダが書き込み不可になっていただけだった。

# 対処: save-sessionをsudoなしで再インストール

一旦save-sessionをアンインストールする
`sudo apm uninstall save-session`

もう一度、今度はsudoを付けずにインストール
`apm install save-session`

なんとなくsudoしていたけど、(自分の使っている範囲では)動かなくなるpackageもなかったので、今後は付けずに操作する。
GNU lsをファイル出力するときは標準出力と見た目が違うから気をつける


## 標準出力

```
$ ls
Plugin		Vendor		app		composer.json	composer.lock	composer.phar	fabfile.py	fabfile.pyc
```

端末上では横に並ぶ。
## ファイル
### tee
```
$ ls | tee ~/test.txt 
Plugin
Vendor
app
composer.json
composer.lock
composer.phar
fabfile.py
fabfile.pyc
```
### 出力した後cat
```
$ ls > ~/test.txt && cat ~/test.txt 
Plugin
Vendor
app
composer.json
composer.lock
composer.phar
fabfile.py
fabfile.pyc
```

## 標準出力も1行1ファイルにしてみる
```
$ ls -1
Plugin
Vendor
app
composer.json
composer.lock
composer.phar
fabfile.py
fabfile.pyc
```
smallbasicでregex

自前のエクステンション使います。
#サンプル
```
GraphicsWindow.BackgroundColor = "skyblue"
button = Controls.AddButton("run", 200, 100)
Controls.ButtonClicked = onclick
Sub onclick
  C = Text.GetCharacter(34)
  R = Text.GetCharacter(13) + Text.GetCharacter(10)
  code = ""
  code = code + "Function setup(a)" + R 
  code = code + "set reg = createObject(" + C + "VBScript.RegExp" + C + ")" + R
  code = code + "reg.pattern = " + C + "a(.)c" + C + R
  code = code + "set mc = reg.execute(" + C + "abc" + C + ")" + R
  code = code + "if mc.count > 0 then" + R
  code = code + "set smc = mc.item(0).submatches" + R
  code = code + "msgbox smc.item(0)" + R
  code = code + "setup = smc.item(0)" + R
  code = code + "end if" + R
  code = code + "End Function" + R
  a = Class1.VBSrun(code)
EndSub
  
```
JDKのバージョンの切替、確認、インストール（Mac OS X）

##最新のJDKのインストール

Homebrew-caskでインストールしていきます。

###まずはbrewのupdateから

```
$ brew update
```

###Homebrew-caskのJDKバージョンを確認

```
$ brew cask info java

java: 1.8.0_45
Java, Java Standard Edition Development Kit
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Not installed
https://github.com/caskroom/homebrew-cask/blob/master/Casks/java.rb
==> Contents
  JDK 8 Update 45.pkg (pkg)
==> Caveats
This Cask makes minor modifications to the JRE to prevent issues with
packaged applications, as discussed here:

  https://bugs.eclipse.org/bugs/show_bug.cgi?id=411361

If your Java application still asks for JRE installation, you might need
to reboot or logout/login.

Installing this Cask means you have AGREED to the Oracle Binary Code
License Agreement for Java SE at

  http://www.oracle.com/technetwork/java/javase/terms/license/index.html
```

###Homebrew-caskでインストール
```
$ brew cask install java
```

##JDKのバージョンの切替

```
$ export JAVA_HOME=`/usr/libexec/java_home -v 1.8.0_45`
```

##JDKのバージョンの確認

```
$ java -version

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
```

##インストールされているJDKのバージョンを確認

```
$ /usr/libexec/java_home -V

Matching Java Virtual Machines (4):
    1.8.0_45, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
    1.7.0_75, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home
    1.6.0_65-b14-462, x86_64:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-462, i386:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
```
smallbasicでsha256

自前のエクステンション使います。
#サンプル
```
GraphicsWindow.BackgroundColor = "skyblue"
button = Controls.AddButton("run", 200, 100)
Controls.ButtonClicked = onclick
Sub onclick
  C = Text.GetCharacter(34)
  R = Text.GetCharacter(13) + Text.GetCharacter(10)
  code = ""
  code = code + "Function setup(a)" + R 
  code = code + "str = " + C + "abc" + C + R
  code = code + "Set text = CreateObject(" + C + "System.Text.UTF8Encoding" + C + ")" + R 
  code = code + "Set sha256 = CreateObject(" + C + "System.Security.Cryptography.SHA256Managed" + C + ")" + R 
  code = code + "hac = sha256.ComputeHash_2(text.GetBytes_4(str))" + R 
  code = code + "For i = 1 To LenB(hac)" + R 
  code = code + "b = b & Right(" + C + "0" + C + " & Hex(AscB(MidB(hac, i, 1))), 2)" + R 
  code = code + "Next" + R 
  code = code + "setup = LCase(b)" + R 
  code = code + "msgbox setup" + R
  code = code + "End Function" + R
  a = Class1.VBSrun(code)
EndSub
```
Unity勉強会「開催予定実績メモ」・「発表資料リンク」（累計開催数：現在31回）

#予定分
* [2015/7/29【#TechBuzz】7/29 第33回代々木Unity勉強会【テーマ：調整中！】](http://unity.connpass.com/event/15168/)

* [2015/6/23【#TechBuzz】6/23 第32回代々木Unity勉強会【テーマ：Unity エディタ拡張でできること、Unity meets Kinect -Unity で NUI を扱ってみた-】](http://unity.connpass.com/event/14547/)

#過去分

* [2015/5/22【#TechBuzz】5/22 第31回代々木Unity勉強会【テーマ：空間インターフェースの作り方 - UnityとBLEデバイスをつないでみるとか/Unity記事をQiitaに作成し、タグストック数1位になる方法/Unity 5のAssetBundleについてまとめてみた】](https://atnd.org/events/64423)

> 資料3 [発表テーマ：Unity 5のAssetBundleについてまとめてみた](http://www.slideshare.net/monry84/20150522-31-unity)

> 株式会社キッズスター　もんりぃさま
大学中退後、都内ITベンチャーを経て、2012年に株式会社アイフリークに入社。2013年04月に同社の会社分割により株式会社キッズスターに転籍し、開発チームリーダーとしてアプリ開発・サーバサイド開発・サーバ運用などを手がける。1984年生まれ。
JavaScriptで指定要素の背景色の輝度を計算する

## はじめに

cssを書いていて、作成中のパーツがどんな色の背景に乗るのか決まらないので文字色が悩ましいなんてことありませんか？

![スクリーンショット 2015-05-22 19.32.42.png](https://qiita-image-store.s3.amazonaws.com/0/673/65548e67-4558-a9e9-9307-b57b7ec84a97.png)

緑の時もあれば

![スクリーンショット 2015-05-22 19.33.47.png](https://qiita-image-store.s3.amazonaws.com/0/673/98fc96e0-e864-8f28-3032-5867f4a271ad.png)

黄色の時もあるんかい……

といった場合に困ってしまいますよね。

## 輝度(luminance)というものがある

Photoshopを使っている人には馴染みがあると思いますが、明度ではなく人間の目が感じる色そのものが持っている輝きみたいなものみたいです。

上の例では黄色地に白抜きはデザインが全く機能していないので文字を黒くしたいところです。

## JavaScriptで計算する

### まずは背景色をゲットする

目的の要素を渡して親の背景色を再帰的に辿って取得すものです

```js
function backgroundColor(el) {
  var color = window.getComputedStyle(el)["background-color"];
  var rgba = color
    .replace(/^rgba?\(/, "")
    .replace(/\)$/, "")
    .split(", ")
    .map(function(val) { return parseInt(val); });

  if (rgba.length > 3 && rgba[rgba.length - 1] === 0) {
    return backgroundColor(el.parentElement);
  } else {
    return rgba;
  }
}
```

### rgbから輝度を算出

こちらのページを参考にしました

> osakana.factory - HSB 値と輝度の求め方
> http://ofo.jp/osakana/cgtips/hsb.phtml

```js
function luminance(rgba) {
  var r = 0.298912;
  var g = 0.586611;
  var b = 0.114478;
  return Math.floor(r * rgba[0] + g * rgba[1] + b * rgba[2]);
}
```

## 輝度120以下だと暗い感じがする

だいたい輝度120くらいがボーダーラインな気がします。HEXだと#777より暗いものは黒い文字が見難くなります。
以下のようにbodyに```.is-dark```クラスを付与したりすると捗りますね。

```js
var el = document.querySelector(".label");
var isDark = luminance(backgroundColor(el)) < 120;

if (isDark) {
  document.querySelector("body").classList.add("is-dark");
}
```

```css
.label {
  color: #000;
}

.is-dark .label {
  color: #fff;
}
```
pryにコードをコピペするためにしておきたい設定

`rails console`などでirbやpryといったREPL（Read-Eval-Print-Loop）を多用する開発をしていると、終いにはプログラムをそこに貼り付けて評価したくなるものです。しかし、REPLは、改行付きメソッドチェーンを上手く評価してくれないという問題があります。

関連して、Rubyでメソッドチェーンを改行して書くとき、ドットを行末に書くか、それとも行頭に書くかという議論がときどきありますが[^1]、ドットを行末に書きたいメインの理由が「REPLに貼り付けたいから」だったりします。

とは言え、そのためだけにコーディングルールを変更したくもないわけで、ここでは、REPL側で解決するための二つの方法と、そのための設定を書きます。

## 方法1：一つの式にしてしまう

REPLが1行ごとに評価されるのは仕方がないので、一つの式にしてしまいましょう。ちなみにRubyはクラスやメソッド定義も式として扱ってくれるので、基本的に何も考えず`()`で囲むだけで十分です。

```irb
irb(main):001:0> (
irb(main):002:1* '1'
irb(main):003:1> .to_i
irb(main):004:1> )
=> 1
```

ただ、pryでメソッドチェーンを正しく認識してもらうにはもうひとつ障害があって、ドットから始めるとシェルコマンドを叩くコマンドとして認識されてしまいます。

```ruby
[1] pry(main)> (
[1] pry(main)*   '1'
[1] pry(main)*   .to_i
Error: there was a problem executing system command: to_i
```

このコマンドはコマンドライン操作も含めてRubyでやろうという素敵な機能ですが、メソッドチェーンの方が大事なので外します[^2]。以下のコードを`~/.pryrc`などに書きましょう。

```ruby
Pry.commands.delete '.<shell command>'
```

## 方法2：pasteboardの中身を直接評価する

基本的にMacでローカルでサーバー立てて開発してるというのであれば、pasteboardを直接評価してしまうコマンドを追加するという方法があります。適当にエディタで書いたプログラムをサクッと評価できるので地味に便利。

```ruby
Pry.commands.delete '.<shell command>'

Pry.commands.block_command (/^.$/), "Evaluate string of `pbpaste`", keep_retval: true do
  string = `pbpaste`
  puts Pry::Helpers::BaseHelpers.colorize_code(string)
  target.eval string
end

# [1] pry(main)> .
# 1
#   .to_i
# => 1
```

以上です。


[^1]: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains

[^2]: 同じ思想のものとして Emacs Lisp で書かれた eshell などがあります。
SSHPASSのインストール（OS X）

## brewコマンドでインストール
```
$ brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb
```

※自分の環境のHomebrewのバージョン(0.9.5)では、以下のコマンドでは、セキュリティエラーによりインストールできませんでした。

```
$ brew install sshpass
```

```
$ brew install https://raw.github.com/eugeneoden/homebrew/eca9de1/Library/Formula/sshpass.rb
```

参考：https://gist.github.com/arunoda/7790979
Qiitaではwindow.consoleは使えない

# 発見の経緯
自社のアプリケーションをブックマークレットで起動してテストすることをよくQiita上で行っていたのだが、出てくるはずの`console.log`が出てこなくてしばらくハマった。
もしかしてと思って`window.console`を調べてみると…

# 結果
![スクリーンショット 2015-05-22 18.46.04.png](https://qiita-image-store.s3.amazonaws.com/0/20695/ddf95e2c-f50b-e984-c165-35dde37b441b.png)

Qiitaでテストするのはやめましょう…
ruby+ocra 1.3.5+特殊な環境でexe化に失敗する件

#特殊な環境において
ocraでrubyスクリプトをexe化しようとすると
downcaseがどうこう言われてexe化に失敗する事があります。

#原因は
ロード済みDLLの探索時にGetModuleFileNameが呼ばれるが、
マルチバイト文字列を適切にエンコードしないままになっているため
- アンチウィルス/パーソナルファイアウォールソフトが日本語ディレクトリ名に格納されてる
- ruby自体が日本語ディレクトリに格納されてる

などのケースに置いて失敗します。
後者はともかく、前者を対策するのは面倒くさい為ちゃっちゃとパッチ書いちゃう

```diff:patch.diff
diff U3Bb C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/old-ocra C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/ocra
--- C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/old-ocra	Fri May 22 18:24:56 2015
+++ C:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/ocra-1.3.5/bin/ocra	Fri May 22 18:38:21 2015
@@ -952,7 +952,7 @@
       require 'Win32API'
 
       enumprocessmodules = Win32API.new('psapi', 'EnumProcessModules', ['L','P','L','P'], 'L')
-      getmodulefilename = Win32API.new('kernel32', 'GetModuleFileName', ['L','P','L'], 'L')
+      getmodulefilename = Win32API.new('kernel32', 'GetModuleFileNameW', ['L','P','L'], 'L')
       getcurrentprocess = Win32API.new('kernel32', 'GetCurrentProcess', [], 'L')
 
       bytes_needed = 4 * 32
@@ -968,9 +968,9 @@
 
       handles = module_handle_buffer.unpack("I*")
       handles.select { |handle| handle > 0 }.map do |handle|
-        str = "\x00" * 256
-        modulefilename_length = getmodulefilename.call(handle, str, str.size)
-        Ocra.Pathname(str[0,modulefilename_length])
+        str = "\x00\x0" * 256
+        modulefilename_length = getmodulefilename.call(handle, str, str.size / 2)
+        Ocra.Pathname(str[0,modulefilename_length*2].force_encoding("utf-16le").encode "utf-8")
       end
     end
```

マルチバイト環境固有の問題は英語圏に説明するのは難しいし、いい感じのテストケース用意するのが難しすぎる
ES6 で書く環境を作る（gulp + Babel 編）


前回の投稿([ES6 で書く環境を作る（WebStorm + Babel 編）](http://qiita.com/hkusu/items/e6ae07277356d0bbe2d7))では Babel を WebStorm から実行しましたが、今回は WebStorm でなく [gulp](http://gulpjs.com) から実行してみます。
(柔軟性を考えると、こちらの方が良いかも。)

### 前提環境

> OS：`Mac OS X 10.9.5`
> Bable：`5.4.7`
> gulp：`3.8.11`
> gulp-babel：`5.1.0`
> npm：`2.7.5`

## 手順

### ① `gulp` と `gulp-babel` をインストール

適当なプロジェクト用ディレクトリを作り、

```shell:
$ mkdir work
```

次のコマンドで、このプロジェクトのルート直下に `package.json` を作成します。（対話インタフェースで色々聞かれますが適当に。）

```shell:
$ cd work
$ npm init
```

私の場合は次のように作成されました。

![スクリーンショット 2015-05-22 18.03.48.png](https://qiita-image-store.s3.amazonaws.com/0/35733/862d84aa-5f14-c8f0-4c90-7a11e00a0f42.png "スクリーンショット 2015-05-22 18.03.48.png")

`package.json` が作成されたら、このプロジェクト配下(グローバルでなく)に `gulp` と `gulp-babel` をインストールします。

```shell:
$ npm install --save-dev gulp
$ npm install --save-dev gulp-babel
```

すると `node_modules` ディレクトリに `gulp` と `gulp-babel` がインストールされ、`package.json` は次のようになりました。

![スクリーンショット 2015-05-22 18.06.54.png](https://qiita-image-store.s3.amazonaws.com/0/35733/6dcd47a7-ad49-6ad3-ca2f-9108f1d9e51a.png "スクリーンショット 2015-05-22 18.06.54.png")

> `package.json` の作成は必須ではないのですが、後で本環境を `$ npm install` で再現できるようになるので、作成することをオススメします。また通常、`node_modules` ディレクトリは Git の管理から外します（`package.json` から再現できるものなので）。

### ② gulp のタスクを作成

このプロジェクトのルート直下に gulp 用の設定ファイル `gulpfile.js` を新規に作成し、

![スクリーンショット 2015-05-22 18.09.21.png](https://qiita-image-store.s3.amazonaws.com/0/35733/370e52be-9009-2dc1-d621-2e80a8f40751.png "スクリーンショット 2015-05-22 18.09.21.png")

次のように記載します。

```javascript:gulpfile.js
var gulp = require("gulp");
var babel = require("gulp-babel");

gulp.task('babel', function() {
  gulp.src('./*.es6')
    .pipe(babel())
    .pipe(gulp.dest('./'))
});

gulp.task('watch', function() {
  gulp.watch('./*.es6', ['babel'])
});

gulp.task('default', ['babel', 'watch']);
```

> このプロジェクトのルート直下の `.es6` ファイルを Babel で変換する、という内容です。`gulp.watch` で、ファイルの変更を監視しています。

## 変換してみる

適当に ES6 の記法でスクリプトを書き、

![スクリーンショット 2015-05-22 18.11.46.png](https://qiita-image-store.s3.amazonaws.com/0/35733/ddc87b8e-343a-719c-0473-ad1bdc27cd3d.png "スクリーンショット 2015-05-22 18.11.46.png")

gulp を実行すると、

```shell:
$ cd work
$ gulp
```

次のように変換されます。

![スクリーンショット 2015-05-22 18.12.56.png](https://qiita-image-store.s3.amazonaws.com/0/35733/663c7a95-6da6-ffe6-9d80-63eb39e76e7e.png "スクリーンショット 2015-05-22 18.12.56.png")

gulp のタスクによりファイルの変更が監視されているので、スクリプトを保存する度に自動的に変換されます。

## 動作確認

ブラウザで動作確認してもいいのですが、console.log 程度なら次のようにコマンドでも確認できます。

![スクリーンショット 2015-05-22 16.18.05.png](https://qiita-image-store.s3.amazonaws.com/0/35733/8e988a51-987f-2d7f-bac4-b8e86f7c575e.png "スクリーンショット 2015-05-22 16.18.05.png")

## ほか

gulp でソースマップも出力する方法は [Babelの公式ページ](http://babeljs.io/docs/setup/#gulp) に書いてあります。

あと gulp 自体の使い方は [ドットインストール の gulp入門](http://dotinstall.com/lessons/basic_gulp) あたりが分かり易かったです。
（今回はいろいろ省きましたが、ちゃんとやれば gulp でもっと色々できそう。）
Rails の controller からパラメータを rack middleware に渡す

もしくは controller 内のパラメータを access log として吐き出す方法。

request.env に適当に値をつっこめばよい

```rb:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  after_action  :set_access_log_info
  
  def set_access_log_info
    info = {}
    info[:controller]   = params[:controller]
    info[:action]       = params[:action]
    info[:user_name]    = current_user.name if current_user
    request.env[:my_access_log_info] = info
  end
end
```

たとえば access log を吐き出す rack middleware

```rb:lib/my/rack/access_logger.rb

require 'time'

module My
  module Rack
    class AccessLogger
      PID = Process.pid

      def initialize(app, io=nil)
        @app = app
        @io = io || $stdout
      end

      def call(env)
        began_at = Time.now.instance_eval { to_i + (usec/1000000.0) }

        status, headers, body = @app.call(env)

        now = Time.now
        reqtime = now.instance_eval { to_i + (usec/1000000.0) } - began_at

        params = {
          time: now.iso8601,
          host: env["REMOTE_ADDR"] || "-",
          vhost: env['HTTP_HOST'] || "-",
          pid: PID,
          forwardedfor: env['HTTP_X_FORWARDED_FOR'] || "-",
          method: env["REQUEST_METHOD"],
          path: env["PATH_INFO"],
          query: env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
          ua: env['HTTP_USER_AGENT'] || "-",
          status: status.to_s[0..3],
          size: extract_content_length(headers),
          reqtime: "%0.6f" % reqtime,
        }
        # env[:my_access_log_info] is coming from ApplicationController
        params.merge!(env[:my_access_log_info]) if env[:my_access_log_info]
        @io.write params.to_json << "\n"

        [status, headers, body]
      end

      private

      def extract_content_length(headers)
        value = headers['Content-Length'] or return '-'
        value.to_s == '0' ? '-' : value
      end
    end
  end
end
```

rack middleware を rails rack middleware の先頭に差し込む設定

```rb:config/application.rb
  class Application < Rails::Application
...
    require_relative '../lib/my/rack/access_logger'

    config.middleware.insert_after(0, My::Rack::AccessLogger, $stdout)
....
  end

```

こんなかんじ
[swift]UIImage(contentsOfFile: String)を使ってて困ったこと 


**現象:**
実行時に以下のエラーで落ちる
[error: unexpectedly found nil while unwrapping an Optional value]


ちなみにソースはこんな感じ

```
let image: UIImage  = UIImage(contentsOfFile: path)!	// pathはDBから取得
```

**原因:**
アプリのDocumentsパスが再起動するたびに変わるっぽい
なので、同じ要領でパス指定すると`NSData(contentsOfURL: url!)`
でも同じエラーが発生するっぽい

**対策:**
こんな感じだろうか

```
// Documentsディレクトリ
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
// 画像ファイルパス:imageNameは表示したい画像ファイル名
let imagePath = documentsPath.stringByAppendingPathComponent(imageName)
let image: UIImage = UIImage(contentsOfFile: imagePath)!
```

毎回Documentsパスを取得する安直な方法


アプリ起動時に取得しなおして、グローバルで参照可能にするほうが綺麗かもしれない
CloudWatchのSNS通知をまとめてみる

以下の図のように複数AWSアカウントの複数リージョンでCloudWatchのアラームを利用している。
何も考えずに各環境でSNSを設定してたら、サブスクライブやメールアドレス変更が大変になってしまったのでまとめられないか考えてみた。

![snsバラバラ (1).png](https://qiita-image-store.s3.amazonaws.com/0/16768/eb9fae21-0885-32be-9f36-0c53f108fd43.png)

# AWSアカウント間でSNSを共通に利用する

## 別アカウントのSNSを利用する

![別アカウントのSNSTopic利用 (1).png](https://qiita-image-store.s3.amazonaws.com/0/16768/1b512165-e35e-1e2a-0da8-5926b34c0dd8.png)

上の図のように別アカウントで作成されたSNS アプリを利用することでがきる。
Management ConsoleだとSNS Topicを作成してTopic Policy編集でPublish Messagesを許可するユーザをAWSユーザにして利用したいAWSアカウントのIDを指定する感じでいける。

ただし、CloudWatchの利用では以下のことに注意する必要がある。

* 同じリージョンのSNS Topicを作成する必要がある。
* 別アカウントのSNS Topicを指定する場合はManagement Consoleからはできない(aws cliなどでは可能)。

## 別アカウントにSubscriptionだけ作成する

![別アカウントにSubscription作成 (2).png](https://qiita-image-store.s3.amazonaws.com/0/16768/260a6e83-f2be-1b2f-86c1-c20d7198cc5d.png)

上の図のようにSNSのSubscriptionだけ別アカウントに作成できる。
Management ConsoleだとSNS Topicを作成してTopic Policy編集で利用するAWSアカウントIDに対してsubscribeを許可し、許可したアカウントでSubscriptionを作成する感じでいける。

同じアカウントにSubscriptionの設定はまとめられる。
ただし、SubscriptionはTopic毎に作成する必要があるため、あるアカウントのTopicと別のアカウントのTopicに対するSubscriptionの2つになる。

# リージョン間でSNS通知をまとめる
## SQSでまとめる

[AWS - SNSから他のアカウントのSQSへメッセージを送るのをやってみる - Qii](http://qiita.com/mechamogera/items/838550241430f7d9b477)参照
ただし、SQSから取り出して通知するシステムがいりエコじゃない感じ。

## Lambdaでまとめる

![SNSとlambda.png](https://qiita-image-store.s3.amazonaws.com/0/16768/d54ea2ef-058b-a966-e3fa-eaf4fb2fa2cc.png)

上の図のようにSNSから別のRegionのlambda Functionが利用できるので以下のようなFunctionで通知をまとめる。

```js
console.log('Loading function');

var AWS = require ('aws-sdk')

exports.handler = function(event, context) {
    console.log(JSON.stringify(event, null, 2));
    console.log('From SNS:', event.Records[0]);
    
    var sns = new AWS.SNS({region: 'Region指定'});
    var params = {
        TopicArn: 'SNS Topic ARN指定',
        Subject: event.Records[0].Sns.Subject,
        Message: event.Records[0].Sns.Message
    };
    sns.publish(params, function(err, data) {
       if (err) console.log(err, err.stack);
       else console.log(data);
    });
    
    context.succeed();
};
```
Swift1.2でクラス名が取得できなくなった


##Swift1.1までのやりかた

私はクラス名を取得するときの方法としてこれまでは↓のようにやっていました。

```swift
func ClassName (object: Any) -> String {
    let className = _stdlib_demangleName(_stdlib_getTypeName(object))
    if let range = className.rangeOfString(".") {
        return className.substringFromIndex(range.endIndex)
    }
    return className
}
```

```NSStringFromClass()``` を利用するという方法もあるのですが、enumやstructでも利用したかったので↑のように書いていました。


参考：[Swiftでクラス名を取得するメソッドを書いてみた](http://qiita.com/morizotter/items/9739d789d69924fd1897)


##Swift1.2からのやりかた

という経緯から```_stdlib_demangleName(_stdlib_getTypeName(object))```を利用していましたが、1.2から```_stdlib_getTypeName```が使えなくなったようで、コンパイルエラーとなってしまいます。
そこで、↓のように書きなおしたら問題なく動作するようになりました。

```swift
func ClassName (object: Any) -> String {
    let className = _stdlib_getDemangledTypeName(object)
    if let range = className.rangeOfString(".") {
        return className.substringFromIndex(range.endIndex)
    }
    return className
}
```

具体的にはこれまで

```swift
_stdlib_demangleName(_stdlib_getTypeName(object))
```

としていた部分を

```swift
_stdlib_getDemangledTypeName(object)
```

と書き直すことでコンパイルは通ります。

Playgroundで試したところ、期待通りの挙動だったので問題ないかと思われます。

enumやstructでも動作しました。
Fessを使って色々な検索をしてみた

# はじめに

Fessという全文検索サーバを使って色々な検索を試してみました。
公式サイトはこちら
http://fess.codelibs.org/ja/
環境構築方法はこちら
http://fess.codelibs.org/ja/articles/article-1.html
# 実践
ここではFessを使った検索を色々試したみたいと思います。例としてQiita http://qiita.com/ を最大アクセス数1000で検索しています。

## 1.AND検索

####検索形式
>検索語１ AND 検索語2`

####意味
AND検索は検索語をスペースで区切った時と同じ結果となります。複数の検索語がすべて含まれるドキュメントを検索します。
####用例
>java AND eclipse

javaとeclipseが含まれるドキュメントを検索。検索件数10件｡
![Screenshot from 2015-05-20 16:17:55.png](https://qiita-image-store.s3.amazonaws.com/0/69140/0bf869d0-8ecb-e5a4-a0fe-842d927ee188.png)

## 2.OR検索

####検索形式
>検索語1 OR 検索語2

####意味
検索語のどれかが含まれるドキュメントを検索します。検索語１が含まれていなくても検索語2が含まれていれば検索対象となります。逆もまた然りです。
####用例
>php OR perl

phpとperlのいずれかが含まれるドキュメントを検索。検索件数211件。
![Screenshot from 2015-05-20 16:53:17.png](https://qiita-image-store.s3.amazonaws.com/0/69140/22970b0c-cfb5-5bee-914b-eb74c16152bc.png)

## 3.NOT検索

####検索形式
>検索語1 NOT 検索語2

####意味
NOTの後に指定した検索語を含まないドキュメントを検索します。検索語1が含まれていて検索語2が含まれていないドキュメントが検索されます。
####用例
>java NOT js

javaを含むがjsを含まないドキュメントを検索。検索件数601件。
![Screenshot from 2015-05-20 16:53:38.png](https://qiita-image-store.s3.amazonaws.com/0/69140/b931f1de-f053-fc4e-b05b-8aa7ea79ea83.png)

## 4.ブースト検索

####検索形式
>検索語1^ブースト値 検索語2

####意味
特定の検索語をブースト値をつけることで優先して検索させます。検索語1の方が検索語2より優先されて表示されます。
####用例
>php^5 html

phpの方がhtmlより優先して検索されます。検索件数58件。(検索表示の順番が変わるだけなので、ブースト値をいくつにしても検索件数は変わらず58件になります)
![Screenshot from 2015-05-20 16:54:17.png](https://qiita-image-store.s3.amazonaws.com/0/69140/ac7be75f-6dcf-e427-9251-ad96f855a906.png)


## まとめ
検索方法によって色々な結果が期待できます。目的に沿った検索をすることで作業が捗ります。