OmniAICreator/Qiita-1.07M huggingface dataset:
WCFのhttp通信で動的圧縮に対応する。(.Net3.5 / IIS8.5)

.Net4.0からは簡単だけど.Net3.5ではめんどくさかった。

クライアントサイド
https://code.msdn.microsoft.com/WCF-Compression-Example-9ffab49c
直接ServiceClientとかをカスタムするのではなくWebRequestに介入すればよいっていうのは盲点だった。

サーバーサイド
http://www.hanselman.com/blog/EnablingDynamicCompressionGzipDeflateForWCFDataFeedsODataAndOtherCustomServicesInIIS7.aspx
動的圧縮の細かい設定はサーバに対して行う。
サイトに対してはできない。
DynamicTypeは環境的に特に問題なければapplication/*が楽。
AWS EC2 Redmine導入済みのAMIを試してみた(farend)

題名通りのことをやってみました。すごく簡単に出来ました！

#ザックリな手順
1. AMIを選択してインスタンスを作成(下記参考サイトに分かり易い情報があります)
2. 起動するのを待つ
3. 作成したインスタンスのパブリックIPにアクセス

これだけ！ビックリしました^^

# アクセスできなかった
ただ、少しハマりました。。。アクセスできないぞ？って^^;
セキュリティーグループの設定にHTTPを追加していなかったのです。
インスタンスを作成する時か、作成後にセキュリテーグループにHTTPの追加を忘れ無い様に^^v

#参考サイト

・Redmine 3.0のAMIをAWS東京リージョンで公開
http://blog.redmine.jp/articles/3_0/redmine-ami/

・Join記念日はRedmineの話をするよ
http://www.farend.co.jp/blog/2015/04/published-redmine-ami/

#所感
久々の更新！仕事が忙しくて、全然更新できなかった。
今度は自分でRedmineを導入してみよう。
もしかしたら、現場によってはウチのサーバに入れてよとかありそうだし。
Homebrewのインストールに失敗した時に確認したいこと

## 経緯

- proxy環境下で新規にHomebrewをインストールしたかった
- 環境変数設定前にHomebrewインストール用のスクリプト実行してしまったりゴニョゴニョやってしまっていた
- その後とりあえず環境変数http_proxyの指定などは済んでいた

ということで、下記を実行してみても

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


このようなメッセージになっていたので

```
It appears Homebrew is already installed. If your intent is to reinstall you
should do the following before running this installer again:
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
```

そこで上記のメッセージにある削除用スクリプトを実行してみても効果なし。

```
brew -v
```

とかやっても、そもそもインストールされていないのに削除とかできませんよね。



調べるうちに、

```
/usr/local/.git
```
があることに気がついたので、早速削除。

もう一度インストールコマンドを実行してみたら無事完了。

何らかの理由でインストールに失敗とか、Homebrew自体を削除したあとに、再度入れなおしたいなどの場合、もしこういう現象になったら疑ってもいいのでは？ということでした。
Webアプリのバージョニングについて

Webアプリのバージョン管理について、個人的に行っている内容のメモ。

# Webアプリのバージョン

まずアプリケーションはセマンティックバージョニングで管理する。
http://semver.org/lang/ja/
APIの変更に互換性のない場合はメジャーバージョン、後方互換性があり機能性を追加した場合はマイナーバージョン、後方互換性を伴うバグ修正をした場合はパッチバージョンを上げる。

Webアプリということはnpmでgrunt・gulp・browserifyなどを使っていることが多いと思うので、package.jsonのversionを書き換えることによってアプリのバージョンを参照出来るようにする。

以下はbrowserifyを使っている場合の例

```js:package.json
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-browserify');

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    browserify: {
      app: {
        files: {
          './app.js': ['src/index.js']
        },
        options: {
          banner: 'var version ="<%= pkg.version %>";'
        }
      }
    }
  });
};
```

bannerオプションでpackage.jsonのversionを埋め込んでいる。
この場合はグローバル変数として定義されてしまうので、concat等を使って無名関数で括ったり、何かオブジェクトに定義するようにしてもいいと思う。


# メジャーバージョンを上げるとき

Ajaxなど通信インターフェースが変わるような、後方互換性がないリリースをしないといけないときについて。

URLにバージョンを含めて「/api/v1/getUser」などとするのは痛手になりやすい。
だいたいコードのコピペが発生してつらいし、バージョンアップ後にクライアント側でブラウザリロードが発生すればv1はもう使わないので残しておく意味もない。

というわけで、HTTPのレスポンスヘッダーにAPIバージョンを埋め込む。

```
X-Api-Version: 1
```

という感じで、APIのバージョンはメジャーバージョンのみを使っている。
あとはフロントエンド側でAjax通信をする際にX-Api-Versionを参照して、バージョンが新しくなっていればダイアログを表示してユーザーにリロードを行う旨を通知し、リロードを行う。

jQueryを使っているならAjaxのコールバック関数中に以下で取れる。

```js
jqXHR.getResponseHeader('X-Api-Version');
```

$.ajaxのラッパー関数としてrequest関数などを作り、そこにエラー処理やデフォルト設定を詰め込んで、全てのAPI通信がそこを通るようにすると楽。

## 追記

こういったバージョンアップを稼働中のサービスで行うときは、ユーザーへの事前告知をしている前提でブラウザリロードしています。
[Linux][tips] UNIX時間(UNIX time)からその日時を求める

squid.logなどで出力されるUNIX timeがいつの日時を指しているのか確認するための手順を紹介します

UNIX時間は1970年1月1日の0時0分0秒からの経過秒数です。(厳密には閏秒が考慮されているようです)

# UNIX時間の日時を確認する

dateコマンドに -d オプションまたは --date オプションを指定し、"@"に続けてUNIX時間を指定します

実行例
<pre>
$ date -d "@121212000"
1973年 11月  4日 日曜日 07:00:00 JST

$ date --date "@121212000"
1973年 11月  4日 日曜日 07:00:00 JST
</pre>

# 日時のUNIX時間を確認する

-d オプションに日時を入れて、出力フォーマットを"%s"にします

実行例
<pre>
$ date -d "2012-12-12 12:12:12" +%s
1355281932
</pre>

現在時刻のUNIXを確認するには、単に"+%s"のみを指定すれば良いです

<pre>
$ date +%s
1446601854
</pre>
macでfluentdを使ってみた


## download install
http://docs.fluentd.org/articles/install-by-dmg


## launchctl

```
sudo launchctl load /Library/LaunchDaemons/td-agent.plist
```

## add plugin

```
sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-kafka
```

## back up 

```
cp /etc/td-agent/td-agent.conf /etc/td-agent/td-agent.conf.bak
```

## /etc/td-agent/td-agent.conf

``` bash:td-agent.conf
<source>
  type tail
  format apache
  path /var/log/test/test.log
  pos_file /var/log/td-agent/td-agent.log.pos
  tag apache.access
</source>
<match *.**>
  type file
  format json
  path /var/log/out/out.log
</match>
```


## start fluentd

```
sudo launchctl start td-agent
```

## fileに追記

```
data >> /var/log/test/test.log
```

## 転送確認

```
cat /var/log/out/out.log
```

## stop fluentd

```
sudo launchctl stop td-agent
```
Cloud9 IDE上でrails serverの起動

[cloud9](https://c9.io)でRuby on Railsの開発を行うときにサーバーを立ち上げるときのコマンドです。よく忘れるのでメモ。

cloud9のターミナル上で

```
rails s -b $IP -p $PORT
```

です。
ローカルで開発するときと若干ちがいます。


参考
[Running a Rails App](https://docs.c9.io/docs/running-a-rails-app)
AndroidStudio/Git Hubでよく見る英単語

##AndroidStudio
用語|意味
:--|:--
build|~~コンパイル~~ソースコードのコンパイルやライブラリのリンクなどを行い、最終的な実行可能ファイルを作成すること
gradle|ビルドシステム
aceept|受け入れる
ignore|無視する、除外する
exception|例外的状況、想定外の事態（メモリが少なかったり）
parse|解析する
failed|失敗
comfirm|確認
JDK|基本的なjavaクラス
SDK|携帯電話用のjavaクラスや開発ツール（software development kit)
インスタンス|実体化すること、newする
context|文脈、アクティビティ
sync now|同期
configurat|自分で設定する
intent|意図・目的、主にアクティビティを起動する時に使う、newする
resolve|解決する

>buildの参考
ビルド 【 build 】
http://e-words.jp/w/%E3%83%93%E3%83%AB%E3%83%89.html


##GitHub
用語|意味
:--|:--
checkout|今のファイルの状態から出て移動する
force checkout|ローカルの変更を無視してチェックアウト
smart checkout|ローカルの変更をstashしてチェックアウト
merge|統合する
conflict|衝突
stash|一時的に退避
add root|あやふや（Gitにつなげる、Enable VCS->Gitと同じと考えるのはちょっと違うかも？）
リポジトリ|ファイルやディレクトリの状態を記録する場所

>smart checkoutの参考
AppCodeのsmart checkoutが便利だ
http://anton0825.hatenablog.com/entry/20140331/1402648066
SQL Serverのバージョン確認


# SQL Serverのバージョン確認

## SQL Serverの製品名とバージョンの取得


```sql:SQL
    SELECT @@VERSION
```
SQL Serverのバージョンやエディションによって結果は異なります。
 - SQL Server 7.0
  >`Microsoft SQL Server 7.00 - 7.00.623 (Intel X86) Nov 27 1998 22:20:07 Copyright © 1988-1998 Microsoft Corporation Desktop Edition on Windows NT 5.1 (Build 2600: )`
 - SQL Server 2008 R2
  >`Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) Apr 2 2010 15:48:46 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7600: ) (Hypervisor)`
 - SQL Server 2012
>`Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Feb 10 2012 19:39:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)`
 - SQL Server 2012 SP1
 >`Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) Oct 19 2012 13:38:57 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.2 <X64> (Build 9200: ) (Hypervisor)`
 - SQL Server 2014
 > `Microsoft SQL Server 2014 - 12.0.2000.8 (X64) Feb 20 2014 20:04:26 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)`
 - SQL Server 2014 SP1
 > `Microsoft SQL Server 2014 - 12.0.4100.1 (X64) Apr 20 2015 17:29:27 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)`

## SQL Serverのプロダクトバージョンの取得
```sql:SQL
    SELECT SERVERPROPERTY('productversion')
```
バージョン番号とSQL Serverの製品との対応付けは下記の通りです。  

| プロダクト バージョン | 製品名 |
|-------------------------:|:------------:|
| 12.0.4100.1 | SQL Server 2014 SP1 |
| 12.0.2000.8  |SQL Server 2014 |
| 11.0.3000.0  | SQL Server 2012 SP1 |
| 11.0.2100.60 |SQL Server 2012 |
| 10.0.1600.22 |SQL Server 2008 |
| 10.0.2531.00 |SQL Server 2008 Service Pack 1 |
| 10.50.1600.1 |SQL Server 2008 R2 |
| 9.00.1399.06 |SQL Server 2005 |
| 9.00.2047.00 |SQL Server 2005 Service Pack 1 |
| 9.00.3042.00 |SQL Server 2005 Service Pack 2 |
| 9.00.4035.00 |SQL Server 2005 Service Pack 3 |
| 8.00.194 | SQL Server 2000 |
| 8.00.384 | SQL Server 2000 SP1 |
| 8.00.534 | SQL Server 2000 SP2 |
| 8.00.760 | SQL Server 2000 SP3 |
| 8.00.760 | SQL Server 2000 SP3a| 
| 8.00.2039 | SQL Server 2000 SP4 |
| 7.00.623 | SQL Server 7.0 |
| 7.00.699 | SQL Server 7.0 Service Pack 1 (SP1) |
| 7.00.842 | SQL Server 7.0 Service Pack 2 (SP2) |
| 7.00.961 | SQL Server 7.0 Service Pack 3 (SP3) |
| 7.00.1063 |SQL Server 7.0 Service Pack 4 (SP4) |
| 6.50.201 |SQL Server 6.5 |
| 6.50.213 |SQL Server 6.5 Service Pack 1 (SP1) |
| 6.50.240 |SQL Server 6.5 Service Pack 2 (SP2)| 
| 6.50.258 |SQL Server 6.5 Service Pack 3 (SP3) |
| 6.50.281 |SQL Server 6.5 Service Pack 4 (SP4) |
| 6.50.415 |SQL Server 6.5 Service Pack 5 (SP5) |
| 6.50.416 |SQL Server 6.5 Service Pack 5a (SP5a) |
| 6.50.479 |SQL Server 6.5 Service Pack 5a (SP5a) Update|


## SQL Serverのエディションの取得

```sql:SQL
    SELECT SERVERPROPERTY ('edition')
```
[例]
>Standard Edition (64-bit)

## 参考リンク
[SQL Server とそのコンポーネントのバージョンとエディションを確認する方法](https://support.microsoft.com/ja-jp/kb/321185)
Rakeが引数を受け取ってくれない


rake taskに実行時オプションを渡すときは ENV を使って渡すと便利だけどなんでもかんでも使えるわけではないという話

```Rakefile
task :superimportanttask do
  if ENV["envvar"]
    puts "set envvar: #{ENV["envvar"]}"
  end

  if ENV["env-var"]
    puts "set env-var: #{ENV["env-var"]}"
  end

  if ENV["--envvar"]
    puts "set --envvar: #{ENV["--envvar"]}"
  end

  if ENV["--env-var"]
    puts "set --env-var: #{ENV["--env-var"]}"
  end

  if ENV["env_var"]
    puts "set env_var: #{ENV["env_var"]}"
  end
end
```

実行してみる

```sh
$ rake superimportanttask envvar=hoge
set envvar: hoge
$ rake superimportanttask env-var=hoge
rake aborted!
Don't know how to build task 'env-var=hoge'

(See full trace by running task with --trace)
$ rake superimportanttask --env-var=hoge
invalid option: --env-var=hoge
$ rake superimportanttask --envvar=hoge
invalid option: --envvar=hoge
$ rake superimportanttask env_var=hoge
set env_var: hoge
```

環境変数名の途中にハイフン（ダッシュ）が入るとタスク名として認識され、頭につくとrakeの実行オプションとして認識される。アンダーバーは大丈夫。そもそもRakeは定まった処理を実行するためのものとして利用されることが多いし、実行時オプションに依存するタスクが多いほど再現性が低下するのでやめた方がいいんじゃないのという話もある。
Fluentd v0.14.0.pre.1のリリース


Fluentdのv0.14の開発バージョンであるv0.14.0.pre.1をリリースしました．
これはテストして欲しい以下の二つの機能が実装されたからです．

- Windowsサポート
- イベントのナノ秒サポート

## インストール

開発版なので，普通にインストールは出来ません．`--pre`をつけてください．注意点として，v0.14はruby 2.1以上を必要とします．

```sh
gem install fluentd --pre --no-document
```

依存ライブラリのいくつかがWindows向けのbinary gemをリリースしてないので，Windows環境ではDevKitが必要になると思います．DevKitのインストールについては[fluentd for WindowsをRuby 2.2で動かす](http://qiita.com/nurse/items/b38a7f2c084cf2b56631)の記事を参照してください(時間があればパッチを投げたい)．


## Windowsサポート

nurseさんやokahashi117さんの尽力やパッチを投げてくれた方々のおかげで，Windowsで動くようになりました．テストは全部通っているので，基本的なプラグインは動くようになっているはずです．ただ，まだ様々な環境でのテストが出来てないのは事実なので，是非皆さんの手元で動かしてもらい，問題があればどんどんissueで報告してもらいたいです(PRも勿論Welcomeです)．

## イベント時間のナノ秒サポート

mururuさんによって実装されました．Fluentdのイベントにつく時間は今まで秒でしたが，v0.14から`Fluent::EventTime`を導入することでナノ秒になりました．プラグインによっては対応が必要にはなりますが，Elasticsearchならミリ秒，Google系ならナノ秒でちゃんとログを保存出来るようになります．

`EventTime`は既存の秒実装と最大限互換性を保つように実装されているので(秒として振る舞う)，広く使われているプラグインのほとんどで問題なく動くことは確認しています．あるプラグインでナノ秒精度で扱いたい場合には，`sec`/`nsec`でそれぞれの値を取り出すか，もしライブラリ内で`Time.at(time)`を使っていた場合には，何もせずともナノ秒で保存されるようになるでしょう．
もしナノ秒のための特別な実装と分けたい場合には以下のようにすれば，既存実装に影響を与えずv0.14向けのテストが出来ると思います．

```rb
if defined?(Fluent::EventTime) # v0.14
  def format(tag, time, record)
    # ...
  end
else # v0.12
  def format(tag, time, record)
    # ...
  end
end  
```

PR([Support nanosecond #653](https://github.com/fluent/fluentd/pull/653))には互換性周りの注意点などが書かれているので，英語ですが気になる方は読んでみてください．いずれプラグイン開発者向けのガイドもちゃんと書く予定です．

v0.14にはまだ未実装の機能があるので正式リリースはまだですが，是非色々とテストして貰えると助かります！
.NET Frameworkのバージョン 確認


# .NET Frameworkのバージョン

@ITの下記の記事が分かりやすくまとまっているので
備忘録がてら記述します。

[.NET Frameworkのバージョンを整理する (1/2)][1/2]
[.NET Frameworkのバージョンを整理する (2/2)][2/2]

[1/2]:http://www.atmarkit.co.jp/ait/articles/1211/16/news093.html
[2/2]:http://www.atmarkit.co.jp/ait/articles/1211/16/news093_2.html

### .NET Frameworkの各バージョン同士の関係

![関係.png](https://qiita-image-store.s3.amazonaws.com/0/99066/b109ff1e-3873-44ff-75b7-c73fdd125074.png)  
```
.NET Frameworkの各バージョンの関係
水平に並ぶ4つのグループはお互いに独立していて、一つのシステムに複数のバージョンを  
インストールして同時に利用できる。逆に言えば、上位バージョンをインストールしても下位
バージョンをインストールしたことにはならない。Ver.2.0／3.0／3.5は内包関係にあるが、
Ver.4／4.5.x／4.6は置き換えなので共存できない。原則として、個々の.NET対応アプリ
ケーションが必要とするバージョンの.NET Frameworkをそれぞれインストールすることになる。
```

### 各Windows OSで利用できる.NET Frameworkのバージョン
![クライアントWindows OS.png](https://qiita-image-store.s3.amazonaws.com/0/99066/4148819c-0255-8a04-61d8-d1ddd0f14c30.png)
![Windows Server.png](https://qiita-image-store.s3.amazonaws.com/0/99066/e39689b4-f04e-f5c2-9ef7-54732e53ac9c.png)
```
各Windows OSにインストール可能な.NET Frameworkのバージョン
「プレインストール」は各Windows OSのデフォルト設定でインストールされるかどうかを表している。
そのため設定次第では、「プレインストール」のものがインストールされていなかったり、
「インストール可能」の範囲内で別のバージョンの.NET Frameworkがプレインストールされていたりする
こともある。また打ち消し線は、すでにサポートが終了していることを表している。
＊1　Tablet PC／Media Centerエディションには、Ver.1.0がプレインストールされていた
＊2　Ver.1.1はインストールできる場合もあるが、マイクロソフトはサポートしていない
＊3　Ver.4.x系列は上位のVer.4.xによって置き換えられるため、これらのWindows OSには
該当バージョンの.NET Frameworkをインストールできない。
    ただし、Ver.4.x系列に対応する.NETアプリケーションは一部の例外を除いて上位のVer.4.x上で実行できる
```

### .NET Frameworkのバージョンの確認方法
 - Microsoft社から提供されているバージョン確認方法 - レジストリ情報
[インストールされている Microsoft .NET Framework の
バージョンとサービス パック レベルを確認する方法][1]  
[1]:https://support.microsoft.com/ja-jp/kb/318785
 - @ITの記事に載せている.NET Frameworkのバージョン確認方法 - バッチ・ファイル
[バージョン自動検出用バッチ・ファイル（ZIPファイル）][2]  
このZIPファイルを展開すると「checkvdnfw_cmd.txt」というファイルが生成される。
これを「checkvdnfw.cmd」にリネームして、管理者モードで起動します。
やはり、レジストリ情報を探すより、バッチファイルで確認するのが簡単だし早いですね。
[2]:http://www.atmarkit.co.jp/ait/files/20121026/checkvdnfw-20151009.zip
```bat:checkvdnfw.cmdの実行例
C:\Temp>checkvdnfw.cmd \\UserPC01
----- \\UserPC01 -----
.NET Framework 2.0 Service Pack 2 がインストール済みです
　日本語Language Pack（Service Pack 2）がインストール済みです
.NET Framework 3.0 Service Pack 2 がインストール済みです
　日本語Language Pack（Service Pack 2）がインストール済みです
.NET Framework 3.5 Service Pack 1 がインストール済みです
　日本語Language Pack（Service Pack 1）がインストール済みです
.NET Framework 4.6 がインストール済みです
　日本語Language Packがインストール済みです
```
Anacondaに入っているSpyderを使ってみる

[こちらの記事](http://ktadaki.hatenablog.com/entry/2015/10/27/094325)に触発されて、自分の環境にもSpyderを導入することを決めた。
公式から落としてくるかな...と思っていたら、Anacondaには Spyderがmoduleとしてインストールされていることを知った。（参考: https://pythonhosted.org/spyder/installation.html）

* Python 3.4.3 :: Anaconda 2.4.0 (x86_64)
* spyder (2.3.7)

すでにAnacondaは導入済みだったので、早速使ってみた。

```bash
$ spyder
```

動いた。
Spyderが立ち上がったのはいいが、このままだと、Spyder起動中はターミナルが使えなくなってしまう。ということで、バックグラウンドで動かそうと思った。

```bash
$ spyder &
```

できた。
ついでに、これをaliasにしておくと便利かもと思ったので、aliasにしてみた。

```bash
$ alias spy="spyder &"
```

問題なし。
これからはPythonの開発には積極的にSpyderを使っていこう。

-----
### * 補足

pyenvを使っている環境だと、Anacondaを有効にしている場所でしかspyderを起動できない。なので、ちょっと長くなるが**pyenv配下にあるAnaconda内のpythonを使ってSpyderを直接起動する**ようにaliasを設定し直した。

```bash
$ alias spy="~/.pyenv/versions/anaconda3-2.3.0/bin/python3.4 ~/.pyenv/versions/anaconda3-2.3.0/lib/python3.4/site-packages/spyderlib/start_app.py &"
```

これでどこでコマンドを叩いても、同じようにSpyderが立ち上がる。
pyenvで管理しているバージョンごとに起動させたい、という時も、aliasの名前とversions以下を望みのものにちょっと修正してあげればうまくいく。
非エンジニアに古いプログラムの問題を物件のたとえで説明した

昨今お茶の間をにぎわせているこのニュースを見て、プログラムも似ているな、と思いました。

* [なぜ不正、募る疑問　専門家「犯罪に近い」　横浜・マンション傾斜 （カナロコ by 神奈川新聞） - Yahoo!ニュース](http://mainichi.jp/select/news/20151017k0000m040136000c.html)


## 非プログラマに古いプログラムの問題を説明した時のたとえ

* 古いプログラムの面倒を見るより、一から作ったほうがメンテナンスしやすい。
* 家で例えれば築10年の家をリフォームして店舗に変えるより、平屋にしてから新築を立てたほうが良い。
* 基礎部分や骨組みは変えることが難しいように、プログラムもそういうもの。


## サポートが切れたバージョンの説明

* 修繕してくれる管理会社は居なくなった。
rbenvでrubyのバージョンを切り替える


## 現在のrubyのバージョンを確認

```
$ ruby --version
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin12.0]
```

rbenvでインストールしてあるrubyのバージョン確認

```
$ rbenv versions
  system
  2.0.0-p195
* 2.1.1 (set by /Users/user_name/.rbenv/version)
```

rbenvでインストールできるrubyのバージョンを確認

```
$ rbenv install -l
Available versions:
  1.8.6-p383
  1.8.6-p420
  1.8.7-p249
  1.8.7-p302
  1.8.7-p334
  .
  .
  .
```


## インストールしたいrubyのバージョンがリストにない場合

```
$ brew update
$ brew upgrade rbenv ruby-build
```

もっかい確認

```
$ rbenv install -l
Available versions:
  1.8.6-p383
  1.8.6-p420
  1.8.7-p249
  1.8.7-p302
  1.8.7-p334
  .
  .
  .
  2.1.5
```

## インストール

```
$ rbenv install 2.1.5
Downloading ruby-2.1.5.tar.gz...
-> http://dqw8nmjcqpjn7.cloudfront.net/4305cc6ceb094df55210d83548dcbeb5117d74eea25196a9b14fa268d354b100
Installing ruby-2.1.5...
Installed ruby-2.1.5 to /Users/user_name/.rbenv/versions/2.1.5
```

確認

```
$ rbenv versions
  system
  2.0.0-p195
* 2.1.1 (set by /Users/user_name/.rbenv/version)
  2.1.5
```

## インストールしたバージョンに変更

```
$ rbenv local 2.1.5
```

確認

```
$ ruby --version
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin12.0]
```

おしまい。

と、思ったら

```
rails s
/Users/user_name/.rbenv/versions/2.1.5/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- bundler/setup (LoadError)
	from /Users/user_name/.rbenv/versions/2.1.5/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /Users/user_name/work/hyakuren/jamb_temp/config/boot.rb:4:in `<top (required)>'
	from bin/rails:7:in `require_relative'
	from bin/rails:7:in `<main>'
```

rails動かなくなったー。

## cannot load such file -- bundler/setup (LoadError)

```
$ rbenv exec gem install bundle
```

これで動きました。



参考：
http://h2ham.net/ruby-rbenv
http://ylgbk.hatenablog.com/entry/2014/08/24/192707
golangでシグナルを拾ってgracefulにgoroutineを停めたい

# golangでシグナルを拾ってgracefulにgoroutineを停めたい

とりあえず `SIGHUP` をトラップしてみる。

…全然カンタンじゃない。
もうちょいなんとかならないのかと思うけど、とりあえずこれで上手くいってそうな気がする。

=> 続き
http://qiita.com/arc279/items/6154919702b2fa408c72

```go:main.go
package main

import (
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

func main() {

	procs := []string{
		"proc1",
		"proc2",
		"proc3",
		"proc4",
		"proc5",
		"proc6",
		"proc7",
	}

	ch := make([]chan int, len(procs))
	for i, _ := range ch {
		ch[i] = make(chan int)
	}

	var wg sync.WaitGroup
	// goroutine起動
	for i, id := range procs {
		wg.Add(1)
		go func(ch chan int, id string) {
			cnt := 0
			fmt.Println("start " + id)
			for {
				select {
				case sig := <-ch:
					fmt.Println(sig)
					wg.Done()
					break
				default:
					// 何らかの平行処理したいやつ
					cnt++
					fmt.Println(fmt.Sprintf("%s>> %d", id, cnt))
					time.Sleep(500 * time.Millisecond)
				}
			}
		}(ch[i], id)
	}

	// HUP シグナルをトラップ
	signal_chan := make(chan os.Signal, 1)
	signal.Notify(signal_chan,
		syscall.SIGHUP,
	)
	go func() {
		for {
			switch <-signal_chan {
			case syscall.SIGHUP:
				fmt.Println("hungup")
				for _, c := range ch {
					c <- 1
				}
			}
		}
	}()

	// goroutine終了を待ち合わせ
	wg.Wait()

	fmt.Println("stop gracefully")
	os.Exit(0)
}
```

## ビルドして実行

```bash
$ go build -o sample main.go && ./sample
```

## シグナル送る

別の端末から

```bash
$ kill -SIGHUP `pgrep -f sample`
```
バッファが足りないと結果が切り捨てられる文字列取得関数を自動リトライするユーティリティ関数

Windowsプログラミングをしていると、「バッファにめいっぱい文字列を取得し、バッファが足りなければ切り捨てます。取得できた文字数を返します」というインターフェースのAPIがたくさん出てきます。`LoadString`だとか`GetWindowText`だとか。事前に必要なバッファサイズがわからず、取得結果の文字数がバッファ一杯だったことで、「もしかして切り捨てられた残りがあるかも?」とわかるというインターフェース、出会うたびにうんざりさせられます。
バッファは何文字分確保しましょう？ 十分に大きく？ その十分っていくらですか…?

そのうんざりを解決してくれるユーティリティ関数`challenge_get_string`を用意しましたのでお役立てください。
`(引数..., バッファポインタ, バッファサイズ) -> 取得文字数` というシグネチャの関数を、全部取得できるまでバッファを拡大しながらリトライします。

文字の型（`char`か`wchar_t`かでしょう）が指定必須の型パラメータで、残りの型パラメータ（関数ポインタの型、関数に渡す引数の型）は省略可能です。

```cpp
// バッファが足りないと結果が切り捨てられる文字列取得関数を、バッファを拡大しながら呼び出し続けて全内容を取得します
template<typename TChar, typename PFunc, typename... TParams>
std::basic_string<TChar> challenge_get_string(PFunc f, TParams... params)
{
	vector<TChar> buf(256);
	size_t result_len;
	for (;; buf.resize(buf.size() * 2))
	{
		result_len = f(params..., buf.data(), buf.size());
		if (result_len < buf.size() - 1) break;
	}
	return std::basic_string<TChar>(buf.data(), result_len);
}
```

すると以下のように`LoadString`だとか`GetWindowText`をスマートに呼び出せるわけです。


```cpp
// ウィンドウのキャプションを取得します
std::wstring get_window_text(HWND hWnd)
{
	return challenge_get_string<wchar_t>(&GetWindowTextW, hWnd);
}

// リソースから文字列を取得します
std::wstring load_resource_string(UINT id)
{
	return challenge_get_string<wchar_t>(&LoadStringW, GetModuleHandle(NULL), id);
}
```

`challenge_get_string`はC++汎用で書いてありますが、Windows開発に特化するなら`TChar`を型引数にせず`TCHAR`決め打ちにした方がテンプレート引数が不要になってすっきりするかもしれません。`std::string`と`std::wstring`を`UNICODE`マクロに応じて使い分ける`std::tstring`なんて自前で定義したりしつつ。
フォーム内でonclick属性を使う時には、name / idに気をつけよう

# はじめに
form周りのコードを書いていたところ、思わぬ動作に遭遇しました。基本的な知識かもしれませんが、知らなかったので備忘録がてらメモしたいと思います。





# 結論
さっそく結論を書いてしまうと、**`<form>`タグ内においてフォーム部品（inputなど）のnameやidと、onclick属性で呼び出すユーザ定義関数名が重複していると関数が実行されない**というものです。

名前が重複していなかったり、`element.onclick = function() {}`や`.on()`でイベントを設定していれば避けられるので、遭遇する機会は少ないかもしれません。ですがせっかくなので、これに至るまでの道のりを簡単に残したいと思います。。。

> 動作はchrome 46.0.2490.80で確認しました



# 鳴らない、電話
（実際のものから相当省略していますが）以下のようなコードを書いていました。
とりあえず動作を確認しようと思い、`onclick`属性で関数を実行させようとしました。


```index.html
<script>
  function callPhone() {
    console.log('ジリリリ...');
  }
</script>
<form action="" onsubmit="return false;">
  <input type="submit" name="callPhone" onclick="callPhone();" value="着信あり">
</form>
```

**一向に電話は鳴りません。**

はて？と思いDevtoolsでコンソールを見ると以下のように表示されています。

`Uncaught TypeError: callPhone is not a function`

関数じゃない・・・？
よくいみがわかりませんでした。





# 色々試してみる
## 何が返ってきているのか
**関数じゃないなら何なんだ！**
ということで、まずは`console.log()`してみました。

```index.html
<!-- 略 -->
<input type="submit" name="callPhone" onclick="console.log(callPhone);" value="着信あり">
```

```コンソール.
<input type="submit" name="callPhone" onclick="console.log(callPhone);" value="着信あり">
```

自分自身が返って来ていました。
念のためinputのすぐ下に`<script>console.log(callPhone);</script>`を仕込みましたが、こちらは意図した通り`function()`が返って来ました。



## グローバルにアクセスしてみる
次に`callPhone()`はグローバルにしていたので、直接グローバルにアクセスしてみました。

```index.html
<!-- 略 -->
<input type="submit" name="callPhone" onclick="window.callPhone();" value="着信あり">
```

```コンソール.
ジリリリ...
```

**電話が鳴りました！**

つまり`callPhone();`だけだと、グローバルより前で発見されたと考えられます。`onclick属性`はこんな動作だったかな・・・？



## 要素を変更してみる
`input`タグから別の要素に変えてみます。

```index.html
<!-- 略 -->
<p onclick="callPhone();">着信あり</p>
```

```コンソール.
ジリリリ...
```

**電話が鳴りました！**

・・・

あ、name属性がいけないのかな？

```index.html
<!-- 略 -->
<p name="callPhone" onclick="callPhone();">着信あり</p>
```

```コンソール.
ジリリリ...
```

**鳴った！**

うーん、どうもinputの時だけ鳴らないようだ。



## inputでname属性を変えてみる
`input`タグのname属性を少し変更してみます。

```index.html
<!-- 略 -->
<input type="submit" name="callPhone_" onclick="callPhone();" value="着信あり">
```

```コンソール.
ジリリリ...
```

**鳴った！**

だんだん分かってきました。念のため**name="callPhone"**に戻してみると鳴らなくなりました。
> もちろんname自体を削除しても関数が実行されるようになります



## さらに色々試してみる
気になって色々と試してみると、以下のことが分かりました。

- `input`の他にも`select`、`textarea`、`button`など、いわゆるフォーム部品のタグで同じ挙動になった
- typeは関係無かった（textでもradioでも同じ）
- フォーム部品であっても、`<form>`外に配置すると一転、関数が実行されるようになった
- name属性だけでなく、idでも同じ挙動になった

以上のことから、`<form>`内の部品要素のnameやidと、onclick属性で呼び出す関数名が重複していると意図した関数が実行されない、との結論に至りました。





# 終わりに
しかし何でなんだろうなぁと思っていたところ、stackoverflowにズバリその答えが書いてありましたw

> Why JS function name conflicts with element ID?
> http://stackoverflow.com/questions/9158238/why-js-function-name-conflicts-with-element-id

簡単に言うと、チェインによりthis.formが自動的かつ優先的に、見つかっていたということのようです。
またstackoverflowでは、`onchange属性`について書かれているので、`onclick`だけでなく色んな**onXXXX**属性で発生しそうです（onclick以外は未確認です）。

```index.html
<!-- true -->
<input type="submit" name="callPhone" onclick="console.log(callPhone === this.form.callPhone);" value="着信あり">
```
ノウハウ・Tips を共有するためのノウハウ・Tips

# これは何？

この記事では、Qiitaに限らず様々な場面でノウハウやTipsを共有するときに役立つノウハウ・Tipsを紹介します。記事を分かりやすくまとめ、課題の解決を望む人たちにダイレクトに届く記事を仕上げるための一助となれば幸いです。

# 表明しておくとよいこと

記事を書く上では何かしらのコンテンツがあるはずですが、そのコンテンツが一体何なのかを説明しておくと、読む人がスムーズに話題を理解できるようになります。

## 前提を明らかにしておく

共有したいノウハウやTipsがどんなときに役立つかという情報は非常に重要なものです。問題が再現する環境、そもそもどんな問題に対して取り組んだのか、そしてその問題が何故困るのか、ということを目のあたりにするからこそ、ノウハウやTipsが活きた技術として活用できるようになりますし、それらの前提が異なればノウハウやTipsも変わってくることでしょう。

特に小技紹介やお悩み解決のような記事では、どういうところに効果があるのかを述べておくと、ノウハウやTipsを活かしやすくなります。

この記事でも、まず最初に`これは何？`としてどんなことに役立つかを明らかにしています。

## ノウハウ・Tips の真髄はタイトルにする

ひとことで言うとどんなノウハウ・Tipsであるかの説明をタイトルにすることで、記事にどんなことが書いてあるかが理解しやすくなります。
また、**何をどうしたのか**がシンプルにまとまっているとより良いタイトルになるでしょう。

## 記事を読むことによって得られるメリットを明らかにする

どんな問題を、どのように解決したのかということも重要ですが、**その結果どうなったのか**というのもまた重要な情報です。あるいは、その記事を読むことで**将来どうなることを目的とするのか**ということでも構いません。最終的なゴールがどこにあるかによって、ノウハウやTipsも変わってくるはずですから、そこを明らかにしておくことは、ノウハウやTipsを現場で活かす判断をする上で重要なことになります。

## 理由を明らかにする

どのような技術によってそのノウハウ・Tipsが支えられているのか、といったことや、なぜそのノウハウ・Tipsがうまく機能するのか、という点が明らかになることで、実際の場面で活用しようとした時の判断材料になります。もしかすると、微妙に前提条件や環境が異なっていたり、適用する理由として適当でない場面があるかもしれません。また、様々なトレードオフの関係にある物事を天秤に書けて、こういう理由・目的があるからA（またはB、Cなどの選択肢のうち一つ）を選択した、ということも有るでしょう。記事中に理由を表明しておくことで、どんな判断をするとよいのか、という一つの指針を作ることが出来るようになります。

# Markdown 記法を活用する

文章を構成するのに必要な要素は上記に並べてみましたが、文章をうまく整理することで、読みやすい文章を書くことができます。

## 見出しを活用する

`#` 記号を重ねることで、見出しに階層を作ることが出来ます。この階層を活用して、文章を階層構造に分解し、順序だてて並べると、スラスラと読みやすい記事になります。

また、見出しのタイトルはその見出しで解説している内容の要約になっていると、見出しを目次にしたときに、文章全体がどのようなことを話しているかがひと目で分かりやすくなります。

## リンクは言葉に貼る

URL をリストするだけの場合を除いて、引用や参考リンクを張る場合には、URL のみを貼り付けるのではなく、ある程度の手短な言葉や引用元・参考リンク先のタイトルを用いてその言葉にリンクを張るようにします。このようにすることで、リンク先に何が有るかが分かりやすくなります。

その意味では、「ここ」や「こちら」といった言葉にリンクを張るのは避けたほうが良いかもしれません。コードを参照する場合でも、どのコードのどのあたりかをリンクとして用いると分かりやすくなりますね。

## 長文記事には TL;DR なセクションを置く

2~3ステップくらいの手短なインストラクションで、何をどうすればどうなるのかを説明するだけのセクションがあると、読む人の理解が深まりやすくなるでしょう。その場合、以後の見出しとTL;DRのセクションの順番は一致させておくことが望ましいですね。

## まとめを用意する

最終的に何が大事だったのかをまとめましょう。最初に表明した概要と同じでも構いません。

# まとめ

ノウハウやTipsを共有する上では

- 大事な部分の要約をタイトルにする
- 前提条件をはっきり表明する
- 何故そのノウハウやTipsが役だったのか、どうしてその判断をしたのか、理由を述べる
- 実践した結果どうなったのかを明らかにする
- (可能ならば)他のやり方はあるか、あるとしたら何故それをしなかったのか理由を挙げてみる

が文章を構成する上で大事な要素になります。
また、これらをまとめる上では

- 見出しの構成をうまく分解して、階層構造を作る
- リンクを言葉に貼って参照先を分かりやすくする
- (必要ならば)TL;DR なセクションを用意して全体像を把握しやすくする
- まとめを置いて結局何が言いたかったのかを整理する

ことを意識すると、より読みやすい記事に仕上がることでしょう。

# 参考リンク

[いい記事を書くためのガイドライン - Qiita::Support](http://help.qiita.com/ja/articles/qiita-article-guideline)

# 最後に

[DroidKaigi 2016 はじまるよー！](https://droidkaigi.github.io/2016/)
Node.js で小規模なアプリケーションを開発する方法 その7

# はじめに
今回の投稿では全体の作業の流れと、それぞれの作業でどんなことをやるかの作業詳細について解説します。本来その1でやる内容なのですが、計画不足ですみません。

# 全体の流れ
全体の流れへ下記の通りです、なお既に仕様は確定しているものと仮定します。

- staticのセットアップ（済み）
- appのセットアップ（済み）
- HTMLのルーティング（済み）
- ページ仮作成
- appのモデル作成（済み）
- テストデータ作成（済み）
- APIのルーティング
- APIの仮組み
- staticのモデル作成
- セッションと認証管理の設定
- ページ作成

ページ仮作成を飛ばしてしまっていました、次回のその8ではViewの実装をやろうと思います。

# staticのセットアップ
staticのセットアップでは```webpack-dev-server```などをインストールし、クライアントサイドのJavaScriptのコーディングがスムースになるようにします。

- ```webpack_dev_server```, ```nodemon```, ```gulp``` のインストール
- ```gulpfile.js``` の追加
- ```webpack.config.js``` の追加
- ```package.json``` の編集
- HTML5 Boilerplate からファイルをコピー
- ```src/entry.js``` の追加
- .gitignore の追加

# appのセットアップ
appのセットアップでは```express```などのインストールとサーバ起動のスクリプト追加などにより、開発が開始できるようにします。

- ```express```, ```proxy-middleware```, ```serve-static```, ```morgan```, ```jade``` のインストール
- 開発用に```nodemon``` のインストール
- ```index.js```の追加
- ```bin/www```の追加
- ```package.json```の編集
- ```routes/pages.js```の追加
- ```views/layouts/default.jade```の追加
- ```views/pages/anonymous-home.jade```の追加

# HTMLのルーティング
HTMLのルーティングでは次の作業であるページ仮作成で作成されるページをどのURLに配置するを設定します。

- ```index.js```の編集
- ```routes/projects.js``` などの追加
- ```views/projects/admin-list.jade``` などの追加
- ```views/layouts/2-column/admin.jade``` などの追加

# ページ仮作成
ページ作成ではモックアップを作成します。何かとモックアップを作ると、どんなものが必要なのかが見えてくるので便利だなーと、自分は忘れっぽいので重宝しています。

- ```views/projects/admin-list.jade``` などの編集

# appのモデル作成
データベースに格納されるデータを設計します。

- ```sequelize```, ```sqlite3```, ```mysql``` をインストール
- 開発用に ```sequelize-cli``` をインストール
- ```sequelize init``` で ```models/index.js``` を追加
- ```models/project.js``` などの追加
- ```data``` ディレクトリの作成

# テストデータ作成
テストデータがあった方が動作確認が楽なのでテストデータを作成します。

- ```test/fixture/index.js``` の追加
- ```test/fixture/projects.js``` などの追加
- ```bin/sync``` の追加

# APIのルーティング
次の作業のAPIの仮組みで作成するAPIをどのURLに配置するかを設定します。

- ```index.js``` の編集
- ```routes/projects.js``` などの編集

# APIの仮組み
リソースに対するGET, POST, PUT, DELETEなど基本的なREST APIを実装します。

- ```routes/projects.js``` などの編集

# staticのモデル作成
フォームではValidationが必要になることが多いですが、これをクライアントサイド側だけでやりたいので、staticのモデルを作成します。

- ```static/src/models/project.js``` などの追加
- ```static/src/entry.js``` の編集

# セッションと認証管理の設定
ユーザのIDがないと保存できないテーブルなどもありますので、この段階でセッションを設定し、認証管理を行えるようにします。

- ```express-session```, ```connect-redis``` のインストール
- ```app/index.js``` の編集

# ページ作成
個々のページを実装していきます、だいたいが下記の繰り返しです。

- Viewの編集
- APIの追加と変更
- Routerの追加・編集
- Componentの作成

Componentとはクライアントサイドで使用するパーツのことを指しています。HTMLのWeb Componentと概念が近く、私が勝手にそう呼んでいます。

# おわりに
これまで無計画に進めてしまって読みづらい記事になってしまって恐縮ですが、これからはもう少し計画的に記事を書いていこうと思います。

次回は飛ばしてしまった作業である「ページ仮作成」についてご紹介します。
EcmaScript6のハマり記法問答集（変数編）


Reactで開発的なことをしてみたら、わりとReactそのものよりES6の記法的な質問がそれなりにあったのを感じたので雑多に問答集

# Q. `var`と`let`と`const`って何が違うの？
A. ざっくり言えばこう

```js
var a = "hoge" // もう忘れていい
let b = "fuga" // 変更できる値。mutable
const c = "baz" // 変更できない値。immutable
```
`var`に関しては、多分使うことはもう無いはず（と僕は思っている）。ESLintでも[no-var](http://eslint.org/docs/rules/no-var)というルールがあるので、設定しちゃっている。

# Q. `let obj = { hoge } `っていうこれなに
A. `{hoge}`は`{hoge: hoge}`となる。いわゆるシュガーシンタックス的なもの

こんな感じ。便利。

```js
let hoge = "fuga"

let obj = {
	hoge
}

console.log(obj) 
// { hoge: "fuga" }
```

# Q. `const { hoge } = obj`っていうこれなに
A. さっきの逆だと思っていい。`let hoge = c.hoge`と展開する。これは割りと他の言語にありがちな記法

```js
const { hoge } = obj

console.log(hoge)
// "fuga"
```

## 補足：さらにネストも展開できます。
これだとあんまり他の言語だと見ない（気がする）
そしてこの記事書いてる時に気づいたけど展開されるのは末端の要素だけのようだ

```js
let a = {
  b : {
    c : "d"
  }
}

let { b : { c } } = a
console.log(c) // "d"
console.log(b) // undefined
```


## 補足：関数の引数にも使えるのでこんなふうに組み合わせられる

```js
let fooFn = function({ hoge, fuga }){
	console.log(hoge, fuga)
}

fooFn({
	hoge: "aaa",
	fuga: "bbb"
}) 
// aaa, bbb
```
javascriptだとオプションとかをobject形式で渡すこと多いのでよくつかう。

## 補足：reactだったらこんなふうに利用する

```js
let foo = "baz"
let bee = "boo"
retrun <Cmp { ...{ foo, bee } } />
// <Cmp foo={foo} bee={bee} /> と同じ
```

### 補足の補足：↑の`{ ...{ a, b } }` こういうの何
`{a,b}`と一緒なのだけど、reactの記法上こう書くしか無い

```js
let a = 1
let b = 2
let c = { a, b }
let d = { ...{ a, b } }

console.log(c) 
console.log(d) 
// どっちもこうなる{ a: 1, b:2 }
```
詳しくは[Reactのドキュメント](https://facebook.github.io/react/docs/jsx-spread.html#spread-attributes)参照。ES7になったら改善しそう

# Q. `a = { [b] : c }`っての何

展開した変数をキーとして使えます。
使わないようでわりとあると便利。

```js
let b = "foo"
let a = { [b] : "baz" }
// a = { foo: "baz" }
```
border-radiusについて【trタグには効かないっぽい】

こんにちは。

今回は角を丸くする「border-radius」についてご報告させていただきます。


角がガッチガチの四角だとダサい！ってことで丸くしようとしたのですが・・・

なんと「td」タグではしっかり効くのに、「tr」タグだと丸くならない！


逃げるためには「tr」で色を指定して「td」で角を丸くするとかしないとダメですかねー
memcached内のKeyをリストする

[OpenStack HorizonでなぜかMemcachedが使われない場合の対処法](http://qiita.com/kentarosasaki/items/d241baa2721170637de2)

に加えて、Keyをリストする方法。

```
stats items
STAT items:16:number 3
STAT items:16:age 666
STAT items:16:evicted 0
STAT items:16:evicted_nonzero 0
STAT items:16:evicted_time 0
STAT items:16:outofmemory 0
STAT items:16:tailrepairs 0
STAT items:16:reclaimed 0
STAT items:16:expired_unfetched 0
STAT items:16:evicted_unfetched 0
END
```

`items:<id>:~`がSlubのIDになるので、

```
stats cachedump 16 100
ITEM :1:django.contrib.sessions.cachehzw3pa5nlvhl4pyaeifgvqgcvf5qgl0l [2369 b; 1445416629 s]
ITEM :1:django.contrib.sessions.cache23b5m3bd2ph914v1yey238qkjju6oy3d [2522 b; 1445416581 s]
ITEM :1:django.contrib.sessions.cachewv7dgbo4a1uyn3mljoed1xfvsh7f7zi9 [2448 b; 1445416081 s]
END
```

で先頭から100個分のKeyが出力される。
Caps Lockを左Ctrlにする（Windows）

https://technet.microsoft.com/ja-jp/sysinternals/bb897578.aspx

まさかのMicrosoft提供。

> 私を含め、UNIX から Windows NT に移行したユーザーは、標準的な PC 用キーボードでは CapsLock キーが存在する場所に Ctrl キーが存在することに慣れているので、このようなユーティリティは快適に編集するうえで不可欠です。

おっしゃる通りでございます。
ScrollViewに長い文字？を入れるとレンダリングがはみ出る問題の対応

## <Font color="red">追記（2016/01/26）</font>
以下のプロパティを設定することにより、オーバーレイ表示が解消する場合があります。
```IsClippedToBounds = true```
設定する箇所はScrollViewですが、ScrollViewだけに設定しても解消しない場合は、
ヘッダー部分やフッター部分にも同様に設定してみてください。

## 問題
タイトルのとおり、ScrollViewの中のLabelに大量の文字をバインドした結果、
ScrollViewの描画領域をはみ出して下のボタンの背景にまで文字がレンダリングされました。

言葉で説明しづらいですが、まんま下記参考URLのような現象です。

Xamarin.Forms ScrollView with long text
http://stackoverflow.com/questions/30369438/xamarin-forms-scrollview-with-long-text

ScrollView in Xaml
https://forums.xamarin.com/discussion/20945/scrollview-in-xaml

## 解決策
上記URLではStackLayoutをうまく調整するか、
Gridを使うということでしたが、どちらもうまくいきませんでした。
※Androidのみで確認です。

最終的にScrollViewの使用をやめて1行のみのListViewにすることで解決しました。
※ListViewにはもともとスクロール処理が実装されています。

なおこのまま利用すると、スクロール領域をタップしたときに背景色が青く（Androidだと）なってしまいます。
Xamarin.Formsでは選択時の色を変更するにはカスタムレンダーを利用するしかありません。

下記のようなコードを書けば選択時の色の変更がされなくなります。

## コード
カスタムViewCell

```
using Xamarin.Forms;

namespace MyProject.Controls
{
    public class CustomViewCell : ViewCell
    {
        public static readonly BindableProperty BackgroundColorProperty = BindableProperty.Create<CustomViewCell, Color>(i => i.BackgroundColor, default(Color), BindingMode.OneWay);

        /// <summary>
        /// 背景色を取得または設定します。
        /// 選択時の色も同時に指定されます。
        /// </summary>
        public Color BackgroundColor
        {
            get
            {
                return (Color)this.GetValue(BackgroundColorProperty);
            }
            set
            {
                this.SetValue(BackgroundColorProperty, value);
            }
        }
    }
}
```

カスタムViewCellのレンダラー

```
using Android.Content;
using Android.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using View = Android.Views.View;
using MyProject.Controls;

[assembly: ExportRenderer(typeof(CustomViewCell)
    , typeof(MyProject.Droid.Renderer.CustomViewCellRenderer))]
namespace MyProject.Droid.Renderer
{
    public class CustomViewCellRenderer : ViewCellRenderer
    {
        protected override View GetCellCore(Cell item, View convertView, ViewGroup parent, Context context)
        {
            View cellcore = base.GetCellCore(item, convertView, parent, context);

            var cell = item as CustomViewCell;
            cellcore.SetBackgroundColor(cell.BackgroundColor.ToAndroid());

            return cellcore;
        }
    }
}
```

CustomViewCellクラスはViewCellクラスにBackgroundColorプロパティを追加しただけのものです。
カスタムレンダラーでは、BackgroundColorプロパティに設定されている色を上書きしているだけです。
Atomでファイルを読み書きするパッケージを作る際にUTF-8以外の文字コードにも対応する方法メモ


## 結論

ファイルの読み書きをする際に[Fileクラス](https://atom.io/docs/api/v1.1.0/File)を使い`setEncoding`で適切な文字コードを指定しましょう、以上。

## 蛇足

[TextEditor](https://atom.io/docs/api/v1.1.0/TextEditor)であればCore Packagesの[encoding-selector](https://atom.io/packages/encoding-selector)でよしなに設定できるので問題ないが、例えば[Tablr](https://atom.io/packages/tablr)のように独自の編集画面を作りファイルの読み書きをする場合は自身で文字コードを適切に処理する必要がある。
（なお、例に挙げたTablrは文字コードの処理を行っていないためUTF-8なCSVしか扱えない）

*2016/01/18 Update*
Tablr 0.10.0より文字コードの処理が入り、UTF-8以外の文字コードであっても扱えるようになった。

[node-pathwatcher/file.coffee at master · atom/node-pathwatcher](https://github.com/atom/node-pathwatcher/blob/master/src/file.coffee)の`readSync`と`writeFileSync`の実装を見ると以下のようになっている。

```coffeescript
  readSync: (flushCache) ->
    if not @existsSync()
      @cachedContents = null
    else if not @cachedContents? or flushCache
      encoding = @getEncoding()
      if encoding is 'utf8'
        @cachedContents = fs.readFileSync(@getPath(), encoding)
      else
        iconv ?= require 'iconv-lite'
        @cachedContents = iconv.decode(fs.readFileSync(@getPath()), encoding)

    @setDigest(@cachedContents)
    @cachedContents

  writeFileSync: (filePath, contents) ->
    encoding = @getEncoding()
    if encoding is 'utf8'
      fs.writeFileSync(filePath, contents, {encoding})
    else
      iconv ?= require 'iconv-lite'
      fs.writeFileSync(filePath, iconv.encode(contents, encoding))
```

ここの`getEncoding`で取得している文字コードは`setEncoding`でセットした文字コードであるため、実際にファイルを読み書きする前に文字コードのセットが必要となる。
文字コードの変換には[iconv-lite](https://github.com/ashtuchkin/iconv-lite)を使っていることから、iconv-liteで対応できる文字コードであればFileクラスを使い適切な値を`setEncoding`で指定してやれば読み書きの際に変換のことを考える必要はなくなる。

## 文字コードの自動判定をしたい場合

残念ながらFileクラスには文字コードの自動判別処理が入っていない。
encoding-selectorには文字コードの自動判別処理が実装されているが、外部からこれを利用する方法はないため自前で実装しなければならないようだ。

```coffeescript
  detectEncoding: ->
    filePath = @editor.getPath()
    return unless fs.existsSync(filePath)

    jschardet = require 'jschardet'
    iconv = require 'iconv-lite'
    fs.readFile filePath, (error, buffer) =>
      return if error?

      {encoding} =  jschardet.detect(buffer) ? {}
      encoding = 'utf8' if encoding is 'ascii'
      return unless iconv.encodingExists(encoding)

      encoding = encoding.toLowerCase().replace(/[^0-9a-z]|:\d{4}$/g, '')
      @editor.setEncoding(encoding)
```
Unity対応mBaaSサービス比較(2015年11月)

いわゆる内部メモですが、公開することによって広がりがあったりするのか、あるいは需要があるのかを知るためにアップしてみました。

#必要な要件

## データホスティング
* ステージデータなどのAssetBundleの配信
* ユーザー認証によるアクセスコントロールが可能なことが望ましい

## データAPI
* マスターデータ
* ステージデータ
* APIアクセスコントロール
* 管理者
* ゲームからのアクセスのみ許可

## アナリティクス
* リアルタイム
* コホート解析
* ファンネル

## Push Notification
* 予約配信
* セグメント指定配信
* 開封率チェック

## クラッシュレポート
* クラッシュ時にログを送信、コンソールからチェックできる

# 候補

## ワンストップ
* Amazon Mobile SDK
* Fabric
* Parse
* ニフティクラウド http://goo.gl/CYQ1FX
* GMOアプリクラウド https://goo.gl/WfLBVs

## 単機能
### アナリティクス
* Google Analytics for Mobile
* Unity Analytics
* Analytics | Flurry - http://goo.gl/DFxDoP
* GameAnalytics - http://goo.gl/NaK14

### ホスティング

### データAPI

### Push Notification
* Amazon SNS

# 費用での比較
* 100MBあたりの転送単価
* Push Notificationの単価
* リクエスト数あたりの単価

## ファイルストレージ
### Amazon S3 (クラウドストレージサービス Amazon Simple Storage Service) | アマゾン ウェブ サービス（AWS 日本語） https://aws.amazon.com/jp/s3/pricing/
* 転送料: 10 TB まで/月　$0.140 /GB = 100MBのアセットダウンロードに付き1円
 
### Parse https://parse.com/plans
* 転送料金: 2TBまでフリー。$0.10/GB

## Push Notification
### Parse https://parse.com/plans
* 100万"recipients"まで無料。recipientはユニークな端末の数。同一端末への複数のPush送信は「1」としてカウントされる。 https://parse.com/plans/faq
* $0.05 / 1000 ユーザー？
### Amazon SNS https://aws.amazon.com/jp/sns/pricing/
* 100万件まで無料
* 追加100万件あたり0.5ドル

## REST API
### Amazon API Gateway https://aws.amazon.com/jp/api-gateway/pricing/
* 100 万回の API 呼び出しの受信につき 3.50 USD
* 最初の 10 TB につき、0.09 USD/GB
*  キャッシュ: メモリサイズ 「0.5 GB」に付き「0.020 USD/Hour」 
### Parse 
* 30req/secまで無料

# 機能での比較

### アナリティクス
|| Unity | Parse | Game Analytics |
|:-------|:------|:------|:------|
| リアルタイム解析|||○|
|コホート解析||
|ファンネル解析||

### データAPI
||Unity| Parse | Amazon AWS |
|:-------|:------|:------|:------|
|データエディタ| ALPHA |○||
|APIサーバー機能| ALPHA |○|○|

### ホスティング
|| Parse | Amazon AWS |
|:-------|:------|:------|
|ファイルホスティング|○|○|

### Push Notification
|| Parse | Amazon AWS |
|:-------|:------|:------|
|ファイルホスティング|○|○|

### ファイルサイズ200MBバイト程度

# ユースケース
* 離脱率を調べる
* 離脱者がどのステージで離脱しているかを調べる
* ステージの難易度を調整する
* どのステージで何%のユーザーが離脱しているか
* ゲームオーバー時に広告を開いてコンティニューしたユーザーの割合を調べる
* ゲームオーバーの回数を調べる
* ゲームオーバーと離脱の関係を調べる
Raspberry Piの内蔵オーディオデバイスを無効化する方法

## TL;DR

内蔵オーディオデバイス全体を無効化するには、`/etc/modules`の`snd_bcm2835`をコメントアウトすればOK。

## 内蔵オーディオデバイス全体を無効化する方法

デバイスドライバを読み込まないようにすることで無効化できます。
具体的には`/etc/modules`に含まれている`snd_bcm2835`をコメントアウト（先頭に#を付加）し、再起動することで無効化できます。

```
root@volumio:~# lsmod | grep bcm2835
snd_bcm2835            21342  1
snd_pcm                93100  2 snd_bcm2835,snd_usb_audio
snd                    67211  11 snd_bcm2835,snd_usb_audio,snd_hwdep,snd_timer,snd_pcm,snd_seq,snd_rawmidi,snd_usbmidi_lib,snd_seq_device

root@volumio:~# cat /etc/modules
snd_bcm2835

root@volumio:~# vi /etc/modules

root@volumio:~# cat /etc/modules
#snd_bcm2835

root@volumio:~# reboot
```

## HDMIへのオーディオ出力を無効化する方法

`/boot/config.txt`の`hdmi_drive`を変更することで無効化できるらしいですが、未確認。
公式サイトに詳しい記述があります。

[config.txt - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/configuration/config-txt.md)

## 無効化の背景

[Volumio](https://volumio.org/)という音楽再生に特化したLinuxディストリビューションがあります。
Raspberry Pi用のイメージも存在し、とても手軽に導入することができます。
しかし、このシステムでは、サウンドデバイス（サウンドカード）の指定にデバイス番号が使われており、USBスピーカーなど、取り外し可能なオーディオデバイスを使った場合に、デバイス番号が一定にならない問題があります。（デバイス名で識別してくれたらいいのに・・・）

そのため、内蔵オーディオデバイスを無効化することで、デバイス番号0が外部オーディオデバイスになるように暫定的に対処しました。
なお、Volumio 1.55での話であり、今後は改善される可能性があります。
IEnumeratorを待つのにStartCroutine()とMoveNext() + Currentの違いを検証

## 調べたこと
UnityでIEnumerator()を待つ場合、StartCoroutineを使う方法とMoveNext()メソッドとCurrentプロパティを使う方法がある。
2種類の書き方にはどんな違いあるか気になったので調べてみた。

## 検証コード
```csharp
using UnityEngine;
using System.Collections;

public class IEnumeratorBehavior : MonoBehaviour
{
    const int count = 3;

	void Start ()
    {
        Debug.Log("start");
        StartCoroutine(test1());
        StartCoroutine(test2());
    }

    void Update ()
    {
        Debug.Log("update");
    }

    IEnumerator test1()
    {
        yield return StartCoroutine(ie("test1"));
    }

    IEnumerator test2()
    {
        var e = ie("test2");
        while (e.MoveNext())
        {
            yield return e.Current;
        }
    }

    IEnumerator ie(string s)
    {
        for(int i=0; i<count; ++i)
        {
            Debug.LogWarning(s + " " + i);
            yield return null;
        }
    }
}
```

## 実行結果
![result.jpg](https://qiita-image-store.s3.amazonaws.com/0/39587/92575477-0c7e-3cd8-5241-969ddb4daf93.jpeg)
Unity 5.2.1p4で確認

## 結論
どっちも挙動は変わらなかったから短く書ける StartCoroutine() の方が良さげ

実行結果を見て「おや、出力順はなんでこうなる…」と思われた方は以下の「イベント関数の実行順」もご参考ください。
http://docs.unity3d.com/ja/current/Manual/ExecutionOrder.html
postfixで同時送信件数を絞る

## 参考

* [UNIXサーバメモメモ - 制限の設定](http://unixservermemo.web.fc2.com/sv/postfix-maincf-seigen.htm)
* [postfixでメール送信制限 その３ - Wat’s up Dude?](http://d.hatena.ne.jp/chiyotsu/20100909/1284017245)

## 同時送信件数を絞る

* local_destination_concurrency_limit : 同じローカル受信者に対して同時に配送するメッセージの数
* smtp_destination_concurrency_limit : 同じ接続先に対する同時接続数
* smtp_destination_recipient_limit : 1セッションの最大宛先数

```bash:/etc/postfix/main.cf
local_destination_concurrency_limit=1
smtp_destination_concurrency_limit=1
smtp_destination_recipient_limit=1
```
hjklをMacのカーソルキーにする

**カーソルキーなんてキーボードから消えてしまえ！**と心の中で思っているvi使いは多いと思います。

エディターならvim
PHPな開発環境なら PHPStorm + IdeaVim
Androidな開発環境なら ADT + Vrapper
iOSな開発環境なら Xcode + XVim
ブラウザなら Firefox + vimperator
bashなら set -o vi

とアプリごとに対応するわけですが、いっそOSワイドにカーソルキーを置き換えたいと考えるのは自然な流れです。

そんな時にありがたいのがBetterTouchToolです。

ここからダウンロードできます。
http://www.bettertouchtool.net/

<img width="400" alt="Screen Shot 2015-11-04 at 16.31.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/74328/7969fde8-4286-79b5-e774-f7aa8b407395.png">

私の場合、SHIFT + COMMAND + hjkl がカーソルキー代わりになるよう設定しています。


良いvi + Mac ライフを！
Rails4のdevise3.5.xのENV['DEVISE_SECRET_KEY']について

# はじめに

この記事はrails4におけるdevise v3.5.xでのENV['DEVISE_SECRET_KEY']の有無について書いたものです。

## 確認済み環境

```rb
gem 'rails', '4.2.4'
gem 'devise', '3.5.1' # '3.5.2'も
```

# DEVISE_SECRET_KEYは指定必須か？

ENV['DEVISE_SECRET_KEY']を定義してる時と、ミスって定義し忘れた場合も変わらず正常に動いていたので、指定必須じゃないの？どーなってんの？と思ったのが事の発端。

```
補足：
DEVISE_SECRET_KEYとは、config/initializers/devise.rbに下記の様に、誰かが書き始めたことによって稀に検索される環境変数名。

config.secret_key = ENV['DEVISE_SECRET_KEY']

```

## 結論

DEVISE_SECRET_KEY（ or config.secret_key）は指定してもしなくてもいい！

deviseの挙動としては、下記の様になってると言っているので、

```rb
Devise.setup do |config|
  # ENV['DEVISE_SECRET_KEY']が未定義なら、ENV['SECRET_KEY_BASE']を利用する
  config.secret_key = ENV['DEVISE_SECRET_KEY'] || ENV['SECRET_KEY_BASE']
end
```
production環境でもSECRET_KEY_BASEさえ設定されていれば後は気にしなくていい。

# 確認方法
下記を実行すると、

```
$ bundle exec rails g devise:install
```

`config/initializers/devise.rb`が生成され、

そこに真理が書かれてた。

```ruby
Devise.setup do |config|
  # The secret key used by Devise. Devise uses this key to generate
  # random tokens. Changing this key will render invalid all existing
  # confirmation, reset password and unlock tokens in the database.
  # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
  # by default. You can change it below and use your own secret key.
  # config.secret_key = '5b82d6c79aa93c1b06...'

  # 基本的にはRails4+のsecret_key_baseを再利用するんだけど、
  # deviseのconfig.secret_keyを定義した場合は、そっちを優先的に使うよ。
  #..
end
```

# まとめ



結果、DEVISE_SECRET_KEYが未定義の場合は、railsのSECRET_KEY_BASEを再利用するんだとわかり、取り敢えずスッキリ。
TransmitMail 2 のカスタマイズ例のリンク集

[TransmitMail 2](https://github.com/dounokouno/TransmitMail) のカスタマイズ例をいくつか Qiita に書いたので、そのリンク集です。

# TransmitMail とは

拙作（ @dounokouno 作）の Copyright 表示不要のオープンソースメールフォームシステムです。

# カスタマイズ例

- [TransmitMail 2 の送信メールの件名に POST パラメータを利用する - Qiita](http://qiita.com/dounokouno/items/c1b3d8a043560e785ce8)
- [TransmitMail 2 で入力内容に応じて送信メールの宛先を切り替える - Qiita](http://qiita.com/dounokouno/items/21dcf87f2e43a73be551)
- [TransmitMail 2 に「存在する日付の判別」機能を追加する - Qiita](http://qiita.com/dounokouno/items/4014dee5bdb2b8c7d1e1)
- [TransmitMail 2 で入力内容を MySQL に保存する - Qiita](http://qiita.com/dounokouno/items/a51a1226dafc98ab5665)
- [TransmitMail 2 で入力内容を Google スプレッドシートに保存する - Qiita](http://qiita.com/dounokouno/items/01561521e1f9d4cd49b3)
Fragment/View 中でどの Activity から利用されているか判定する


## Fragment の場合

`getActivity()` で Activity への参照を取得し `getLocalClassName()` メソッドでクラス名(文字列)を取得します。

```java:
Activity activity = getActivity();
if (activity != null) {
    Log.i("foo", activity.getLocalClassName());
}
```

あとはクラス名(文字列)を利用して `if` や `switch` 文で条件分岐すれば。

## View の場合

`<Viewのインスタンス>.getContext()` で Activity への参照が取得できるので、あとは上記と同じです。

```java:
Activity activity = (Activity) mFooViewInstance.getContext();
if (activity != null) {
    Log.i("foo", activity.getLocalClassName());
}
```

## ほか

`switch` 文でうまく扱えないですが、それでもいいなら `instanceof` で判定してもよいかと思います。文字列でないのでクラス名の変更に強い。

```java:
if (activity instanceof FooActivity) {
	//...
}
```
現在Swift学習の欲しい機能一覧。

データ保存。

APIからとってきたデータをAviewからBviewに渡す。
Aに存在するデータをお気に入りデータとしてBに渡す。

##ここでデータの保存を簡単に学ぶ
http://easyramble.com/swift-todo-app-tutorial.html

##二つのView間で値の受け渡しをする場合を学ぶ。
http://swift-ios.keicode.com/ios/passing-values-between-views.php

##AppDelegateを用いて画面間のデータ受け渡し

http://qiita.com/xa_un/items/814a5cd4472674640f58

##Magical Recordの学習 全編 ♡
http://applewatchjournal.net/development/1085

##Swift + MagicalRecord
http://bundlr.com/clips/538e569809359743040000c0

http://ai-future.hatenablog.jp/
TransmitMail 2 で入力内容に応じて送信メールの宛先を切り替える

[TransmitMail 2](https://github.com/dounokouno/TransmitMail) で入力内容に応じて送信メールの宛先を切り替えるカスタマイズ例をご紹介します。

# 開発および動作確認環境

開発および動作確認環境は下記の通りです。

- TransmitMail: 2.0.0
- PHP: 5.6.10

# `input.html` に入力フィールドを追加する

`input.html` に下記のような入力フィールドを追加します。

```html:input.html
<table>
    <tr>
        <th>お問い合わせ内容</th>
        <td>
            <select name="お問い合わせ内容">
                <option value="利用方法について" {$selected.お問い合わせ内容.利用方法について}>利用方法について</option>
                <option value="資料請求" {$selected.お問い合わせ内容.資料請求}>資料請求</option>
                <option value="その他" {$selected.お問い合わせ内容.その他}>その他</option>
            </select>
        </td>
    </tr>
</table>
```

# `config.yml` を修正する

`config/config.yml` に「利用方法について」と「資料請求」の場合のメール送信の宛先を追加します。

```yaml:config/config.yml
config:
    to_email: info@example.com
    to_email_support: support@example.com
    to_email_material: material@example.com
```

# `exTransmitMail.php` を作成する

`TransmiMail` クラスを継承した `exTransmiMail` クラスを `lib/exTransmitMail.php` に作成します。

```php:lib/exTransmitMail.php
<?php
class exTransmitMail extends TransmitMail
{
}
```

# `exTransmitMail` クラスに機能を実装する

メール送信の前の処理となる `afterSetTemplateProperty` メソッドを追加し、そこに処理を書いていきます。（ `afterXXX` メソッドについては [Wiki](https://github.com/dounokouno/TransmitMail/wiki/TransmitMail-%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E5%90%84%E5%87%A6%E7%90%86%E3%81%AE%E5%AE%9F%E8%A1%8C%E9%A0%86%E7%95%AA%EF%BC%88v2%EF%BC%89) をご参照ください。）

```php:lib/exTransmitMail.php
/**
 * メール送信の前の処理
 */
