OmniAICreator/Qiita-1.07M huggingface dataset:
ModSecurityでPOSTのサイズ制限をする


## ModSecurityとは

[ModSecurity](https://www.modsecurity.org/documentation.html)はオープンソースのWeb Application Firewall(WAF）モジュール。
攻撃を検知するための基本的なルールセット、[Core Rule Set (CRS)](https://github.com/SpiderLabs/owasp-modsecurity-crs)が準備されている。

## インストール

CentOS6.5を想定

### EPELリポジトリの追加

```
$ rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
```

EPELリポジトリを普段は使わないように`/etc/yum.repos.d/epel.repo`の設定を変更

```
[epel]
.
.
.
enabled=0
```

### ModSecurityのインストール

mod_securityとmod_security_crsをインストール

```
$ yum --enablerepo=epel install mod_security mod_security_crs
```

| パッケージ名 | 概要 |
| :--------: | --- |
| mod_security | ModSecurity本体 |
| mod_security_crs | ModSecurityのルールセット |


インストール完了後、`service httpd restart`を実行することでModSecurityが有効になる

### ModSecurityの確認

ModSecurityが正常に動作していることを確認する。
既存コンテンツの後ろに`?union+select`をつけてアクセスをする。

http://example.jp/index.html?union+select
※URLについてはそれぞれの既存コンテンツを指定する

403 Forbiddenのエラーが返されればOK
また、`/var/log/httpd/modsec_audit.log`にログが吐かれていることを確認する

## 設定

インストールすると`/etc/httpd/conf.d/mod_security.conf`と`/etc/httpd/modsecirty.d`が作成される。

* `/etc/httpd/conf.d/mod_security.conf`にはModSecurityの設定が書かれている
* `/etc/httpd/modsecirty.d`にはルールセットが格納されている
  * mod_security.confから読み込まれている  
	初期状態は全て読み込むようになっている

### パラメータ


| パラメータ | 内容 |
| :------: | ---- |
| SecRequestBodyLimit | ファイルアップロードのリクエストボディ上限値 |
| SecRequestBodyNoFilesLimit | ファイルアップロード以外のリクエストボディの上限値（Content-Typeが`application/x-www-form-urlencoded`の場合にのみ有効）|


* `SecRequestBodyLimit`の値を2097152(=2MB)に変更する
* `SecRequestBodyNoFilesLimit`を51200(=50KB)に変更する

変更後に再度、`service httpd restart`を叩く。

### 設定の確認

設定がちゃんと反映されている場合、ファイルサイズが上限値以上（今回でいうと2MB以上）でアップロードを試みると、以下のレスポンスが返る

* ステータスコード413が返される
* Request Entity Too Largeページが表示される
初めてのテストコード


> javascript, node.js などにおいてテストコードを自分で書いたことがなかった人が学習した内容をまとめます。

「javascript テスト」と調べるとjasmine, JUnit, karma, ... 等々たくさん出てきてなにからすれば、どういう手順で導入する目的が見えるのかわかりづらいですね。

テストコードはできるだけ単純に coffee で書きたく、またテスト本体も coffee で書き始めるのにとっつきやすいものがあればよいのですが。

僕が調べた中で一番シンプルに導入できて、実際に使いたくなる手軽さがある手法は、gulp というビルドの自動化ツールから mocha を使うことです。

### まず、テストコードを書きます。

```sampleSpec.coffee
require 'should'

foo = require('../src/sample')

describe 'foo()', ->
    it 'は引数ありなら正負を逆にした値を返す', ->
        foo(9).should.equal -9
        foo(-3).should.equal 3
    it 'は0なら0を返す', ->
        foo(0).should.equal 0
    it 'は引数なしなら0を返す', ->
        foo().should.equal 0
```

1. 判定するために should を使います。Object.prototype を拡張して判定文をかけるようにしてくれていますね。
1. Spec するモジュールを require して持ってきます。こんかいは foo
1. describe -> it -> [ASSERTION] の構造で SPEC を書きます。

### 実装


さて、これを実現できそうなモジュールを作ります。失敗してもいいです。

```sample.coffee
foo = (num = 0) -> return num * -1
module.exports = foo
```

### 環境構築

さて、spec でテストしたいのですが以下のものが必要になります。

```sh
$ npm init -y
$ npm i -D coffee-script gulp gulp-mocha should
```

mocha ってのは describe や it の構造化やテストの成否を拾ってくれるライブラリだと思います。

gulp 書きます。

```gulpfile.coffee
gulp = require "gulp"
mocha = require "glup-mocha"

gulp.task "test", () ->
  gulp.src ['spec/*.coffee']
    .pipe mocha {reporter: 'spec'}
```

これで spec 内の spec が動きます。.coffee であっても動いてくれます。
やってみましょう。

```sh
$ gulp test
[15:11:15] Requiring external module coffee-script/register
[15:11:16] Using gulpfile ~/Works/0_/mocccha/gulpfile.coffee
[15:11:16] Starting 'test'...


  foo()
    ✓ は引数ありなら正負を逆にした値を返す
    ✓ は0なら0を返す
    ✓ は引数なしなら0を返す


  3 passing (12ms)

[15:11:16] Finished 'test' after 129 ms

```

できました

まとめ
---

* まずshould 拡張して、引っ張ってきたテストとなるモジュールを使って、describe>it>[ASSERTION] 構成でテストを書いてしまう。
* 適切なモジュールを作る。
* 環境を作って、gulpfile.coffee を書く。

簡単でよかった。
MacOSX でTCP LISTENしているプロセスとポート番号を知るには

## 実現したいこと

```
$ sudo netstat -ntpl
```

Linuxで上記のようにnetstatコマンドを利用して実現していることをMacOSX Mavericksでも実現する

## MacOSX Mavericksでnetstatコマンドを利用してListenしているポートを調べるには、-l ではなく -L を利用する。




 lsofコマンドを利用する

```
$ sudo lsof -nP -iTCP | grep LISTEN
```

* MacOSX Mavericksに標準で導入されているnetstatコマンドは、Linuxに標準で導入されているnetstatコマンドとは、若干仕様が違うため lsofコマンドを利用します。

```
$ netstat -h
netstat: illegal option -- h
Usage:	netstat [-AaLlnW] [-f address_family | -p protocol]
	netstat [-gilns] [-f address_family]
	netstat -i | -I interface [-w wait] [-abdgRt]
	netstat -s [-s] [-f address_family | -p protocol] [-w wait]
	netstat -i | -I interface -s [-f address_family | -p protocol]
	netstat -m [-m]
	netstat -r [-Aaln] [-f address_family]
	netstat -rs [-s]

$
```
```
$ man netstat

〜 snip 〜

     -L    Show the size of the various listen queues.  The first count shows the number of unaccepted connections.  The second count shows the amount of unaccepted incomplete con-
           nections.  The third count is the maximum number of queued connections.

     -l    Print full IPv6 address.

〜 snip 〜
```
JenkinsのBuild Flowで連続失敗時に失敗にしてみる

JenkinsのBuild Flowから実行したジョブが連続で失敗した時に結果を失敗にしてみたのでメモしておく。

以下の例のようにジョブが失敗していて3連続まで達していない場合はUNSTABLEにし、3連続失敗している場合はFAILUREにしている。

| ビルド番号 | パラメータ | 結果 |
|:-----------|:------------|:------------|
| #10 | PARAM=hoge | 3連続失敗しているのでFAILUREにする |
| #9  | PARAM=a | - |
| #8  | PARAM=hoge | 2連続失敗しているのでUNSTABLEにする |
| #7  | PARAM=b | - |
| #6  | PARAM=hoge | 1回失敗しているのでUNSTABLEにする |
| #5  | PARAM=hoge | SUCCESS |

Build Flowのコードは以下のようにしている。

```groovy
import static hudson.model.Result.UNSTABLE

FAIL_NUM = 3 // この数だけ連続して失敗していたら失敗とする
MAX_LOG = 100 // この数だけ過去の結果を調べる

def res= null
// ジョブ実行(失敗無視)
ignore(FAILURE) {
  res = build([:], "sub-job")
}

// ジョブが失敗だった場合
if (res.result.name != "SUCCESS") {
  def is_failure = false
  def crr_build = build.getPreviousBuild()
  def count = 1;

  // 過去の結果を調査
  for(i in 0..<MAX_LOG) {
    if (!crr_build) {
      break
    }
    
    try {
      // パラメータが一致する結果だけ調べる
      def resolver = crr_build.buildVariableResolver
      if (resolver.resolve("PARAM") != params["PARAM"]) {
        continue
      }
    
      // 成功していたか調べる
      if (crr_build.result.name == "SUCCESS") {
        println("${crr_build.number} ${crr_build.result.name}")
        break
      }
    
      // 過去の結果について出力
      println("#${crr_build.number} ${crr_build.result.name}")
      crr_build.getActions(hudson.model.ParametersAction).parameters.each {
        println "parameter ${it.name}:${it.dump()}"
      }
    
      // 失敗数をカウント
      count += 1
      if (count >= FAIL_NUM) {
        is_failure = true
        break 
      }
    } finally {
      crr_build = crr_build.getPreviousBuild() 
    }
  }
  
  // 結果の変更
  if (is_failure) {
    flowRun.state.result = FAILURE
  } else {
    flowRun.state.result = UNSTABLE
  }
}
```

参照サイト

* [How to retrieve Jenkins build parameters using the Groovy API? - Stack Overflow](http://stackoverflow.com/questions/10882515/how-to-retrieve-jenkins-build-parameters-using-the-groovy-api)
* [Parameterized System Groovy script - Jenkins - Jenkins Wik](https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+System+Groovy+script)
【RSpec】Validatorのテストを限界まで手抜きする

# Validatorのテストを限界まで手抜きする
## TL;DR
* [**rspec-validator_spec_helper**][rspec-validator_spec_helper]つかう
* テストをパラメタライズドテストに落としこむ
* [**rspec-parameterized**][rspec-parameterized]つかう
* しあわせ

## RSpec::ValidatorHelper
[**rspec-validator_spec_helper**][rspec-validator_spec_helper]というgemがある．
これが提供する`RSpec::ValidatorSpecHelper`はvalidatorのテストを簡単化するためのものである．
このクラスは以下の機能を提供する．

* validate対象になるダミーのクラスの提供
* ダミークラスの`validates`，`validates_with`の設定

> ```ruby
> describe NotOverlappedValidator, type: :validator do
>   let(:attribute_names) { [:begin_at, :end_at] }
>   let(:begin_at) { Time.parse("2014-12-24T12:00:00+09:00") }
> 
>   describe '#validate' do
>     context 'when end_at is overlapped' do
>       let(:end_at) { Time.parse("2014-12-24T09:00:00+09:00") }
>       it { is_expected.to_not be_valid }
>     end
> 
>     context 'when end_at is not overlapped' do
>       let(:end_at) { Time.parse("2014-12-24T19:00:00+09:00") }
>       it { is_expected.to be_valid }
>     end
>   end
> end
> ```
> 
> <cite>[【Rails】まだValidatorのテストで消耗してるの？ - Qiita][qiita]</cite>


## さらなる単純化
`RSpec::ValidatorSpecHelper`はダミークラスを提供するのがメインだが，その副作用で**テストコードをパラメタライズドテストに落としやすくなる**というものがある．

> Parameterized Test とは、まさに似たようなテストメソッドをテストデータだけ変えて複数件実行することができる手段で、多くの場合テスティングフレームワークの拡張機能として提供されています。
>
> [これであなたもテスト駆動開発マスター！？和田卓人さんがテスト駆動開発問題を解答コード使いながら解説します～現在時刻が関わるテストから、テスト容易性設計を学ぶ #tdd｜CodeIQ MAGAZINE][codeiq]

Validatorは**何かしらの入力に対してtrue/falseを出力するだけで副作用がない**ものがほとんどなので，そもそもパラメタライズドテストにしやすいという特徴がある．
`RSpec::ValidatorSpecHelper`がテストコードを規約で縛る役割を果たすので，よりパラメタライズドテスト化しやすくなる．

そこで，先ほどのサンプルコードを[rspec-parameterized][rspec-parameterized]を利用してリファクタリングしてみる．

```ruby
describe NotOverlappedValidator, type: :validator do
  let(:attribute_names) { [:begin_at, :end_at] }

  where(:begin_at_str, :end_at_str, :be_valid_or_invalid) do
    [
      ["2014-12-24T12:00:00+09:00", "2014-12-24T09:00:00+09:00", be_invalid],
      ["2014-12-24T12:00:00+09:00", "2014-12-24T19:00:00+09:00", be_valid]
    ]
  end

  with_them do
    let(:begin_at) { Time.parse(begin_at_str) }
    let(:end_at) { Time.parse(end_at_str) }
    it { is_expected.to be_valid_or_invalid }
  end
end
```

このサンプルはパラメータが長いのでちょっとだけ見栄えが悪いが，結構スッキリしたと思う．
これはテストケースが増えれば増えるほど効果がある．
逆に言うと，**テストケースを増やしてもテストの複雑さには全く影響を及ぼさない**．
また，`ActiveModel::EachValidator`継承クラスのテストにはより効果が高いような気がしなくもない．

# Conclusion
パラメタライズドテストたのしい

# References
* [**izumin5210/rspec-validator_spec_helper**][rspec-validator_spec_helper]
* [**tomykaira/rspec-parameterized**][rspec-parameterized]
* [【Rails】まだValidatorのテストで消耗してるの？ - Qiita][qiita]
* [これであなたもテスト駆動開発マスター！？和田卓人さんがテスト駆動開発問題を解答コード使いながら解説します～現在時刻が関わるテストから、テスト容易性設計を学ぶ #tdd｜CodeIQ MAGAZINE][codeiq]

[rspec-validator_spec_helper]: https://github.com/izumin5210/rspec-validator_spec_helper
[rspec-parameterized]: https://github.com/tomykaira/rspec-parameterized
[qiita]: http://qiita.com/izumin5210/items/a7036093c25c42f2298d
[codeiq]: https://codeiq.jp/magazine/2013/11/1475/
iOSアプリで、Google AnalyticsのABテスト機能を使う その1


[今開発中のPlayer!](https://itunes.apple.com/jp/app/id897872395)というiOSアプリでABテストを行うために、各種サービスを検討したり自前で何とかしようか迷いつつ、Google Analyticsを利用することにしました。

- Google Analytics以外はけっこうお高い
- [mattt/SkyLab](https://github.com/mattt/SkyLab) + 仕組み作るのはちょっと手間かかりそう
- 若干柔軟性に欠ける感はあるけど、Google Analyticsがモバイルアプリにも対応したABテスト環境を用意してくれている

[「iOSアプリで、Google AnalyticsのABテスト機能を使う その2」はこちら](http://qiita.com/mono0926/items/a45f2ba268bca964ef9b)

## 導入準備

### Google Analytics導入

[Google アナリティクス公式サイト - ウェブ解析とレポート機能 – Google アナリティクス](https://www.google.com/intl/ja_jp/analytics/)でアカウントやビューを作りましょう。

アプリへのSDK導入は、[CocoaPods対応](https://github.com/CocoaPods/Specs/tree/master/Specs/GoogleAnalytics-iOS-SDK)なので、
`pod 'GoogleAnalytics-iOS-SDK'`でインストールが楽です。

### Google Tag Managerアカウント作成

Google Tag Managerは、ざっくり言うと、タグの一括管理だったりその柔軟・動的な変更を可能とするシステムです。

詳しくはこちら: [タグの一括管理ができる！Googleタグマネージャの使い方 | タグマネージャ | ひびの備忘録](http://www.h-nanae.com/analytics/tagmanager/entry-82.html)

Google Analyticsのモバイルアプリ用ABテスト機能(ウェブテスト機能)を使うにあたり、この設定が必要のようです。

[Google Tag Manager official website](https://www.google.com/tagmanager/) でアカウント・Containerを作りましょう(　´･‿･｀)

### Google Tag ManagerとGoogle Analyticsの紐付け

Tag ManagerContainerの設定のここからGoogle Analyticsへの紐付けを行います。

![Screen_Shot_2015-06-23_at_16_30_50.png](https://qiita-image-store.s3.amazonaws.com/0/19398/352c23f1-009e-a3bf-7db2-08ed5cc8a6f0.png "Screen_Shot_2015-06-23_at_16_30_50.png")


こうなったらOKです。

![Screen_Shot_2015-06-23_at_16_31_40.png](https://qiita-image-store.s3.amazonaws.com/0/19398/1055c933-6576-86c6-22ee-78be18c91668.png "Screen_Shot_2015-06-23_at_16_31_40.png")


そのあと、ごにょごにょすると、Google Analyticsのウェブテストの項目でこんな感じで、Originalとテスト群との比較が見られるようになります。

**詳しいやり方は、[その2へ続きます。](http://qiita.com/mono0926/items/a45f2ba268bca964ef9b)**

![Screen Shot 2015-06-23 at 16.35.59.png](https://qiita-image-store.s3.amazonaws.com/0/19398/7a3dcdec-d33f-d1e5-c1f4-c382c9a5b0be.png "Screen Shot 2015-06-23 at 16.35.59.png")


![Screen Shot 2015-06-23 at 16.37.05.png](https://qiita-image-store.s3.amazonaws.com/0/19398/4d4fd8e4-e84b-2200-dd28-a68b2e559833.png "Screen Shot 2015-06-23 at 16.37.05.png")




## 注意事項

最近、Tag Managerがリニューアルして用語が変わりました。
- 「ルール」→「トリガー」
- 「マクロ」→「変数」


[タグマネージャの新しい管理画面 - Tag Manager ヘルプ](https://support.google.com/tagmanager/answer/4605576)




## リンク集

- [iOS v3 - Getting Started   |   Google Tag Manager for iOS   |   Google Developers](https://developers.google.com/tag-manager/ios/v3/)
	- iOSアプリでのTag Manager導入方法の公式ドキュメント
- [Content Experiments for Mobile Apps - Tag Manager Help](https://support.google.com/tagmanager/answer/6003007?hl=en)
	- Google AnalyticsとTag Managerの紐付けについて
- [ウェブテストのメリット - アナリティクス ヘルプ](https://support.google.com/analytics/answer/1745147?hl=ja&ref_topic=1745207)
	- ウェブテストについての説明でけっこう勉強になる
- [Google Tag Manager Fundamentals: Course Schedule](https://analyticsacademy.withgoogle.com/course05)
	- Google Tag Managerについてはこちらで詳しく学べます
【UE4】【Unity】ポータル作りのエッセンス

#これなに？
↓こんなやつのメイキングです。
UE4
https://www.youtube.com/watch?v=NJi340eIPnc&feature=youtu.be
Unity
https://www.youtube.com/watch?v=FHt0BXXx4fI&feature=youtu.be

ポイントとしては
1. 触れるとワープする
2. ワープ先の風景が写りこんでいる
3. ワープ時、写りこんだ風景がそのままワープ先の画面とつながる（画面の連続性）

この記事では詳細な手順には触れず、仕組みだけ説明します。
なんとなく中級者向きという感じでしょうか。

#仕組み
ポータルには以下の特徴的な情報が含まれます。
* 移動先のポータルへの参照
* ポータル自身の周辺の風景を写すカメラ
* ポータルを表示するためのシーンオブジェクト
* 当たり判定

### 移動先
触れたときに移動する先のポータルです。
移動処理については少し工夫が必要で、滑らかに移動させるためには
object.setpos( targetPortal.pos ) （擬似コード）
のようなものでは不足です。
**移動前のポータルからの相対的な姿勢が、移動後のポータルからの相対的な姿勢と一致するように移動処理を行う必要があります。**

### カメラ
カメラについては、UnityであればTargetTextureを設定したカメラ、UE4であればSceneCapture2D(Component)ということになります。
ここでキャプチャーして得られた画像を、「移動先」のほうのオブジェクトに適用します。
このカメラの姿勢制御がもっとも特殊な部分です。
**このカメラのポータルからの相対的な姿勢が、
プレイヤーカメラの移動先ポータルからの相対的な姿勢と一致するように制御します。
また、視野(fov, aspect)がプレイヤーカメラと一致するようにします。**
なんとなく図にするとこんな感じです
（今ひとつよく分からない図ですが作ってしまったので載せておきます）。
![CIKmMIiUsAA8Yz_.png](https://qiita-image-store.s3.amazonaws.com/0/61553/f7b8b0f0-e206-5552-beb1-799886cc579d.png)
また、このカメラには、**このポータル自身が写らないようにする必要があります。**
UnityであればカメラのCullingMask、UE4であればHideActorComponentsが使えます。

### シーンオブジェクト
**移動先のカメラがキャプチャーしたものを受け取って表示します。**
実体としては見えれば何でもよいのですが、
**受け取ったテクスチャからスクリーン座標でサンプリングするようなシェーダーを適用することが必要です。**
つまり、このオブジェクトが画面全体を覆った時に、移動先のカメラに写っているものと表示画面が一致するようにします。

### 当たり判定
領域については適当に設定すればよいですが、
「通り抜けられる」感じにするには、ブロックしないような設定にすべきです。
UnityであればCollisionにTriggerチェックを入れる、UE4であればOverlapALlに設定するなどです。
また、移動先のポータルに触れることで再度戻されないよう何らかの処置が必要です。
動画のプロジェクトにおいては、単に出口のポータルを一定時間無効にしています。


こういうPrefabなりBlueprintなりを作って二つ配置し、互いに行き先として設定すればできあがりです。
移動するモノの側ではなくポータルの方に「触れたモノを移動させる」という機能を持たせることで、キャラクターであろうと弾であろうと転移させられるようになります。


# まとめ
ポータルの作り方についてのエッセンスをざっくりと紹介しました。
RPM が管理しているファイルを確認する方法

#１．Linux上のファイルが管理されているRPMを確認する方法

##例） /etc/redhat-release

*確認方法*
>$ rpm -qf /etc/redhat-release
>centos-release-6-4.el6.centos.10.x86_64

#２．.rpm が管理しているファイルを確認する方法

##例） centos-release-6-4.el6.centos.10.x86_64

*確認方法*
> $ rpm -ql centos-release-6-4.el6.centos.10.x86_64
>/etc/centos-release
>/etc/issue
>/etc/issue.net
>/etc/pki/rpm-gpg
>/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
>/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Debug-6
>/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Security-6
>/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Testing-6
>/etc/redhat-release
>/etc/rpm/macros.dist
>/etc/system-release
>/etc/system-release-cpe
>/etc/yum.repos.d/CentOS-Base.repo
>/etc/yum.repos.d/CentOS-Debuginfo.repo
>/etc/yum.repos.d/CentOS-Media.repo
>/etc/yum.repos.d/CentOS-Vault.repo
>/usr/share/doc/centos-release-6
>/usr/share/doc/centos-release-6/EULA
>/usr/share/doc/centos-release-6/GPL
>/usr/share/doc/redhat-release
とりあえずInferを使ってみた。


# 何？

* 静的コード解析ツール
* C / Java / Objective-C のコードを解析可能 
* C++は解析できないっぽい


# インストール

バイナリ落としてくるのが楽。Macだと　 https://github.com/facebook/infer/releases/download/v0.1.1/infer-osx-v0.1.1.tar.xz からv0.1.1を落としてこれる


落としてきて解答したら
``infer/infer/bin`` にPATHを通しましょう。


# 解析

iOSということで、ずごく昔に作った
https://github.com/sassy/iOSFirstTwitterApp
を解析かけてみた。


```bash:
$ git clone git@github.com:sassy/iOSFirstTwitterApp.git
$ cd mac:iOSFirstTwitterApp
$ infer -- xcodebuild -target TwitterViewer  -configuration Debug -sdk iphonesimulator
```

そしたら、

```shell-session:
Starting analysis (Infer version v0.1.1)
Analysis done

5 files analyzed


No issues found

```

何も見つからなかった。
 ```infer-out```　というディレクトリができていて、
その中のbugs.txtに結果が記録されている。

実際は
http://fbinfer.com/docs/hello-world.html#hello-world-ios
にあるみたいにいろいろ指摘がかかれるっぽい。


# 詳しくは

http://fbinfer.com/docs/

を見ましょう。

何かあったら追記します。
Redmineでアップロードできるファイルサイズの最大値を増やす


アップロードできる添付ファイルの最大値は、下の値を変更すれば増やすことができる。

```
管理アカウントログイン→管理→設定→添付ファイルサイズの上限
```

ただし、nginxを使用している場合はこれだけだと `413 (Request Entity Too Large)` が発生してしまう。

# nginxのclient_max_body_sizeを変更する

`/etc/nginx/nginx.conf` に設定を追記する

```
server {
    listen 80;
    server_name redmine.example.com;
    client_max_body_size 50M;  # ←追加
    
    # その他の設定など...
}
```

これを記述することで、nginx側の制限値が変更できる。

# Apacheを利用している場合

恐らく何かしらの設定が必要そうな気がします。。
Meteor Event Submit でページがリフレッシュしてしまう時

# Event Submitでページがリフレッシュ？

meteorでフォームを作成してsubmit用のイベントを設定しているにもかかわらず、ページがリフレッシュしてしますときの対応策。

```js
'submit form': function(event){
    console.log("Form submitted");
    console.log(event.type);
}
```
上記のコードを書いたとき、コンソールに何も表示されずに、ただページがリフレッシュしてGETリクエストっぽくなった。。そんな時は、以下のように`event.preventDefault()`を加えてやるとリフレッシュしません。

```js
'submit form': function(event){
    event.preventDefault();
    console.log("Form submitted");
    console.log(event.type);
}
```
Rails tutorial - Guardをインストールできない

またWindows依存の箇所でうまく動作しなくなった。

[チュートリアル](http://railstutorial.jp/chapters/static-pages?version=4.0#sec-guard)どおりにやってもGuardをインストールできない。
厳密にいうと、以下の様なエラーメッセージが表示される。

```
C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/win32console-1.3.2-x86-mingw32/lib/Win32/Console.rb:12:in `require': cannot load such file -- 2.0/Console_ext (LoadError)
```

調べてみるとどうもWin32consoleというモジュールはもうインストールする必要がないらしい。
- [rspec error (cannot load such file)](http://stackoverflow.com/questions/28503579/rspec-error-cannot-load-such-file)

でuninstallの方法がわからない。。
適当にためしたら以下でいけた。

1. bundleのGemfileからwin32consoleをコメントアウト。
1. gem uninstall win32consoleでアンインストール。
1. budle install --without productionからやり直し。

これでもwin32consoleは自動でインストールされちゃうんだけど、今度はGuard起動時のエラー表示は無くなった。
不思議すぎるけどまあいい。
パイプライン策定ガイドライン [WIP]

# About
パイプラインのデザインに関するガイドライン集。
随時追記＆編集していくため[WIP]のままツッコミ待ちも含めて公開状態。

# パイプラインの目的
基本的には自動化、合わせてデータの例外をなくす。

決められたルールにもとづいてデータが作成されることで、
**必要とするデータの｛特定/判別/生成｝が可能になっている状態にする。**
ルールが守られることで新たに追加されるデータも等しく処理できる。
※自動化要望は後から発生することも多い、その時どこまで徹底するかの判断も

* XXなデータをXXしたい
* XXでXXがXXならXXにする

## 最初にやること
* **使用するツールを決定する**
    * DCCツールやゲームエンジンなど必要なツール全て
    * ツールのバージョン（サービスパックの指定など）
    * ツールの言語（英語に統一がベター？）
    * ツールのインストールパスを決定する（基本統一）
    * ツールバージョンの更新ルールを決定する
* **データ構造と命名規則を決定する**
    * データ格納パスを決定する（基本統一）
    * ファイル名、フォルダ名、ディレクトリ構造
    * データ名、データ構造（オブジェクト名含む）
* **3DCGツール特有のルールを決定する**
    * Y-Upにするか？ Z-Upにするか？
    * Ascii/Binary？圧縮有無
    * 単位はcm?meter?inch?
    * 可能な限りスクリプトで設定を毎回チェックすること！
* **CGツール特有のルールを決定する**
    * データ入出力フォーマット（FBXなど）
* **以上の決定事項が外部協力会社でも守られるようにする**

## ファイル＆ディレクトリ命名規則のポイント
* ファイル名だけでもアセットをユニークに識別出来るようにする  
* ファイル名から格納先パスが構築できるようにする  
　※特に名前の省略するしないは基本統一する。  
　　仮にフォルダ名は非省略＋ファイル名は省略とした場合、  
　　ファイルIDをフォルダ名にも含めるなどして機械的にフォルダが特定できること  
* 迷ったら自由桁はやめる。固定桁のIDに落としこむ。  
 可変となる非省略形を採用してもアセット量が多い場合、識別力し易さは期待できない。
* 全てのアセットが同じ規則に出来る方がいい。（キャラ、背景、エフェクト...etc）
* 今良くても「何でもいい」は避ける。ルールを決めて自動的に名前が決まるようにしてみる。
* ゲームの場合はバリエーションがよく発生する。（テクスチャ替え、モデル替えモーション共有） 
  その場合もバリエーションであること、メイン素材が特定できる名称にすること。
　※CH01_V1, CH01_V2 や CH_01_01, CH_01_02など。
　　複数同時に使用される場合、末尾が 01などの連番にすると複製時の名称と衝突しやすい。

## 3DCGデータ構造のポイント
* **同名オブジェクトは存在しないようにする**
* **ジョイント、メッシュ、リグの区別がつくようにする**  
    * ジョイントにマテリアルが設定されているか判定できること
    * メッシュにマテリアルが設定されているか判定できること
    * メッシュ用ポリゴンなのか、スケルトン用のポリゴンか判定できること

## DCCツールのバージョンを検討する
### 予想に反してバージョンを変えなければならないケースは無いか？
* 途中から使用したくなったプラグインが対応していない
* 既に新規購入ができないバージョンで、社内外のメンバーが増えてライセンスが不足する
* 取引先の要求でバージョンを上げる必要になった

## スクリプト作成で考えておくべき点
### 共通事項
* **そのスクリプトは個人で使うものか？チームで使うものか？**
    * **複数のプロジェクトが混在しているか？**  
        プロジェクトによっては使わない？見えなくていい？
    * ** 社外や異なる環境にスクリプトを提供するか？**
        * ファイル名やメモリ上のデータが重複しないようにする  
            ファイル名の先頭やフォルダ名に会社名を入れるなど
        * 出来る限りリソースをまとめて削除しやすくする  
            きれいにアンインストールできるほうがいい！
        * 社外の人に見えていけないものを隠ぺいする  
            ソースコードの中身やバージョン管理ツールのコメント  
            社内で働く社外の人はいないか？  
            ファイル名などにプロジェクト名がはいっていないか？
    * **開発用リソースとリリース用リソースが区別しやすいか？**  
        開発にのみ必要か？実行時に自動生成するのか？  
        区別がしやすいとリリース作業が楽。  
* **ローカライズの仕組みが事前に検討されているか？**
    * 使用しているDCCツールにGUIをローカライズする仕組みはあるのか？  
        ローカライズにはどのようなリソースを用意し、構造を維持しなければいけないか？
* **容易に配布できるか？利用者が常に最新のツールがを利用しているか？**
    * ファイルサーバーを全員で参照する？
    * SVNなどから自動で取得してくる？
    * インストーラーを作成する？
    * 勝手にツールがコピーして再配布されていないか？（古いバージョンが使われる！）

# 3dsMaxの注意点
* Mayaと違ってツールリソースへの参照パスはたくさん追加できない。  
    systemPath。additionalPath。PluginPath。
* MaxUIに使用できるアイコンはMax起動後に任意のパスからロードは出来ない。  
* Max起動後にMCRをロードする場合、作成済みMenuやToolBarがUnknownに
* 拡張メニュー用の画像はどのように用意したらいいのか？

#まとめ中
* パイプライン診断ツールがあったほうが良いかもしれない。
　正しく環境が構築されていて、ツールが機能しているかのチェック＆リポートツール。
　特に外部会社や追加人員の環境構築で問題があった場合に発覚と調査が遅れるため。
* Mayaなどが標準インストールパスにインストールされていないケース
* バージョン管理サーバーが分かれていて変更を双方向同期しないといけないケース
僕はこうやって画面設計書を作ってる（Webシステムにおける簡潔な画面設計書の例）

Webシステムを作る上で、画面設計書を作成する事は多々あると思うんだけど、みんなどうやってるんだろうか。
取り敢えず、僕はこんな感じで作ってるよってのを紹介したいと思います。
小規模のプロジェクトで、ドキュメントIDとかプロジェクトIDとか使わなくてもいいような、管理が複雑でないプロジェクトを想定しています。

ルールとしては以下を守ってます。

* 画面設計書には画面遷移図の情報を含めない。<br>画面設計書は単一の画面の設計を掲載すべきと考える。
* DBの操作、ビジネスロジック層に関する処理は画面設計書に記載しない。<br>別途アクション設計等に作成するべき。
* Excel方眼紙を使わない。（←重要）<br>詳しくは後述。

参考にしたのは、以下のサイト。
［画面設計］画面の構造は物理的・論理的に示す
http://itpro.nikkeibp.co.jp/article/COLUMN/20090108/322455/
IPA 「発注者ビューガイドラインの公開」
http://www.ipa.go.jp/sec/softwareengineering/reports/20080710_3.html

Qiitaは画像ファイルしか添付出来ないので、画像のキャプチャを貼っておく。
１ページ目
![WS000031.JPG](https://qiita-image-store.s3.amazonaws.com/0/55730/45931341-3984-fd09-db2c-399b10494446.jpeg)
２ページ目
![WS000033.JPG](https://qiita-image-store.s3.amazonaws.com/0/55730/d0e0eadf-14d2-6ebc-499d-32dc973251fb.jpeg)



* 部品の記述はどうするべきか？

以前はヘッダとかサイドバーは、暫定の画像を貼り付けていたのですが、これだと実装者によっては**全部の画面にヘッダやサイドバーのソースを実装しちゃったりする**ので、危険。明確に「別の設計書ですよー」と書いておかないと、実装者には伝わらなかったです。

* ExcelよりWord

Excel方眼紙の方式は、一見作りやすそうに見えるんですが、修正箇所の履歴を見る時に大変不便です。TortoiseSVNを使ってて物凄く実感します。
お客様に納品する際に印刷してお渡しする事は多々あると思うんですが、Excel方眼紙はこの点で不利です。**細かすぎて印刷したら読めない設計書が出来て、納品直前に慌ててドキュメント修正**なんて事にならないように注意しましょう。
設計書は、縦ページと横ページを組み合わせる時が多いです。縦に長い画面は縦ページに記載して、アクション一覧は横ページにする、なんて事もあります。Excelだと、シートを切り替えないとページ構成を変えられません。**複数シートを選択して、一気に印刷しようとしたら、印刷設定がデタラメになった**なんて事もありました。

Excel方眼紙を使うなら、繰り返し編集するような事が無く、印刷物にせず、ページのレイアウトを複雑にしないようなドキュメントで使うべきだと思います。
もちろん、表計算が必要な場合にはExcelを使った方が良いと思います。適材適所ですね。
Errno::EMFILE: Too many open files - getcwd に悩まされた時


Macのローカルで稀によく落ちるspecの原因調査の為に、csv絡みのrspecを走らせていたら、エラーが発生するようになってしまった。

```
An error occurred
  Errno::EMFILE: Too many open files - getcwd
  occurred at /foo/project_root/vendor/bundle/gems/rspec-core-2.99.2/lib/rspec/core/formatters/base_formatter.rb:208:in `expand_path'
```

Macのファイルディスクリプタの上限は、初期値では256しかないので、プロセスが取り扱うファイルが多くなるとエラーが発生してしまう。


```
% ulimit -n
256
```

その他の上限値も合わせて確認する場合は以下のコマンドでいける。

```
% launchctl limit
        cpu         unlimited      unlimited
        filesize    unlimited      unlimited
        data        unlimited      unlimited
        stack       8388608        67104768
        core        0              unlimited
        rss         unlimited      unlimited
        memlock     unlimited      unlimited
        maxproc     709            1064
        maxfiles    256            unlimited
```


## 解決方法


### limit -n で一時的に設定を変更する

```
% ulimit -n 1024
% ulimit -n
1024
```
javafx8での外部フォントの使用について

OSに関わりなく同じフォントで表示したい。
webフォントを使えば、

```
scene.getStylesheets().add("http://fonts.googleapis.com/css?family=Gafata");
exampleLabel.setText("Gafata example");
exampleLabel.setStyle("-fx-font-family: 'Gafata'; -fx-font-size: 24;");
```

設定が反映される。
しかし全く同じcssファイルをローカルに保存すると、

```
scene.getStylesheets().add("file:///C:/tmp/Gafata.css");
exampleLabel.setText("Gafata example");
exampleLabel.setStyle("-fx-font-family: 'Gafata'; -fx-font-size: 24;");
```

反映されない。
ログを見ると、

```
6 23, 2015 2:23:01 午後 com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
情報: Could not load @font-face font [（以下略
```

とか言われる。
cssに書くfont-face内のurlは http:// でも file:/// でもどちらにしても読めないっぽい。
ネットにアクセスできない環境を想定してるので、これは困った。
jquery.tmpl.jsの使い方まとめ

jquery.tmpl.jsが便利だったのでまとめ。
今、使うならangularjs　vuejsのほうがいいとおもいます。
案件でこちらを使っていたのでそれをそのまま踏襲する流れで調べたことをまとめておきます。

■基本的な使い方
####・JS側
```js
<script src="/js/lib/jquery.tmpl.min.js"></script>
<script id="template" type="text/x-jquery-tmpl">
${name}：${hoge}
</script>
<script>
  var data = {name:'text', hoge:'hello world.'};
  $('#template').tmpl(data).appendTo("#contents");
</script>
```
####・HTML側
```html
<div id="contents">
</div>
```
\#contentsのdivに対してテンプレート内で置換したものを出力します。
出力は以下のようなイメージです。

```html
<div id="contents">
text：hello world.
</div>
```

■テンプレートを別のファイルとして処理
テンプレートファイルは基本外部に出しておいてやったほうが見た目上も管理上もいいので
テンプレートファイルを別ファイルとして扱う方法をご紹介いたします。

####・js側の記述

```js
<script src="/js/lib/jquery.tmpl.min.js"></script>

<script type="text/javascript">
  //getでテンプレートを取得しておく
  var tmplate;
  $.get("tmpl.htm", function(data) { template = data; });

  //テンプレート用オブジェクト作成
  var obj = new Object();

  obj = {
    list : [
      { 'name' : 'aaa', 'no' : 1 },
      { 'name' : 'bbb', 'no' : 2 },
      { 'name' : 'ccc', 'no' : 3 }
    ]
  }
  //置換処理
  $.tmpl(template, obj).appendTo("#box");
</script>
```

####・tmpl.htm側の記述

```html

{{if list != ''}}
  <ul>{{each list}}
    <li{{if $index == 1}} class="first"{{else($index + 1 == list.length)}} class="last"{{/if}}>${no}:${name}</li>{{/each}}
  </ul>
{{else}}
  listがないよ！
{{/if}}
```

###・js側説明
$.get("tmpl.htm",function(data){template = data;});でテンプレートの内容を取得してきます。
dataに取得してきてtemplate変数に取得してきたコードを入れておきます。

var objでテンプレートでの変換に使うオブジェクトを生成しておきます。
今回はテンプレート上でループも再現するためにオブジェクトの中に配列を作成してます。

$.tmpl(template,obj).appendTo("#box");
idがboxの中にtemplateの中をobjを元に書き換えたものを追加します。
※appendTo以外つかえないのでappendToのところをhtmlなどに変えてしまうと動作しません。

###・tmpl.htm側説明
####　ifの書き方
if文を記述する際は{{if 条件式}}～～{{else 条件式}}～～{{/if}}
条件式はいろいろと記述可能です。
&&や||など基本的にはjsと同じような感覚で使っていけるようです。

####　ループの書き方（each文）
each文の使用が可能です。
js側でlistに配列をつくってあります。
ただし、jsのように配列でない場合などにエラーになります。
なので、{{if list != ''}}としています。
{{each list}}～～～{{/each}}
ループ中の現在の回数が$indexで取得可能です。
配列の要素数はxxx.lengthで取得可能です。
jsと同じ感覚です。

####　エスケープ処理
jquery.tmpl.jsでは自動でhtmlエスケープがかかるようになっています。
エスケープをかけたくない場合には{{html xxx}}の形でエスケープを無効にして出力が可能です。
ActiveRecordでkakurenbo-putiを使っている時のuniqueness検証

* Padrinoアプリを作っているうちに、モデルのuniquenessの検証をする必要があった。モデルには論理削除を設けているので、論理削除されたものは除外してuniquenessの検証をする必要があった。
* かつてparanoiaを使っている時は、```validates_as_paranoid ```としておくと適切に処理してくれたが、paranoiaはActiveRecordのバージョンアップに伴って動かなくなることがあって辛かった。
* ActiveRecordのメソッドを上書きしないkakurenbo-putiを使うようにしているが、uniqueness検証の書き方で錯誤したので、記す。
* 最初こう書いた。

```ruby:models/a.rb
class A < ActiveRecord::Base
  soft_deletable column: :deleted_at
  validates :name,
            uniqueness: {unless: :soft_destroyed?, message: "This name in Japanese is already existing."}
end
```

こうすると、```A.new(name: "あ")```した時には当然```soft_destroyed?```は```nil```なのですり抜けてしまう。

* こう書くのが正しいと思う。

```ruby:models/a.rb
class A < ActiveRecord::Base
  soft_deletable column: :deleted_at
  validates :name,
            uniqueness: {conditions: ->{without_soft_destroyed}, message: "This name in Japanese is already existing."}
end
```

* uniqueness検証の場合、今から作成や格納しようとするレコードを見て足りるわけではなく、あるスコープ全体を見る必要があるということに気付いた。
Swift2の配列、辞書の初期化

Swift1.2で通用した初期化方法が通用しない！!

```swift:foo.swift
//以下はコンパイルエラー発生
//var e: Dictionary[String: Int]
//var e: Dictionary<String: Int>
//var e: Dictionary
var e: [String: Int]
var d: [String: Int] = ["OK": 1, "NG": 0]
print(d) // =>[OK: 1, NG: 0]
var a: [[String: Int]] = [["OK": 1], ["NG": 0]]
func foo(inout a: [[String: Int]]) {
  a[0] = ["why": 2]
}
foo(&a)
print(a) // =>[[why: 2], [NG: 0]]

func bar(var a: [[String: Int]]) {
  a[0] = ["How":3]                                       
  print(a)
}
bar(a) // =>[[How: 3], [NG: 0]]

```

その代りメソッドの引数にvar修飾した変数を記載しておくと、メソッド呼び出し時に&修飾が不要になるみたい。

- どうやらArrayやDictionaryはOpen Source化への布石であって、iOS, OSX用アプリ作るんだったら、NSMutableArray, NSMutableDictionaryを使えって事じゃないのかなぁ。あと、高速動作を望むなら、使えるときにはNSArray, NSDictionaryとか。
- NSMutableArray, NSMutableDictionaryの方が宣言の記述が簡単だ。辞書を格納した配列なんか、[[String: Int]]なんて複雑なこと書かなくても、ただ単にNSMutableArrayって書けばコンパイルが通ってくれる。

```Swift:foo.swift
import Foundation
var d: NSMutableDictionary = ["OK": 1, "NG": 0]
print(d)
var a: NSMutableArray = [["OK": 1], ["NG": 0]]
func foo(a: NSMutableArray) {
  a[0] = ["Why": 2]
}       
foo(a)  
print(a)
a.addObject(["Which": 99])
print(a)
    
        
func bar(d: NSMutableDictionary) {
  d.setObject(3, forKey:"How") // add element.                                  
  print(d)
}
bar(d)
    
d.setObject(7, forKey: "OK") // modify element.
print(d)
//{                                                                             
//    NG = 0;
//    OK = 1;
//}
//(
//        {
//        Why = 2;
//    },
//        {
//        NG = 0;
//    }
//)
//(
//        {
//        Why = 2;
//    },
//        {
//        NG = 0;
//    },
//        {
//        Which = 99;
//    }
//)
//{
//    How = 3;
//    NG = 0;
//    OK = 1;
//}
//{
//    How = 3;
//    NG = 0;
//    OK = 7;
//}
```
DOSコマンド　ファイル名で検索、操作

カレントディレクトリから、**hoge**をファイル名に含むファイルを表示する
````
dir /A-D /B /S | findstr "hoge[^\\]*$"
````

#解説
##dir
ディレクトリを表示。表示させるするディレクトリ名を明示しない場合、カレントディレクトリが表示対象。
##/A-D
ディレクトリ以外を取得
**/A:D**なら、ディレクトリのみを取得

##/B
ディレクトリ名とファイル名のみを表示

##/S
サブディレクトリも含めた全てのファイル情報を表示

##findstr
文字列や正規表現を使って文字列を検索する 
###[^\\\\]
「ディレクトリ区切り文字を含まない」という意味
これをいれないと、ディレクトリ名に**hoge**を含んだディレクトリがあった場合、それも抽出されてしまう。

###$
行末にマッチ

カレントディレクトリから、**hoge**をファイル名に含むファイルを削除する

#抽出したファイルを削除

````deletefiles.bat
dir /A-D /B /S | findstr "hoge[^\\]*$" > temp.txt
for /f %%f in (temp.txt) do del "%%f"
del temp.txt

````
一時ファイルに出力して、それをもとに削除しています。
最後に一時ファイルを削除します。

#入力パラメータ
汎用性を持たせるなら、以下のようにするとよいでしょう。

````deletefile.bat
@echo off
echo 削除するファイル名(一部でも可)を入力してください
set /P SEARCHWORD=""
dir /A-D /B /S | findstr "%SEARCHWORD%[^\\]*$" > temp.txt
type temp.txt
echo 上記ファイルを削除しますか?(y/n)
set /P CONFIRM=""
if "%CONFIRM%"=="y"  for /f %%f in (temp.txt) do del "%%f"
del temp.txt

````
上記バッチファイルを所定のフォルダに保存し、実行すれば、そのフォルダ以下のファイルが対象となります。
※検索文字入力で何も入力しないとすべてが対象となってしまうので、その辺考慮したほうがよいです。

直接削除されるのが不安なら、一時フォルダを作成してそこに移動すればよいでしょう。

````moveFile.bat
@echo off
echo 削除するファイル名(一部でも可)を入力してください
set /P SEARCHWORD=""
dir /A-D /B /S | findstr "%SEARCHWORD%[^\\]*$" > temp.txt
type temp.txt
echo 上記ファイルを削除しますか?(y/n)
set /P CONFIRM=""
if "%CONFIRM%"=="y" (
mkdir temp
for /f %%f in (temp.txt) do MOVE /Y "%%f" temp
)
del temp.txt
````

このサンプルですと、すでに移動先ディレクトリがあった場合、その中も移動対象になりますので、その辺考慮する必要はありますが、特定のフォルダの以下の特定のファイル名を含むファイルを抽出したい場合には役に立つかと思います。
Node.jsでasyncモジュールを使って同期処理を行う

# Node.jsで同期処理を行う際にちょっとハマったのでメモ

# やりたかったこと
* Socket.ioのイベント内で、Redisにアクセスして、結果をゴニョゴニョして、Socket.ioでクライアントに結果を返す処理

# ちょっとハマったポイント
* Node.jsはノンブロッキングIOなので、関数が非同期に実行され、ゴニョゴニョする前の結果をSocket.ioで返却してしまっていた。

# 最初のソースコード
```
var redis = require("redis");
var socketIO = require("socket.io");
var express = require("express");
client = redis.createClient(port, 'ip');

//サーバー構築
var app = express();
var port = process.env.PORT || 5000;

app.use(express.static(__dirname + "/public"));
var server = http.createServer(app);
server.listen(port);

// Socket.IOサーバーを構築する
var io = socketIO.listen(server);

// websocketのイベント
io.sockets.on("connection", function (socket) {

 // イベントを受け取った時
 socket.on("event1", function (data) {
    
    //返却するリスト
    var returnArray = [];
    
    //Redisからデータを取得。ここでは複数のユーザープロフィールを取得したとする
    client.MGET(["userprofile1","userprofile2"], function(err, profiles){
        
        profiles.forEach(function (profile, i) {
            //ここでプロフィールをゴニョゴニョした結果をreturnArray に詰める
            returnArray.push(profile);
        });
    });
     
    //WebSocketで送信
    io.sockets.emit("retEvent1", returnArray);
  });

});
```
こんな感じで最初書いてましたw
こうすると、
`returnArray`は空っぽのまま、WebSocketで送信されてしまいます。
Node.jsはノンブロッキングIOなので、`client.MGET`が完了するのを待たずに、
次の`io.sockets.emit`が実行されてしまうためです。
これは、やりたいことと違うので、asyncモジュールを使って、処理を同期的に書き換えます。
これくらいの処理では、async使わずともできますが、`client.MGET`の中でさらに、Redisにアクセスして
ゴニョゴニョしてってやっていくと、ネストがどんどん深くなり、可読性、メンテナンス性が下がるのでオススメしません。
asyncを使うと、ネストを深くせずに、処理を記述していけます。

# ネストがどんどん深くなる例

```
client.MGET(["userprofile1","userprofile2"], function(err, profiles){
    
    
    client.GET("hoge", function(err, hogeval){
        // 何か処理

    	client.GET("fugafuga", function(err, fugaval){
         // 何か処理
    
         });
    
    });
    
});

```

# asyncを使ったソースコード
```
var redis = require("redis");
var socketIO = require("socket.io");
var express = require("express");

//async モジュールのインポート
var async = require('async');


client = redis.createClient(port, 'ip');

//サーバー構築
var app = express();
var port = process.env.PORT || 5000;

app.use(express.static(__dirname + "/public"));
var server = http.createServer(app);
server.listen(port);

// Socket.IOサーバーを構築する
var io = socketIO.listen(server);

// websocketのイベント
io.sockets.on("connection", function (socket) {

 // イベントを受け取った時
 socket.on("event1", function (data) {
    
    async.waterfall([
      function(callback) {
         client.MGET("userprofiles", function(err, profiles){
           //次の処理を呼び出す。callbackを呼ばないと次の処理は実行されない
           callback(null,profiles);
         });
    
      },
      function(profiles, callback) {
        var returnArray = [];
        profiles.forEach(function (profile, i) {
           //ここでプロフィールをゴニョゴニョした結果をreturnArray に詰める
           returnArray.push(profile);
       });
    
       callback(null,returnArray);
    
      },
     ],
     function(err, returnArray) { 
        //WebSocketで送信
        io.sockets.emit("retEvent1", returnArray);
   });

  });

});
```

async.waterfallを使うことで、ネストさせずに処理を記述していくことができます。


# 参考にしたサイト
* http://dev.classmethod.jp/server-side/asyn/
* https://github.com/caolan/async
AWS SQS メソッド一覧

### 全体系
sqs.createQueue(params = {}, callback) ⇒ AWS.Request
// 新規キューを作成する

sqs.deleteQueue(params = {}, callback) ⇒ AWS.Request
// キューを削除する

sqs.setQueueAttributes(params = {}, callback) ⇒ AWS.Request
// キューの設定を更新

sqs.getQueueAttributes(params = {}, callback) ⇒ AWS.Request
// 現在のキューの設定を取得

sqs.getQueueUrl(params = {}, callback) ⇒ AWS.Request
// ENDポイントのURLを取得

sqs.listQueues(params = {}, callback) ⇒ AWS.Request
// 現在のキューのリストを取得

sqs.listDeadLetterSourceQueues(params = {}, callback) ⇒ AWS.Request
// すでにDeadになっているキューのリストを表示

### 処理系
sqs.receiveMessage(params = {}, callback) ⇒ AWS.Request
// [1-10]件のメッセージを取得

sqs.sendMessage(params = {}, callback) ⇒ AWS.Request
// １件のメッセージを送信

sqs.sendMessageBatch(params = {}, callback) ⇒ AWS.Request
// 複数件のメッセージを送信

sqs.deleteMessage(params = {}, callback) ⇒ AWS.Request
// メッセージを１件削除

sqs.deleteMessageBatch(params = {}, callback) ⇒ AWS.Request
// メッセージを複数件削除

sqs.purgeQueue(params = {}, callback) ⇒ AWS.Request
// 全てのメッセージを削除

### APIドキュメント

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html#listQueues-property
dataTaskWithURLメソッドが吐き出すエラーの例

NSURLSession.sharedSession()で取得したsessionオブジェクトのdataTaskWithURLメソッドが失敗した時に吐き出されるエラーは、こんな感じです。(xcode7 beta + Swift2.0)

- NSErrorを取り出すコードの断片

```swift:foo.swift
let session = NSURLSession.sharedSession()                                      
let task = session.dataTaskWithURL(url,
  completionHandler: { data, response, error in
if error != nil {
  print("err descpription = \(error!.description)")
  print("err = \(error!.localizedDescription)")
  print("err code = \(error!.code)")
  print("err domain = \(error!.domain)")
  print("err userInfo = \(error!.userInfo)")
}

```

- debug consoleの出力

```swift:foo.swift
2015-06-23 13:49:10.814 xxx[4869:202756] CFNetwork SSLHandshake failed (-9824)
2015-06-23 13:49:10.827 xxx[4869:202756] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)

err descpription = Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo=0x7fe20be44500 {_kCFStreamErrorCodeKey=-9824, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSUnderlyingError=0x7fe20be3eec0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1200.)", NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://www.apple.com/, NSErrorFailingURLStringKey=https://www.apple.com/, _kCFStreamErrorDomainKey=3}

err = An SSL error has occurred and a secure connection to the server cannot be made.

err code = -1200

err domain = NSURLErrorDomain

err userInfo = [_kCFStreamErrorCodeKey: -9824, NSLocalizedRecoverySuggestion: Would you like to connect to the server anyway?, NSUnderlyingError: Error Domain=kCFErrorDomainCFNetwork Code=-1200 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1200.)" UserInfo=0x7fe20be3ec00 {_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9824, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9824}, NSLocalizedDescription: An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey: https://www.apple.com/, NSErrorFailingURLStringKey: https://www.apple.com/, _kCFStreamErrorDomainKey: 3]
```

このあたりは、Swift2のバージョンが上がるに従いthrowsへ書き直される予感！
PHP5.1以前の__toString()に注意せよ

マニュアル書き写し。


[__toString]
>
注意が必要なのは、PHP 5.2.0 より前では、 __toString() メソッドは echo または print と直接結合された場合のみコールされていたということです。 PHP 5.2.0 以降では、これはすべての文字列コンテキスト (たとえば printf() における %s 修飾子) でコールされます。しかし、その他の型のコンテキスト (たとえば %d 修飾子) ではコールされません。 PHP 5.2.0 以降では、__toString() メソッドを持っていないオブジェクトを文字列に変換しようとすると E_RECOVERABLE_ERROR が発生します。 


[__toString]:http://php.net/manual/ja/language.oop5.magic.php#object.tostring

# 引っかかったコード

```php

} catch(Exception $e) {
    // $e->__toString() = $e->getTraceAsString() を期待
    error_log($e)
}
```


# サンプル

```php
class A {
 function __toString(){
  return 'class A';
 }
}

try {
  $a = new A();
  throw new Exception('test exception');
} catch(Exception $e) {
  error_log($e);
  echo "printf\n";
  printf('%s', $e);
  echo "\ncast printf\n";
  printf('%s', (string)$e);
  echo "\ncast printf2\n";
  $e2 = (string)$e;
  printf('%s', $e2);
  echo "\necho\n";
  echo $e;
  echo "echo __toString\n";
  echo $e->__toString();
  echo "\n\n";

  error_log($a);
  echo "\nprintf\n";
  printf('%s', $a);
  echo "\ncast printf\n";
  printf('%s', (string)$a);
  echo "\ncast printf2\n";
  $a2 = (string) $a;
  printf('%s', $a2);
  echo "\necho\n";
  echo $a;
  echo "\necho __toString\n";
  echo $a->__toString();
  echo "\n";
}
```

## 5.1

```shell-session:stdout
printf
Object id #2
cast printf
Object id #2
cast printf2
Object id #2
echo
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}echo __toString
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}


printf
Object id #1
cast printf
Object id #1
cast printf2
Object id #1
echo
class A
echo __toString
class A

```

```shell-session:error_log

[18-Jun-2015 17:44:37] PHP Notice:  Object of class Exception to string conversion in /tmp/test.php on line 13
[18-Jun-2015 17:44:37] Object
[18-Jun-2015 17:44:37] PHP Notice:  Object of class A to string conversion in /tmp/test.php on line 28
[18-Jun-2015 17:44:37] Object

```

## 5.3


```shell-session:stdout
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}
printf
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}
cast printf
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}
cast printf2
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}
echo
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}echo __toString
exception 'Exception' with message 'test exception' in /tmp/test.php:11
Stack trace:
#0 {main}


printf
class A
cast printf
class A
cast printf2
class A
echo
class A
echo __toString
class A


```

```shell-session:error_log
[18-Jun-2015 18:00:10] exception 'Exception' with message 'test exception' in /tmp/test.php:13
Stack trace:
#0 {main}
[18-Jun-2015 18:00:10] class A


```


マニュアルにある通りですが、書いたからには忘れまい。
でもやっぱりバージョンを行き来すると混乱するので注意…
抄訳: Constructor Injection vs. Setter Injection

[Constructor Injection vs. Setter Injection](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/)

2009年の記事ですが、依存性注入の基本を学ぶにあたり役立つ知識だったので、一部補足しながら訳しました。コードを単体テスト可能にする（＝「接合点を作る」）ために、ぜひ知っておくべき内容です。

クラスBに依存しているクラスAをテストするときに、依存性を排除する典型的な方法として **Constructor Injection** (コンストラクター・インジェクション) と **Setter Injection** (セッター・インジェクション) があります。この記事ではそれぞれの実現方法と、どちらがベターかを解説しています。

以下、抄訳です。


セッター・インジェクション とは？
-----------------------
- Springフレームワークで使用。
- コンストラクタは引数を取らない。
- インスタンス化後、そのインスタンスの setter メソッドを使ってオブジェクトを注入する。

```java
Database db = new Database();

OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);

CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);
```

コンストラクター・インジェクションとは？
----------------------------
- Pico-Container や GUICE で使用。
- コンストラクタの引数にインスタンスを渡し、メンバ変数に設定する方法。
- もし引数が渡されなかったらデフォルトのインスタンスを作成する。

```java
CreditCardProcessor processor = new CreditCardProcessor(?queue?, ?db?);
```

どちらが良いか？
----------------
一見すると、コンストラクタにごちゃごちゃ引数を渡さなくて済むぶん、セッター・インジェクション の方が楽に書けて良いように思えます。しかしコンストラクター・インジェクションの方が優れている部分があるため、私は後者を選びます。それは、コンストラクター・インジェクションはパラメータの順序を指定でき、[Circular Dependency（循環参照）](http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/) に陥る危険が無いという点です。

一般的なアプリは多くのクラスと連携します。そこでセッター・インジェクションを採用してしまうと、何度も setter の呼び出しを行う事になってしまいます。これだと連携するクラスの数が増えるたびに setter をコールする行を追加しなくてはいけません。面倒ですし、コールし忘れの危険性も増えます。さらに `set` する順番が決まっている場合は最悪です。

一方で コンストラクター・インジェクションはコンストラクタさえ書いてしまえば、指定した順に、自動でクラスをインスタンス化してくれます。コンストラクトの時点ですべて設定が完了するので、後はそのオブジェクトを確実に使えます。

例
----
`CreaditCardProcessor` クラスをインスタンス化するケースを考えてみましょう。

```java
CreditCardProcessor processor = new CreditCardProcessor();
```

インスタンス化できてめでたしめでたし、とはなりません。実際にはこのクラスは `OfflineQueue` クラスと連携し、またDBとやりとりするために Database クラスとも連携します。これらのインスタンスを `set` してやらなければ使えません。

これらすべてをセッター・インジェクションで行うと、以下のようになります。

```java
// Database クラスのインスタンス化 
Database db = new Database();

// 設定
db.setUsername("username");
db.setPassword("password");
db.setUrl("jdbc:....");

// OfflineQueue クラスのインスタンス化
OfflineQueue queue = new OfflineQueue();

// 設定
queue.setDatabase(db);

// CreditCardProcessor クラスに、上で作ったインスタンスを setter でセットする
CreditCardProcessor processor = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);
```

これで全部？いや、要件が増えればさらに setter でセットする内容は増えるかもしれません。何かフレームワークを使っていれば楽に書く方法があるかもしれませんが、使ってない場合はもうお手上げです。

では同じことをコンストラクター・インジェクションで実現してみましょう。`CreditCardProcessor` は以下のようにインスタンス化できます。

```java
CreditCardProcessor processor = new CreditCardProcessor(?queue?, ?db?);
```

コンストラクタは `OfflineQueue` と `Database` のインスタンスを必要とするので、両方ともインスタンス化しましょう。

```java
// 必要となるインスタンスを作成する
Database db = new Database("username", "password", "jdbc:....");
OfflineQueue queue = new OfflineQueue(db);

// コンストラクタに渡してやる
CreditCardProcessor processor = new CreditCardProcessor(queue, db);
```

コンストラクタにインスタンスを渡すことができました。これで完了です。

このコードの良いところは、コンストラクタに渡す引数が不足していたらコンパイルエラーがちゃんと出ることです。また、意図していない順番でインスタンス化される不具合も防げます。

というわけで、個人的にはコンストラクター・インジェクションがおすすめです。
同僚にも同じ言語を使ってほしいと思ったら

ある言語を普及させたいと思っている場合の注意点をメモしました。

相手が使っている言語をけなさない。
新しい言語・新しいライブラリを習得するという手間を考えても
使った方が相手の仕事がはかどる場合だけ薦めるのがよいでしょう。

同等のことが同等にできて相手が困っていない場合に
言語の押し売りはしないことです。
（どちらの言語がいいかは、すぐ宗教論争になってしまいます。）

・「言語がそんなあるんだ。」
・「なんでそんな言語を使っているの？」
・「その言語は何がうれしいの？」
・「＊＊＊使えば十分じゃん。」
・「その言語で＊＊＊はできるの？」
・「その言語で作ってからC++で作り直すのは二度手間じゃない。」
・「他のメンバーが読めないような言語で書いてほしくない。」
こういった反応がでます。

「他のメンバーが読めないような言語で書いてほしくない。」という意見をもたれないように
注意深く発言しましょう。

まずは、自分専用のツールを作る範囲でだけ
その言語を使いましょう。
しかも、必要が生じた時には、他のメンバーが使えるようにドキュメントを
作成しましょう。

目的は、選択肢を増やすこと、
従来の言語を置き換えることではない。

まずは、自分の書いたコードを共有できるようにする。
書かないまでも、実行できる環境を整えよう。

次に他のメンバーが
書けないけど動作できるを目指します。(他人が作ったツールを使えるという利点を伝えよう）
そのような中で、他のメンバーが困っていそうな部分を便利に解決するツールを紹介していきます。

相手が困っている部分を楽ができるようにだけ考える。
・グラフの作成をOSの種類によらず簡便にできるようにする。
　グラフの作成を自動化したいというニーズは多い。

・使いたいライブラリがあるかどうか？

新しい言語を使うことは労力が増える。
そのため、新規に利用するかどうかは懐疑的になる理由はある。
「使ってみて役に立たなかったということはなくしたい。」
「バグがある処理系・ライブラリでひどい目を見たくない。」
「メンテナンスされず、ほったらかしの処理系はいやだ。」
「覚えるべき文法が多いのはいやだ。」
「やりたいことを実現するための関数を見つけにくいのはいやだ。」
「言語仕様が頻繁に変わる言語は避けたい。」

新しい言語の紹介を受ける側は常に用心するのは当然なこと。
自分が書きたいという分野で信頼のおけるライブラリがそろっている言語を
選ぶこと。
その言語は、時代によって変わっていくことを意識しつづけること。


「本体と追加のライブラリのインストール作業が面倒なのはいやだ。」
「落とし穴がある言語は使いたくない。」
「速さ重視のプログラムに書き換えたいときに。すべてやり直しになる言語はいやだ。」
「よく使う言語のよく使うライブラリをその言語の中でも使いたい。」


「その言語では＊＊＊はどう書くの？」
「＊＊のところがわからないんだけれども」
部署の中で、自分以外のユーザーが2名以上になると
ある程度普及しやすくなる。


権威のある人がその言語とライブラリを紹介してくれると
その言語に対する理解がだいぶ好意的になります。

デメリットの存在しない言語はありませんから、
その言語のデメリットには何があるのか、
それぞれのデメリットはどうやって低減できるのかを
伝えることが大切です。

ゆっくり時間をかけて紹介していくのがいいでしょう。


追記
・同僚の使っている言語やライブラリ、ツールの方が、自分が使っているものよりも優れていることが多々あります。
バージョン管理のツール一つにしても、より便利なツールに乗り換えてきました。
・同僚の使っているライブラリがとても良かったら、それをそのまま使うなり、wrapperを書いて使うなり、
　自分のよく使っている言語で書き直すなり、学ぶことは多い。
　

追記：
・その言語の特集を組んでいる雑誌を机の上に放り出しておく。
・大学の先生による解説や、学会やシンポジウムの権威者による紹介(slideshareなど）を
紹介する。
・社内の他部署の評価が高い人でその言語の利用者がいる場合、そういったことを自分の所属している部署の同僚にも伝える。

その言語に対して「デメリットがあるんじゃない」という視点に立って話しかけてくる人がいますから、むきになって反論しないことです。反論されると、意地になる人がいますから、上手にかわすような話し方をすることです。

未知のもの、怖いものと考える人がいます。ですから、日本の組織では、新しいものを世の中に先駆けて取り入れて考える人、自分の考えで新しいものを作る人に対して、過度にブレーキをかける人がいます。

そういった人の不安を減らすようにしたたかに行動しないと、「わけわからない言語でツールを作ったりしないでくれよ」という圧力で、使用が禁止されてしまうというばかげたことになりかねません。
名前付け > N倍速 > timesFaster / speedTimes

加速度試験などを行う場合の、その設定で「N倍速」がある。

「N倍速」の変数名は何がいいだろうか?

http://eow.alc.co.jp/search?q=times+speed などを参考にして「timesTheNormalSpeed」は...変数名が長い。

82件だが「timesFaster」を使っている例がある [github](https://github.com/search?p=4&q=timesFaster&ref=searchresults&type=Code&utf8=%E2%9C%93)

152件で「speedTimes」を使っている [github]( https://github.com/search?p=2&q=speedTimes&ref=searchresults&type=Code&utf8=%E2%9C%93 )
【Chrome43】floatで0.016pxの隙間ができて崩れる

先月末くらいから話題のやつです。ようやく自分の端末でも起きたのでメモ。
43.0.2357.124以降で起きてるっぽい？

```
<ul>
    <li>
        <img src="http://placehold.jp/150x150.png" alt="">
    </li>
    <li>
        <img src="http://placehold.jp/150x150.png" alt="">
    </li>
    <li>
        <img src="http://placehold.jp/150x150.png" alt="">
    </li>
</ul>
```

#対処
##CSSでどうにかする
###img（inline-blockのもの）にdisplay: block;
```
img {
    display: block;
}
```

###（文字を使っていなければ）floatしている要素にfont-size: 0;
```
li {
    font-size: 0;
}
```

###floatしている要素に幅を指定
```
li {
    width: 150px;
}
```

###font-familyにVerdanaを指定（追加でOK）
```
ul {
    font-family: Verdana;
}
```

###font-familyにMeiryoを指定（追加でOK）
```
ul {
    font-family: Meiryo;
}
```

##HTML
###要素内に「改行や空白」を含めない
```
<ul>
    <li><img src="http://placehold.jp/150x150.png" alt=""></li>
    <li><img src="http://placehold.jp/150x150.png" alt=""></li>
    <li><img src="http://placehold.jp/150x150.png" alt=""></li>
</ul>
```

デモ：[forked: chromeでfloatした要素に幅を指定しなかった場合0.016pxがはいる - jsdo.it](http://jsrun.it/Ituki/cmQm)
【bash】DBのバックアップから特定文字列を含んだレコードを抽出するスクリプト

業務で必要になってスクリプトを書いたのでメモ。

##条件
DB（mysql）のバックアップファイルはzipで、中身はdropとcreateのあとにデータを複数行まとめてinsertしている。このzipファイルが日付ごとに大量にある。

※ほんとにやりたかったことは、DBのデータがどこで変わったかを大量のバックアップファイルから追うこと。

##スクリプト
特定文字列でgrepするだけだと、insertの後ろ全てが取れてくるので、「),(」を改行コードに置換してからgrepすることにした。
※insertの先頭と最後はきれいにレコード取れないけどそれぐらいは良しにした。

grepを二回かけているのは、いきなり置換するより対象のinsert分抽出してからの方が早いから。

特定文字列を含んだレコードとファイル名を結果ファイル（out.txt）へ出力する。

```bash:bash
target=hogehoge

LF=$(printf '\\\012_')
LF=${LF%_}

for file in `ls *.zip`;do
  echo $file >> out.txt
  zcat $file | grep $target | sed 's/),(/'"$LF"'/g' | grep $target >> out.txt
done

```

参考:
[sedコマンドで文字列を改行に置換する、しかもスマートに置換する。](http://qiita.com/richmikan@github/items/3c74212b0d8dec9bd00f)
アプリケーションのインストール中に不明なエラーコードが発生しました 505

### 現象

ストアからインストール時に「アプリケーションのインストール中に不明なエラーコードが発生しました 505」が表示される。


### 原因

開発版のアプリとPlayのアプリがLolipopで同居するとパーミッションエラーになる。
開発版を削除するとインストールできる

### ※
私の場合、開発版が「このユーザーでは未インストール」の状態で残っていた（ドロワーには表示されなかったのですごい困った）
「設定＞アプリ」で見つけたのでそこから削除。削除も通常のアンイストールができず、そのアプリの詳細を表示して右上から「すべてのユーザーから削除」を選択して削除した。

参考
https://teratail.com/questions/3539