public function afterSetTemplateProperty()
{
    if ($this->page_name === 'finish') {
        switch ($this->post['お問い合わせ内容']) {
            case '利用方法について':
                $this->config['to_email'] = $this->config['to_email_support'];
                break;
            case '資料請求':
                $this->config['to_email'] = $this->config['to_email_material'];
                break;
            case 'その他':
            default:
                // 「その他」または選択がない場合は to_email 宛にメールを送信するので、ここでは特に何もしない
                break;
        }
    }
}
```

# `index.php` を修正する

`index.php` に `lib/exTransmitMail.php` の読み込みと `TransmitMail` クラスではなく `exTransmitMail` クラスを利用するように修正します。

```php:index.php
<?php
require_once 'lib/TransmitMail.php';
require_once 'lib/exTransmitMail.php';
$tm = new exTransmitMail('config/config.yml');
$tm->run();
```

# 動作確認

「お問い合わせ内容」によってメールの宛先が切り替わることが確認できました。

# まとめ

以上、TransmitMail 2 で入力内容に応じて送信メールの宛先を切り替えるカスタマイズ例をご紹介でした。こんな感じでカスタマイズすることで、TransmitMail本体には手を加えずにカスタマイズすることが可能です。

今回のカスタマイズのコードは下記ブランチで公開をしています。

[dounokouno/TransmitMail at example_branch_of_email](https://github.com/dounokouno/TransmitMail/tree/example_branch_of_email)

修正ファイルは下記のコミットをご参照ください。

[入力内容に応じて送信メールの宛先を切り替えるカスタマイズ例 · dounokouno/TransmitMail@6f205db](https://github.com/dounokouno/TransmitMail/commit/6f205db45650a37b135da1edb6cca894d9d7f036)
git submoduleでhttpsとsshを使い分ける（仮）

git submoduleを使っていて、私は普段からずっとgitにsshしかつながないのでこうしてました。

```
git submodule add git@example.com:example/example.git
```

で、しばらくして、他の人に「``git clone --recursive``できないんだけど？」と言われて、そんなバカなと思って見てみると、その人はhttpsでつないでました。
で、鍵認証が通らないので"Permission denied (publickey)"で死んでました。

さてどうしたものかな、と。

* https（ユーザー名＆パスワード方式）に切り替えるのは安全性の観点から避けたい（少なくとも自分は）。
* でも、他人にsshでつなぐことを強要するのも難しい（[githubなんかはhttpsを推奨しているみたい](https://help.github.com/articles/which-remote-url-should-i-use/)ですし）

ということで、なんとかプロトコルだけ切り替える方法ないかなと思って探してたんですが、そういえばと思って[boost](https://github.com/boostorg/boost/blob/master/.gitmodules)を見てみたら、なんとsubmoduleのURLに相対URL使えたんですね！
なので、以下のようにすれば解決しました。

```
git submodule add ../example.git
```

しかし問題はこの方法だと、相対URLで指定できないような場所（サーバーごと違うとか）のsubmoduleは、どうしようもないってことですね。
そういう場合の使い分け方法は・・・見つけたら追記します（orご存じの方いたら教えて下さい）。