OmniAICreator/Qiita-1.07M huggingface dataset:
sails.jsでログをカスタマイズしてファイルに出力する

最近sails.jsで一つプロジェクトを回してみたので、そこで得たことをまとめてみる。まずはログ周り。以前ちょっとログをSlackで飛ばしてほげほげする感じのものを投稿していたが、今見返してみると微妙だったので実際どんな感じで実装したのかという話。今回はログをファイルに出力する。

# 実装
ログモジュールはnpm化して再利用するようにしている。あまり大したことはしていないので、index.jsだけ貼る。

```js:index.js
var winston = require('winston');

// Date Formatter
function now() {
  var zeroPadding = function(target) {
    return ('0' + target).slice(-2);
  }

  var now = new Date();
  var date = now.getFullYear() + "-"
    + zeroPadding(now.getMonth() + 1) + "-"
    + zeroPadding(now.getDate());
  var time = zeroPadding(now.getHours()) + ":"
    + zeroPadding(now.getMinutes()) + ":"
    + zeroPadding(now.getSeconds());

  return date + "T" + time + "+09:00";
}

module.exports = function(opt) {
  var system = opt.system || 'node app';
  var subSystem = opt.subSystem || '-';
  var version = opt.version || 'Unknown Version';
  var host = opt.host || 'Unknonw Host';
  var level = opt.level || 'debug';
  var path = opt.path || './.tmp/test.log';
  var toConsole = opt.toConsole || true;
  var environment = opt.environment || 'development';

  return new winston.Logger({
    transports: [
      // 今回はファイルに出力するのでwinston.transports.Fileを指定
      new (winston.transports.File)({
        level: level,
        filename: path,
        json: false,
        formatter: function(args) {
          // デバッグ中にはコンソールでも見たい。そんなときはconsole.log()で無理やり表示
          if (toConsole) {
            console.log(args.message);
          }

          // この辺りのデリミタはプロジェクトで適当に決めると良い
          var header = now() + " " + args.level.toUpperCase();
          var app = ' ' + system + ' ' + subSystem + " " + version + ' ' + environment;
          var msg = args.message;

          return header + ' ' + app + ' ' + host + ' ' + msg;
        }
      })
    ]
  });
}
```

これを`config/log.js`で読み込む。

``` js:config/log.js
// ここで先ほど作ったnpmを読み込む
var myLog = require('my-log');

module.exports.log = {
  // colorsはfalseにしておいたほうが別システムでログを解析するとき楽。
  // productionのみfalseでもいいけど。
  colors: false,

  level: 'info',

  // customで先ほど作成してモジュールを指定
  custom: seleckLog({
    system: 'TEST',
    subSystem: 'app',
    version: require('../package.json').version, // package.jsonのバージョン
    environment: process.env.NODE_ENV,
    host: require('os').hostname(),
    path: '/var/log/TEST/app.log'
  }),
};
```

これで指定したパスにログが出力されるはず。

# 使い方
`sails.log.xxx`を使う

```
sails.log.error("hogehoge");
```
最小構成のzshrc


```bash:~/.zshrc
# 自動補完を有効にする,プロンプトカラーを有効にする
autoload -U compinit promptinit
compinit
promptinit

# プロンプトに現在地を表示できるようになる
prompt walters

# Tab、矢印キーなどを使って補完候補を視覚的に選択できるようになる
zstyle ':completion:*' menu select

# cdした時に同時にコマンド、lsを実行する
function chpwd() { ls -aCFG }

# エイリアスで自動補完を切り替える
setopt completealiases

# 重複した履歴を残さない
setopt HIST_IGNORE_DUPS
```

補完候補は、デフォルトでもLinuxの場合は`/usr/share/zsh/{site-function,function}`以下あたりが設定されていると思います。`echo $fpath`で確認できます。`zsh`に限らず便利なスクリプトとかもあるので、`/usr/share`, `/usr/local/share`に相当するフォルダは覗いておくと良いかもしれません。

初心者なのでよくわかっていません。便利な設定があったらぜひ教えて下さい。
Linuxデスクトップでキーバインドを自由に設定する方法


Linuxデスクトップには、その多くに`GTK2.0`, `GTK3.0`が使われていることが多いです。私が使用しているAwesomeもGTK2.0を使っています。

そして、多くの包括的ツールにおいて言えることですが、テーマを設定できることが少なくありません。具体的には、ファイルマネージャーやデスクトップ、ログインマネージャーなどですね。

今回の例で言うと、例えば、GTK2.0にEmacsのキーバインドを設定することができます。

ユーザーに設定するには`~/.gtkrc-2.0`を編集します。

```:bash
include "/usr/share/themes/Emacs/gtk-2.0-key/gtkrc"
binding "gtk-emacs-text-entry"
{
   bind "<alt>BackSpace" { "delete-from-cursor" (word-ends, -1) }
}
```

Emacsのキーバインド設定は、`/usr/share/themes/Emacs`に置いてあるので、そちらを読みこめばよいです。あと、自分で書きたい場合は、include以下のような感じで書いていきます。

そういえば、ChromiumでC-wのキーバインドで単語削除、タブ閉じるを行うのもこの設定でできます。もちろん、ウィンドウマネージャーによって設定ファイルの書き方は異なってくるため、上記設定はあくまでGTK2.0のみ有効なわけですが。あと、GTK3.0も同じような感じですが、多少書き方は異なるかもです。
Apple WatchKit もくもく勉強会 #6 に参加してきました

# はじめに
* 5月24日(日)に開催されたAppleWatch勉強会に参加してきました
    * イベント
        * https://coedo-dev.doorkeeper.jp/events/24584
    * 関連サイト（公開グループ AppleWatch WatchKit Developers Japan）
        * https://www.facebook.com/groups/944846408876597/

# やったこと
* 利用方法の検討
    * 概要
        * 購入して1ヶ月経過した者同士での利用方法の意見交換
    * そのとき出た意見たっけー
        * 小さなボタンは押せない。押させてもボタンは1つだけくらいにした方が良さそう
            * シミュレーションの段階では、小さいボタンを電卓のように付けたりしてた
        * スクロール付きも使いづらそう。よっぽどのものじゃないとスクロールしない 
        * グランス（見るだけ）の使い方がメインになると思う
            * **どう見せるかが問題**
        * 既存で一番利用価値が高いアプリは、Passbookだと思う
* AppleWatchアプリ間でのデータ交換
    * App Groupsを使用してAppleWatchにデータを引き渡すサンプルを作成
    * App GroupにID登録
        * ![00.0524-appw-appg.jpg](https://qiita-image-store.s3.amazonaws.com/0/44076/dd67520e-c8c8-5f9d-07e0-603062713a33.jpeg)
    * App Groupに登録したIDを設定した2つのアプリ（1つは、AppleWatch拡張アプリ組み込み）を作成
        * ![01.0524-appw-main.jpg](https://qiita-image-store.s3.amazonaws.com/0/44076/8cbe9813-4602-783e-87f6-782ef68ec5db.jpeg)
    * それぞれのアプリからデータを設定してAppleWatchから取得
        * ![02.0524-appw-ap01.jpg](https://qiita-image-store.s3.amazonaws.com/0/44076/6be71e1c-a79e-2b79-b165-e95b83fef094.jpeg)
        * ![03.0524-appw-ap02.jpg](https://qiita-image-store.s3.amazonaws.com/0/44076/cda072d3-dcf5-9377-23d9-0dece2c977be.jpeg)
* その他
    * オリンパスのwifiカメラ開発している人が参加していた
        * http://japanese.engadget.com/2015/03/16/air-a01-3-25-sdk/
    * AppleWatchのラバーバンドは工夫してる
        * バンドの端がふつうのバンドの様に外に出て邪魔にならないようにしている（そういう事だと知らなかったｗ）
    * 新Macbook(金)持ってきている人が居た
        * キーの沈み込みは少ないけどちゃんとタイプ感がある。ボタン広めでタイプミスが慣れるまで多そう。
        * トラックパッドが思ったより広くなってった
        * りんごマークが点灯しないのはデグレ？ｗ
    * 次回勉強会の帯に私が写ってますｗ
        * http://qiita.com/maruo2/items/cdee8ecf149f5f791227

# まとめ
* AppleWatchは、使用方法がまだ未知数。ネイティブアプリ開発SDKが気になるところ。
* 最新デバイスに興味がある人達の集まりなので、自然と最新機器を扱う人たちが集まって意見交換がとても勉強になります。
* もくもく勉強会は、時間が長くて腰を落ち着けて作業や話し合いが出来るのでとても良いと思います。
Struts1.3.10が倒せない

ドーモ、Struts=サン。Dragothです。　Struts殺すべし、慈悲は無い。
書きかけです。

#やらかしてた
「1.3.10」です。「1.310」と入れてたので修正。


#書き始めたいきさつ
仕事の都合でStruts1.3.10について学ぶことになったはいいものの、
資料があっても古い上に、新しい日本語の資料がほぼ、いや、まったくといっていいほどない。
Web上の使い方は書き方バラバラだったり書いても動かなかったりでひたすらに苦労する。
会社に教えてくれる人もいないので独学になるが、どうしていいのか分からない。
なのでとりあえず現状色々集めた知識をまとめておいておきつつGithubも生かして教えてもらえたらな、というところから。
色々集めた知識の集積と現状の理解の整理として書いていきます。
いまだにStrutsにおけるハローワールド相当のフォーム作成が全うに動かない初心者なので、突っ込みや暖かいご指摘をお願いします。
ソースコードは後程GitHubにて上げていきます。
最終的にはまとめて現行で使えるStruts記事にできたらいいなぁと思います。

#何が知りたいか
Web3.0、現行のJava基盤で動くWeb.XMLを使わない形でのStrutsの使い方を覚えたい。

#現状の理解から書いてみる
まず、基礎となるのはJSPとサーブレットの知識。
全体的に網羅していないと歯が立たない。(doGetメソッドの使い方など。)
スッキリわかるサーブレット・JSPなど読むべし。コレでも足りないかもしれない。

そして、StrutsはModel-View-Controllerモデルに沿って作られたフレームワークであり、
StrutsはControllerの部分に相当するものである。

現状においてStrutsは既にEOL（サポート切れ）を迎えているが、
いまだになんだかんだで使用されている企業は多い。
なので最低限でいいので使えるようになっておかねばならない。~~いい加減に死ねばいいのに~~

そして、javaの＠WebServletアノテーション使用の場合の基本的な作成の流れとしては、

index.jsp編集→JSP・アクションクラス作成→Struts-Config.XML編集→Web.XML編集(taglib要素編集)

の流れを繰り返すことになる。

＠Webservletアノテーションを使用すれば、
XML内部に記載する.do等の属性を記載しないで済む、らしい。
こうすることでXMLが内部でこんがらがることを極力防ぎつつ進めていくことが大事。
3.0でも2.X系の書き方は可能だが、今の段階ではレベルが高いかもしれない。
極力現行最新でやりやすいやり方学んでからでも遅くないだろうと思う。

サーブレット仕様3.0とStruts1.3.10があり、別々に策定されている。
＠ITさんの記事が詳しい。サーブレット仕様の現行は3.1だが十分役に立つ。
http://www.atmarkit.co.jp/ait/articles/1104/12/news134.html


~~というかいっそこれ勉強対象を1.2.9に先祖返りしたほうが幸せかもしれない~~

~~なんとなくわかってきたけどこれフレームワークというよりライブラリ集に近い何かじゃ（ｒｙ~~



#問題点
1、全体的な書き方もそうだが、＠Webservletアノテーションの使い方がいまいちつかめていない。
引数に文字列リテラルでURLから見た飛び先を指定してやればいいようだが、
どうも挙動がつかめていない。

2、資料、テキストがあまりに少なすぎる。
最低限読めなくてはならないが、どうにもこうにもこれでは手が出せない。
というか見つけたはいいけれどどれも書き方がバラバラで困る。

#飛んできたトマホーク
中途半端でも書いたらツイッター方面からトマホークが飛んできました。

※動画はイメージです
https://youtu.be/10D_V9JU0uk

サーブレット仕様とStruts1.3.10を混同するなとのこと。
正直今まで混ざったままだったので本当にありがたい。
これをもとに再度勉強しつつ書いていきます。

#とりあえず書いてみる
今行っている環境設定から。

1、
今回使用したのはEclipseのPleiades4.4Luna-32bit、fullバージョン。
窓の杜のリンクに飛ばされるのでそこから自己解凍形式で落とす。
現在配布されているフルバージョンのZIPはなぜか解凍が失敗する。
名前短縮を行い、Win7の標準展開を使用も効果がない。
自己解凍形式の物だと正常に解凍できるのでこれを利用する。

2、
その後、Struts公式サイトへ。1.3.10をダウンロード。
Struts-1.3.10-all.zipを通常通り解凍後、Struts-1.3.10-allフォルダー内、
appsフォルダの中にあるwarファイルを確認する。
今回は「struts-blank-1.3.10」を使用する。
warファイルの拡張子をzipに変えて解凍。Lhaplus等で直接解凍できるならそれでもかまわない。
（ZIPファイルをそのまま取り込む手法もあるらしい。
　確かにお手軽ではある。あるけれどどうだろう……。）
解凍後のフォルダ内、WEB-INF→lib内のjarファイルを確認。今回はこれを使用する。

3、
インストール後立ち上げ、
「パースペクティブを開く」から「JavaEE」を選択し、JavaEEを使用可能にする。
右上のJavaEEをクリック、モードを切り替える。
その後、左上の「ファイル」から「新規」→「動的プロジェクト」を選択。
プロジェクト作成画面でプロジェクト名を「Struts」。
**ここで完了としないこと。**「次へ」をクリックしていき、
最後の画面で「WebXMLデプロイメント記述子の生成」をクリックしてチェック、完了する。
これで大枠となるプロジェクトのひな型が出来上がる。

4、
プロジェクトフォルダ内のWebContentフォルダ内WEB-INFフォルダ、
その中にあるlibフォルダに2で準備したjarファイルを全てドラッグアンドドロップで入れる。
（インポートのほうがいいのか？　実際どちらが正解かまだつかめていない。）
これで開発の準備が整う。準備自体は簡単だが書くとなるとまた難しい。
Rails アプリケーション作成コマンド まとめ

#セットアップ

##rails new
アプリケーションの新規作成。

```
rails new
```
オプションをつけて新規作成。

```
rails new -d mysql
```

##bundle install
gemをインストール

```
bundle install
```



gemの追加

```
gem 'gem名'
```

*Gemfile.lockに変更を加えるときは、ファイル消去後に

```
bundle install
```

#データベース、MVCファイルの作成

##rake db:create
database.ymlというファイルの内容を基にデータベースを新規作成。

```
rake db:migrate
```

##コントローラー

コントローラーの作成。

```
rails g controller articles
```

コントローラー名は基本複数。（用途に応じて単数）
under_score、CamelCasedのどちらでも可。
viewフォルダも一緒に生成。

コントローラーの削除。

```
rails destroy controller articles
```

関連ファイルもまとめて削除してくれる。

##モデル

モデルの作成


モデルの作成。
マイグレーションファイルも一緒に生成。

```
rails g model article
```

モデルの削除。
関連ファイルもまとめて削除。

```
rails destroy model article
```


##マイグレーションファイルの編集

changeメソッドで作成するカラムを指定。
ex.

```rb
class CreateArticles < ActiveRecord::Migration
  def change
    create_table :articles do |t|
      t.string :title
      t.text :content
      t.timestamps
    end
  end
end
```

##rake db:migrate
マイグレーションファイルの実行

```
rake db:migrate
```

###schemaファイル
rake db:migrateを実行するときに、schemaファイルの更新が行われる。

###shema_migration
どのマイグレーションファイルまでが実行されたかを記録するデータベースの変更履歴。
マイグレーションファイルの実行時に自動生成。

###rake db:migrateの仕組み

1. schema_migrationを参照し、まだ実行されていないマイグレーションファイルがないかを調べる。
2. 実行していないマイグレーションファイルが見つかれば、実行。

これによって、rake db:migrationを複数回実行しても、同じマイグレーションファイルが実行されることはない。

##rake db:rollback
データベースの状態を最新のマイグレーションファイル実行前に戻す。

作成したテーブル及びschema_migrationの状態が戻る。

###任意の状態まで戻したい

rake db:rollbackはあくまで1個前の状態に戻すだけ。
任意のmigrateまで戻すときは

1. rake db:drop でデータベースを削除
2. 要らないマイグレーションファイルの削除
3. rake db:create、 rake db:migrateでやり直す
Node.jsモジュール作って、GitHubにリポジトリ作って、npmで公開してみた

#とりあえず晒す
晒すのは良いこと。まあ、ノイズになるかも知らんけど、そこは容赦のない淘汰が帳消しにしてくれるはず。

ハウツー的なnpmへの上げ方は「[3分でできるnpm](http://qiita.com/fnobi/items/f6b1574fb9f4518ed520)」と、同じくGitHubについては「[はじめてのGitHub](http://blog.katsuma.tv/2009/02/first_github.html)」で、間違いもないし迷うところもないので、そっちをみてね。簡単。

と言うわけでやってみた。で、npmはこんな感じ[npm:control-structures](https://www.npmjs.com/package/control-structures)で、GitHubはこんな感じ[GitHub:mrpepper023/control-structures](https://github.com/mrpepper023/control-structures)になった。これ自体は超簡単。だが、その簡単さが怖いのだ。「そのやさしさがこわい」とかじゃなくて、本当に怖いのだよ。

#npm publish怖すぎる！
怖すぎます。そもそも動かなくなる系のエンバグをして、

```
npm publish
```

ふひー。(-.-)y-~~

夜が明けたら50ダウンロード。久々の嫌な汗をかいた。超怖いので、ぜひ、テスト系は真面目に取り組もうね。特に、ブラウザとnode.jsの両方から使えるようにするとか、そういうテストとしても別れていがちなのが怖い。そういうのをやるときのための情報源は色々あるけど、ちょっと引っかかりにくい[「ブラウザとNode.jsへの両対応」というタイトルではないページ](http://blog.oimou.com/7cbfae8d/)のやり方が一番確実な感じ。

www.npmjs.com へのお願い：「ダウンロードしたみんなに謝罪する」ボタンが欲しいデス。

#ちゃんとしたnpmをメンテするとき
絶対、自動テストスクリプトでnpm publishをラップした方が良いよね。今回みたいな単なる便利スニペット集みたいなのだったらまだしも……。痛切に思いました。

指がかゆいので以上。
MacOSXでabコマンドのアップデートメモ


初期状態のabコマンドのバージョンが古かったのでアップデートしたかった話です。

> 参考: http://codedehitokoto.blogspot.jp/2012/02/apache241ab.html

こちらからダウンロードしましょう。
http://httpd.apache.org/download.cgi#apache24

現時点でダウンロードできる最新バージョンは2.4.12でした。

解凍します。

```
$ tar xzvf httpd-2.4.12.tar.gz 
$ ls
httpd-2.4.12
httpd-2.4.12.tar.gz
```

httpd-2.4.12フォルダが出来るのでフォルダ内に移動します。

```
$ cd httpd-2.4.12
```


```
$ ./configure 
```

ここで私の場合エラーが出ました。

>参考 http://qiita.com/DQNEO/items/4ce4b4560c1bfad861e8

```
onfigure: Configuring Apache Portable Runtime Utility library...
configure:
checking for APR-util... yes
checking for gcc... /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.10.xctoolchain/usr/bin/cc
checking whether the C compiler works... no
configure: error: in `/Users/sugawara_nobisuke/Desktop/httpd-2.4.12':
configure: error: C compiler cannot create executables
See `config.log' for more details
```

以下で対応。リンクを貼ってあげます。

```
$ cd  /Applications/Xcode.app/Contents/Developer/Toolchains/
$ sudo ln -s XcodeDefault.xctoolchain OSX10.10.xctoolchain
```

再実行します。

```
$ ./configure
・
・
・
config.status: creating build/rules.mk
config.status: creating build/pkg/pkginfo
config.status: creating build/config_vars.sh
config.status: creating include/ap_config_auto.h
config.status: executing default commands
```

今回はうまくいきました。

```
$ make
```

今コンパイルしたabコマンドをデフォルトのabコマンドに上書きします。

```
$ sudo cp support/ab /usr/sbin
```

バージョンを確認して完了！

```
$ ab -V
This is ApacheBench, Version 2.3 <$Revision: 1178079 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
```
Rails Active Recordのまとめ

#Active Recordとは？
データベースからデータを読み出すアプローチ。(Wikipediaより)
Rails4対応。

#基本編
## Class.create
レコードを作成し、データベースへの保存。

```rb
article = Article.create(title: 'hoge', content: 'hogehoge')
```

##Class.new
オブジェクトのインスタンス化。

```
article = Article.new
```
##Class.save
インスタンスのデータベースへの保存。

```rb
article = Article.new
article.title = 'hoge'
article.content = 'hogehgoe'
article.save
```
*create = new + save*


##Class.build
new ≒ buildではあるが、buildは自動参照キーを自動でセットしてくれる。

```rb
@article = Article.find(1)
@comments = @article.comments.build
```
findについては後述。

article_idをセットしてくれる。

##Class.all
レコード全件取得。

```rb
article = Article.all
```

##Class.first
レコードの最初の1件取得。

```rb
article = Article.first
```

##Class.find
idで1件取得。

```rb
article = Article.find(1)
```

##Class.find_by
特定フィールドで最初の1件取得。

```rb
article = Article.find_by(title: 'hoge')
```

##Class.where().first
特定フィールドで最初の1件取得。
find_byと同じ役割。

```rb
article = Article.where(title: 'hoge').first
```

##Class.where
特定フィールドで全件取得。

```rb
article = Article.where(title: 'hoge')
```

##Class.update
レコードの更新。

```rb
article = Article.find(1)
article.update(title: 'hogehoge')
```

##Class.destroy
レコードの削除。

```rb
article = Article.find(1)
article.destroy
```

#便利メソッド

##Class.where().first_or_initialize
要素があれば最初の要素を取得。なければ、newインスタンスの生成。
ただし、saveを使用しないとsaveされない。

```rb
Article.where(title: 'hoge').first_or_initialize
```

ex.titleで検証してcontentも含めてsaveする。

```rb
article = Article.where(title: 'hoge').first_or_initialize
article.content = 'hogehoge'
article.save
```

##Class.where().first_or_create
first_or_initializeのsaveまでやってくれる版。

```rb
article = Article.where(title: 'hoge').first_or_create
```
##Class.ids
idの配列を作る。

```
article = Article.ids
```

##Class.pluck()
特定フィールドで配列を作る。

```rb
article = Article.pluck(:title)
```

#終わりに
便利なメソッドが見つかり次第、追加していく予定です。

参考
Active Record の基礎http://railsguides.jp/active_record_basics.html
rvmをrootで使用する場合とbash --loginのエラーが出た場合の対処法

##rvmのrootでの使用及び、bash --loginのエラーが出る場合

rootでインストールした`rvm`は、`/usr/local/rvm`にインストールされます。したがって、この`/bin/bash --login`エラーが出る場合は、ここからスクリプトを読み込むと、使えるようになります。一応、設定ファイルにも追記しておきましょう。

```bash:
# rootの場合
source /usr/local/rvm/scripts/rvm

# userの場合
source ~/.rvm/scripts/rvm

# 設定ファイルへの追記
$ echo !! >> ~/.zshrc
$ source !$
```

ちなみに、上記では、rootのホームディレクトリを`/root`と仮定します。OSによっては、違う場所にインストールされるかもしれませんが、`Arch Linux`の場合、こちらにインストールされましたので、他のLinuxでは、そんな感じだとも思われます。
  


##補足

rvmをrootにインストールするというのは、基本的にあまり良いとはいえません。なぜなら、Linuxのrootは、最小構成にして保つのが、システム管理及びセキュリティなどの観点から良いとされているからです。

実は、Linuxのrootというのも、他のユーザーと同じようにカスタマイズ可能です。この感覚は、よりシンプルなディストリビューションを使用したことがある人ならば、よく知っている事柄ではないかと思います。なぜなら、シンプルなディストリビューションというものは、そのすべての管理をユーザーに任せているものが多いからです。しかし、このようなシンプルなLinuxディストリビューション(以下、Linuxと略します)は、使いこなすのが難しいのも事実です。

例えば、rootのshellに設定ファイルを設定することも可能です。

```bash:/root/.zshrc
autoload -U compinit promptinit
compinit
zstyle ':completion:*:default' menu select=1

promptinit
prompt walters

function chpwd() { ls -aCFG }
```

ほとんどのOSというものは、特に、初心者向けのOSは、ユーザーフレンドリーであるものの、ユーザーが全てを管理することはできません。なぜなら、これは思想の問題で、コンピュータ、及びメンテナ自身や配布者に任せる部分と、ユーザーが管理する部分を明確にすることで、使いやすくしているからです。

なので、Linuxのrootといっても、自らがカスタマイズするのに向いているLinuxと、そうでないLinuxがあります。カスタマイズできないようになっているLinuxも中にはあるのではないでしょうか。知りませんが。

しかし、CIサービスや仮想化が主要になってきた現在、私は、rootを使うことが増えました。使い捨てるコンテナにわざわざユーザーを設定してあれこれするのが迂回だからです。もちろん。passwordは設定しますが、厳重にアクセスを制限した仮想化において、わざわざユーザーを設定して、ツールのインストール及び必要な変更において、そのたびにパスワード入力をする必要性をあまり感じていません。
Vimで改行コードCRをLFに、%s/^M/^M/gで置換する

Vim (or MacVim)で改行コードがCRのファイルを開くとこんな感じになってしまう。

![スクリーンショット 2015-06-08 14.51.22.png](https://qiita-image-store.s3.amazonaws.com/0/54305/ec168d7d-920c-1a68-e18d-d5b2f1b1a5a0.png)

以下のコマンドでLFに置換できる。
```:%s/^M/^M/g```

![スクリーンショット 2015-06-08 14.52.35.png](https://qiita-image-store.s3.amazonaws.com/0/54305/4a9106c3-a465-14fe-f128-34bf00c1df9e.png)
![スクリーンショット 2015-06-08 14.52.40.png](https://qiita-image-store.s3.amazonaws.com/0/54305/e8af7ff0-e1be-82a0-cb72-c5e2701d0eeb.png)

^Mは Ctrl+V,Ctrl+M で入力できる。

恒等変換っぽいコマンドなのにCR->LFの変換ができて気持ち悪い
MQTT利用時のクライアントID重複に注意

##同じクライアントIDで接続した場合
[MQTT3.1の仕様](http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html)によると、

>If a client with the same Client ID is already connected to the server, the "older" client must be disconnected by the server before completing the CONNECT flow of the new client.

とあり、古い接続は完了させて、あたらしいクライアントが有効になります。つまり同じクライアントIDで接続した場合には、先に接続していたクライアントが切断されてしまいます。

##接続セッションの保存のリトライ
MQTTクライアントは、clean sessionを設定しない限り、セッション情報(Subscribeトピックや、QoS1や2の未送信メッセージなどを含む)は保持しておくとされています。
>This includes continuing to store QoS 1 and QoS 2 messages for the subscribed topics so that they can be delivered when the client reconnects. The server must also maintain the state of in-flight messages being delivered at the point the connection is lost. This information must be kept until the client reconnects.

したがって、意図しないネットワークの切断が発生してもセッションを再開することができます。この仕様にしたがって、接続が切断した場合に自動で再接続要求をしてくれるクライアント実装があります。

##複数のクライアントが同じクライアントIDでリトライ
以上を総合して、「クライアント１」と「クライアント２」が同じクライアントIDで接続した場合を考えてみます。

1. 「クライアント１」が接続
2. 「クライアント２」が接続（「クライアント１」は切断される）
3. 「クライアント１」が再接続（「クライアント２」は切断される）
4. 「クライアント２」が再接続（「クライアント１」は切断される）

※以降、3. と4.の繰り返し

このように、クライアント間で再接続によるセッションの奪い合いが発生することになります。

##クライアントID重複が検出できない
現在の仕様では、古い接続の切断のみ仕様として定められいます。また、古い接続を切断したことを、新しく接続したクライアントに通知する手段もありません。（Connection Accepted：接続が受け付けられた　のみ）

**CONNACKのリターンコード**

|Enumeration|HEX|Meaning|
|-----|----|--------------------|
|0    |0x00|Connection Accepted|
|1    |0x01|Connection Refused: unacceptable protocol version|
|2    |0x02|Connection Refused: identifier rejected|
|3    |0x03|Connection Refused: server unavailable|
|4    |0x04|Connection Refused: bad user name or password|
|5    |0x05|Connection Refused: not authorized|
|6-255|    |Reserved for future use|

したがって、接続を乗っ取ったことをクライアントは識別できないようです。クライアントからは「なぜかすぐに接続が切れる」としか認識できず、クライアントID重複の検出は難しいと思われます。

## まとめ
クライアントIDは、重複しないようにルールを決めた上で利用するしかなさそうです。ユーザー名とパスワード認証の仕様はあるにもかかわらず、クライアントIDについては別途ルールを定めてコントロールしていくしかなさそうです。

もし、現行バージョンでのよい管理方法をご存知の方がいらっしゃいましたら情報を頂きたいです。

また、今後のバージョンでこの辺りが改善されることを望みます。
（既存クライアントIDの乗っ取りは同じユーザーからのみに制約できるオプションなど希望…）

※この投稿では端折ってますが、
Broker:mosquitto
Client:node.jsのmqttモジュール
で検証しました。
2つの配列両方に属するものを取得する方法をLINQで

#2つの配列のクラスが同じ場合
```csharp

public class Student
{
    public string Name;
    public int Age;
}

public class Class
{
    public Student[] Students;
}

public class Club
{
    public Student[] Students;
}
```

クラスとクラブ両方に属している生徒の名前のリストを作りたい場合
foreachを使った場合は

```csharp
var names = new List<string>();
foreach (var student in @class.Students)
{
    foreach (var clubStudent in club.Students)
    {
        if (student == clubStudent)
        {
            names.Add(student.Name);
        }
    }
}
```

LINQなら

```csharp
var names = @class.Students
    .Intersect(club.Students)
    .ToList();
```
#2つの配列が同じクラスではない場合
```csharp

public class Student
{
    public string Name;
    public int Age;
}

public class Class
{
    public Student[] Students;
}

public class Member
{
    public int Id;
    public string Name;
}

public class Club
{
    public Member[] Members;
}
```

クラスとクラブ両方に属している同じ名前の人のメンバーIDリストを作りたい場合
foreachを使った場合は

```csharp

var ids = new List<int>();
foreach (var student in @class.Students)
{
    foreach (var member in club.Members)
    {
        if (student.Name == member.Name)
        {
            ids.Add(member.Id);
        }
    }
}
```

LINQなら

```csharp

var ids = @class.Students
    .Join(club.Members, student => student.Name, member => member.Name, (student, member) => member.Id)
    .ToList();
```
Windowsにrebarをインストールするだけの簡単なお仕事！

#目的： Windowsにrebarをインストールする。

#実施環境：
OS： Windows8.1
Erlang： Eshell V6.4
rebar： 2.1.0-pre 17

#目次：
1.概要
2.rebarをインストールするだけの簡単なお仕事

##1. 概要

Erlangを使うに当たってrebarが使いたかった。
しかし、Windowsへインストールしている記事が見つからなかった。
仕方がないから自分で試してみました。

rebarの詳しいことは記事にして下さっている方がいますので、
そちらを参考にして下さい。
http://qiita.com/ohr486/items/b33cfcf0978ec51afc63

##2. rebarをインストールするだけの簡単なお仕事

```
>cd 作業ディレクトリ
>git clone https://github.com/basho/rebar.git (github： https://github.com/basho/rebar)
>cd rebar
>bootstrap.bat
>rebar --version
rebar 2.1.0-pre 17 20150608_040953 git 2.1.0-pre-171-gcd55176
```

インストールディレクトリにある。
rebar.cmdへ環境変数を設定しておきましょう。

```
>cd 適当なディレクトリ
>rebar --version
rebar 2.1.0-pre 17 20150608_040953 git 2.1.0-pre-171-gcd55176
```

かなりざっくりですけど、サンプルを作成してみます。

```
>cd 作業ディレクトリ
>mkdir sample_app

>ls
sample_app

>cd sample_app

sample_app>ls

sample_app>rebar -c

sample_app>rebar create-app appid=sample
==> sample_app (create-app)
Writing src/sample.app.src
Writing src/sample_app.erl
Writing src/sample_sup.erl

sample_app>rebar compile
==> sample_app (compile)
Compiled src/sample_app.erl
Compiled src/sample_sup.erl

sample_app>ls
ebin  src

sample_app>ls src
sample.app.src  sample_app.erl  sample_sup.erl

sample_app>ls ebin
sample.app  sample_app.beam  sample_sup.beam

sample_app>rebar clean
==> sample_app (clean)

sample_app>ls
ebin  src

sample_app>ls ebin
なし
```

##まとめ

結構簡単にインストールできました。
これでビルドやパッケージ管理が楽になります！

##参考文献
https://github.com/rebar/rebar/wiki
IEでのYouTube埋め込み動画再生エラー 「エラーが発生しました。しばらくしてからもう一度お試しください。」

会社にあるWindowsの検証マシンで、
YouTubeの埋め込み動画が再生できないという問題にぶつかった。

![image.jpg](https://qiita-image-store.s3.amazonaws.com/0/79112/f02addfc-0600-4ba7-a34c-2e5caad56bfc.jpeg)

解決に向け、もう結構長いこと、いろいろなことを試してみた。

「*YouTube 埋め込み 不具合 IE*」だの、
「*YouTube エラーが発生しました*」だの、
「*YouTube 直らない iframe*」だの、

ググっては試し〜、ググっては試し〜・・・

いろいろな記事を参考に、触ったことのないようなマシン本体の設定までいじってはみたけど、
どうやっても解消されない。


# が、ダメ元で試してみた方法で、あっさり解決。

#### **解決方法：**
**イヤホンでも外付けスピーカーでもいいから、マシンにさす！**

この方法で再生エラーが解消された時は、思わず口から「えぇぇぇぇ・・・」って漏れた。
当該の検証マシンにサウンドデバイスが存在していないことが直接の原因。
でもこれってIEが悪いわけじゃないような。。


#再生エラーの症状についてもうちょっと詳しく検証。

まず、エラーは“動画がまったく再生できない”というものではなく、
2〜3秒タイムラインをカタカタ行ったり来たりしたあとで
`エラーが発生しました。しばらくしてからもう一度お試しください。`
というメッセージが出るというもの。

その他、

・当該マシンで再生エラーが起きるブラウザはIEだけ
　→ 同じマシンのGoogle Chrome, Firefoxは問題ない。
　　問題なく再生されたブラウザの方はVideoタグで動画が表示され、
　　**IEの方は同じ埋め込みコードでもFlashで表示されていた。**

・当該マシンのIEでも、再生できる動画と再生できない動画がある
　→ **パラメーターの設定値やプライバシー強化モードの設定は関係なく、どうやら動画の長さの問題。**
　　今回のマシンのIEについては、長さ13秒がエラー発生のボーダー。

・違うマシンの同じバージョンのIEでは、問題なく正常に再生される
　→ **んんん？？？**


3つ目が決定的。
サウンドデバイスが無効であることで、Adobe Flash Playerがエラーを起こしていた模様。。

ただ動画の長さによっては再生できるものもあったので、
もうちょっとバシッと言い当てられるような原因がある気も。
検証マシンのスペックの問題もあるかしら。。

なんにせよ、長く辛かった・・・
Visioファイル内の図形を列挙する。Excel VBAを使って。

# 概要

Visioでぺたぺた設計書を作りました。
見積り根拠とするために、設計書内の図形を数えたくなりました。[^1]

[^1]: ほんとは、先に一覧ファイルを作ってからVisioに接続するのが美しいやりかた。 :sweat_smile: 

VBAでできそうだったので、Excelを使ってやってみました。

# ソース

## メインルーチン

本体部分です。

ファイルを選択し、Visioを起動し、図形を列挙してワークシートに記録します。

例外処理とかエラー処理とか抜けてますが、とりあえずということで。 :smile: 

```vb:CountVisioShapes.bas
Option Explicit

Public Sub CountVisioShapes()
    Dim fn As Variant
    
    Dim visioApp As visio.Application
    Dim visioDoc As visio.Document
    Dim visioPag As visio.Page
    Dim visioShp As visio.Shape
    
    Dim rs As New ResultSheet
    
    fn = Application.GetOpenFilename(FileFilter:="Visioファイル,*.vsdx", MultiSelect:=False)
    
    Set visioApp = CreateObject("Visio.Application")

    visioApp.Documents.OpenEx fn, visOpenRO + visOpenHidden
    
    Set visioDoc = visioApp.Documents.Item(1)

    For Each visioPag In visioDoc.Pages
        For Each visioShp In visioPag.Shapes
            rs.putPageName visioPag.Name
            rs.putShapeName visioShp.Name
            rs.putShapeText visioShp.Text
            rs.putMasterShape visioShp.MasterShape.Text
            rs.nextRow
        
        Next
    Next
    
    visioDoc.Close
    visioApp.Quit
    
    Set visioDoc = Nothing
    Set visioApp = Nothing
End Sub
```

## ワークシートのラッパ

ワークシートへ値を格納するのを簡単にするためのクラスです。

```vb:ResultSheet.cls
Option Explicit

Private currentRow As Long
Private startCol As Long
Private mySheet As Worksheet

Private Sub Class_Initialize()
    With Application.ActiveCell
        currentRow = .Row
        startCol = .Column
    End With
    
    Set mySheet = Application.ActiveSheet
    
    putHeaderRow
End Sub

Private Sub putHeaderRow()
    putCommon 0, "ページ名"
    putCommon 1, "シェイプ名"
    putCommon 2, "シェイプテキスト"
    putCommon 3, "マスターシェイプテキスト"
    nextRow
End Sub

Public Sub nextRow()
    currentRow = currentRow + 1
End Sub

Public Sub putPageName(s As String)
    putCommon 0, s
End Sub

Public Sub putShapeName(s As String)
    putCommon 1, s
End Sub

Public Sub putShapeText(s As String)
    putCommon 2, s
End Sub

Public Sub putMasterShape(s As String)
    putCommon 3, s
End Sub

Private Sub putCommon(sft As Integer, s As String)
    mySheet.Cells(currentRow, startCol + sft).Value = s
End Sub
```

## 起動ボタン

メインルーチンを起動するためのボタンを作りました。

![excel-button.PNG](https://qiita-image-store.s3.amazonaws.com/0/59475/4976091d-eaf1-5dd0-6163-6cd97bab6a11.png)

ボタンクリック時にメインルーチンを呼ぶようにします。

```vb:
Option Explicit

Private Sub SelectVisioFileButton_Click()
    Call CountVisioShapes.CountVisioShapes
End Sub
```

# 実行結果

作成したボタンを押すとファイル選択ダイアログが表示されますので、ファイルを選択するとアクティブセルに結果が出力されます。

![countvisioshapes.PNG](https://qiita-image-store.s3.amazonaws.com/0/59475/f940a746-068b-a930-1c33-d6d9e3045aad.png)

# 保存

作成したファイルは「マクロ有効テンプレート」として保存しておくと便利です。
electronのビュー(html)でjqueryを使う

electronのビュー(html)でjqueryを使おうとすると`Uncaught ReferenceError: jQuery is not defined`エラーが発生します。以下はその解決方法です。
(jqueryをnpmでインストールしていることが前提です)

# 解決方法

~~~html
    <!-- jQuery -->
    <script src="../node_modules/jquery/dist/jquery.min.js"></script>
    <script>
    /**
     * fix jQuery reference error.
     * see https://github.com/atom/electron/issues/345
     */
    try {
        $ = jQuery = module.exports;
    } catch(e) {}
    </script>
~~~

../node_modulesへのパスは相対パスなので、環境によって変えてください。

参考: https://github.com/atom/electron/issues/345
コマンドラインからフローチャートや図を描く方法


例えば、Vimで図を描くには、[DrawIt](https://github.com/vim-scripts/DrawIt)が有名ですが、私の場合、こういった操作が複雑な、特にキーバーンドを覚えるのが面倒なプラグインを使うことはあまりありません。

ここで、Shell(Terminal)で描く事が多いのですが、そんな時は、[graph-easy](http://search.cpan.org/~tels/Graph-Easy/lib/Graph/Easy.pm)を使います。

ArchLinuxの場合、Perlは元から入ってるというか、ほとんどのOSには最初から入ってるので、以下のコマンドでインストールできると思います。

```bash:
$ cpan Graph::Easy
```

以下の様な感じでフローチャートや図を書けます。

```bash:
$ graph-easy <<<'[ MacBook Air ] -- LAN --> [ WOL Server ] -- LAN --> [ File Server ],[ Post Server ]'

+-------------+  LAN   +-------------+  LAN   +-------------+
| MacBook Air | -----> | WOL Server  | -----> | File Server |
+-------------+        +-------------+        +-------------+
                         |
                         | LAN
                         v
                       +-------------+
                       | Post Server |
                       +-------------+

$ graph-easy <<< '
digraph {
start -> adsuck;
adsuck -> block;
block -> noop[label=yes];
block -> unbound[label=no];
noop -> serve_noop[label=yes];
noop -> serve_empty[label=no];
}'


                      +-------------+
                      |    start    |
                      +-------------+
                        |
                        |
                        v
                      +-------------+
                      |   adsuck    |
                      +-------------+
                        |
                        |
                        v
+------------+  no    +-------------+
|  unbound   | <----- |    block    |
+------------+        +-------------+
                        |
                        | yes
                        v
+------------+  yes   +-------------+
| serve_noop | <----- |    noop     |
+------------+        +-------------+
                        |
                        | no
                        v
                      +-------------+
                      | serve_empty |
                      +-------------+
```
ハイフンに似てる文字の文字コード

日本語環境ではハイフンっぽく見える文字が何種類も有ります。
そのせいで、住所入力欄などでハイフン(っぽい文字)でバリデーションにひっかかってイライラするということが多々有ります。
一般のユーザーがハイフンっぽい文字の違いを理解しているはずもないので、ハイフン系文字の内、特定の1つだけを許容するようなバリデーションルールを設定してしまうと、ユーザビリティを低下させてユーザの離脱を招きます。
ハイフンっぽいものは全部入力できるようにして、サーバサイドで統一的な文字に置換するほうが良いでしょう。

というわけで、日本語環境で入力できるハイフンをまとめてみました。

| 文字 | UTF-8 | Unicode | 説明 |
| ---- | ---- | ---- | ---- |
| - | 2D | U+002D | ASCIIのハイフン |
| ー | E383BC | U+30FC | 全角の長音 |
| ‐ | E28090 | U+2010 | 別のハイフン |
| ‑ | E28091 | U+2011 | 改行しないハイフン |
| – | E28093 | U+2013 | ENダッシュ |
| — | E28094 | U+2014 | EMダッシュ |
| ― | E28095 | U+2015 | 全角のダッシュ |
| − | E28892 | U+2212 | 全角のマイナス |
| ｰ | EFBDB0 | U+FF70 | 半角カナの長音 |

日本語IMEから入力可能なものはこれくらいでしょうか。

例えば、PHPでこれら全てにマッチする正規表現を書くと以下のようになります。

```php
$regex = '/[\x{30FC}\x{2010}-\x{2015}\x{2212}\x{FF70}-]/u';
```

実はまだまだたくさんハイフンに似た文字は有ります。
下記記事を参考に状況に応じて実装して下さい。

## 参考

* [ダッシュ (記号) - Wikipedia](http://ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5_%28%E8%A8%98%E5%8F%B7%29)
* [Unicode対応文字コード表](http://ash.jp/code/unitbl21.htm)
* [UTF-8 to Unicode converter](http://ratfactor.com/utf-8-to-unicode)
* [Unicodeにあるハイフン/マイナス/長音符/波線/チルダのコレクション | hydroculのメモ](https://hydrocul.github.io/wiki/blog/2014/1101-hyphen-minus-wave-tilde.html)

## 謝辞

* [hnw](http://qiita.com/hnw)さんに他にもたくさんのハイフンっぽい文字があることを教えて頂きました。
3年目の若手がエスアイヤーのコードをリファクタしようとした

オフショアからの納品物を仕様変更で改修することになった3年目社員の抵抗
# 改修ついでにリファクタしたもの
## 1行ずつコメント
```java
//hogeを2回行う
hoge(); //1回目
hoge(); //2回目
```
やたらコメントが多い（※あとで気付いたけど、顧客に単体試験のエビデンスでソースコードをスクリーンショットして提出しようとしてたからかも）。
そのくせ変数にはコメントついてなかったりする。
### 対応
~~何もしませんでした~~　→　直しました。
見りゃわかるような意味のないコメントをがっつり削除。
逆にコメントが欲しいところは日本語的に適切なコメントを入れた。
（全くプログラムできない人間にもむりやりプログラム書かせるのでコメント無しにするわけにはいかないのです）
## クラスの最初に”グローバル変数”
```java
public class PluginHoge extends hugahuga {
	/*-----------------------------------
			グローバル変数
	------------------------------------*/
	/**
	 * フレームワークのメソッドに渡すために使うなんかのフラグ
	 */
	private final int NANIKANO_FLG = 1;
```
つっこみが追いつかないくらい嘘つかれてる気がする。
### 対応
別のソースに書いてあった`Member Variables`に書き換えておいた。
できるだけその変数を使うメソッドの直前とかできればその中に移動した。
## 消せないコメント
modの履歴とか不要になった処理とか、変更前のコードとか。
### 対応
変更履歴をコメントで書くのやめてくれって思う。
必ず今後書き直す人が迷うと思うし、バージョン管理が無い時代に編み出された不要なコストなので、古い慣習ﾀﾋねって想いでがっつり消してコミットコメントに書いておいた。
## ローマ字変数
`UKETSUKE_FLG`とか`HUMEITENCD`とか。
### 対応
変数名に日本語使うのはスネークケースでもキャメルケースでも謎の迷いがおきる。何よりかっこ悪い。
けど自分の担当特有のものだけじゃないので混乱を避けるため放置。
## コメントの無い変数
一行一行コメントを書いてた生真面目さは急にどこかに消えた。
### 対応
名前をわかりやすいもの（booleanだったらisHogeみたいな）に変えたりコメントで説明足しておいた。
## if elseでtrue false
```java
boolean flg;
if("何かの判定") {
    flg = true;
} else {
    flg = false;
}

if(flg) {
    hogehoge();
}
```
(;ﾟ□ﾟ)ってなった。
### 対応
```java
if("何かの判定") {
    hogehoge();
}
```
に変えておいた。改修を見越してたのかもしれないけど、きっともっと良い方法がある。
## 繰り返しコード
パラメータだけ変えて同じロジック繰り返したり。
あと共通処理をいじりたがらない人にコピペを強要されたり。
### 対応
メソッドにした。
コピペはやり方だけもらって自分の書き方に落とし込んだ。
## 共通関数に業務ロジック
突然業務ロジックが出てくると思い通りに動かない。配列を渡した場合全部処理するだけみたいな単純な処理にしてほしい。
### 対応
文句言いまくって直してもらった。案の定仕様変更入ったし、できるだけ単純化した方がいい。
## Javadoc
```java
//なにかの処理
/*
@param a
@return
*/
```
・・・
### 対応
書き方知らない人が書いたみたいなので修正した（僕も勉強中だけどな！）。
doc生成しておかしなところとかを共通処理含めとりあえず全部書き直した。
あとJavascriptにもJSdoc書いた。Eclipseならきっと拾ってくれる！
## インデント
派手にずれていたり、スペースとタブが混在してたり、不要な改行が続いたりなので最初にやっちゃう。
## Checkstyle
タブ派とかインデントのチェック外してためしにやってみたけど真っ黄色になった。
# まとめ：何を直したかったのか
~~オフショアしてるのに日本の社員がソースがっつり書き直さなきゃならないとかアホらしいって思ってやりました。~~
変な習慣を直したかった。
てゆうか誰かコードレビューする習慣入れて。。
## 追記
やってみてわかったこと

* わかっててもみんな直す余裕がない
* 誰もやり方に疑問を持っていない
* チームメンバが全員プログラムできるわけではない
* できる人でも変な書き方を踏襲してしまう
* コピペプログラマにコピペさせないようにすることは徹底できない（納期が厳しいのに仕様変更が頻繁にある。共通関数などの開発が間に合わない。使用してるフレームワークの固有機能に興味がない etc...）
* 変えたらメールで使い方とかサンプルコードを周知しないとならない
* 詳細設計書.xls やテスト項目表.xls やエビデンス.xls を作ったりしながらこれらをやる時間がない
* 原価率が`<censored>`
* ~~仕事辞めよ~~
RubyのArrayをorder by rand

order by randと言ったらSQLでたまに話題にあがりますが、それとは関係なく、RubyのArrayをランダムに並び替え(シャッフル)たくなったので、自分用にコードを残しときます。
Fisher-Yatesアルゴリズムのつもりで書いてます。

改善点等ありましたらバシバシご指摘お願いします。

```ruby:order_by_rand.rb
class Array
  def order_by_rand
    n = self.size
    n.times do |i|
      idx = rand(n-i)
      self[idx], self[-(i+1)] = self[-(i+1)],self[idx]
    end
    self
  end
end
```
FactoryGirlアンチパターン(?)

FactoryGirlの使い方はググればすぐ出て来るんだけど、「適切」な使い方、いわゆるベストプラクティスを紹介、あるいは模索しているページは日本語ではほとんどない(英語だとちょくちょくある、たとえば「FactoryGirl slow」でググってみると良いと思う)。テストの改善を任されたのでせっかくだからその記録をここに残しておくことでFactoryGirlのより良い書き方の議論が盛り上がるようなことになればうれしいな、と思う。

アンチパターン1:とにかくcreate
=
SQLアンチパターンみたくかっこいい二つ名をつけたかった気もするけど後で超絶恥ずかしくなるのはわかってるので、そのままの名付けをしていく。
とにかくすべて`create`、`create_list`を使うというパターン。本当に実際の環境をエミュレートしていることに間違いはないのだけど、とにかく遅い。IOを両方行っているし、単一のobjectならいざ知らず、巨大関連からなる一つの「系統樹」とでもいうべき一連のobjectを一つのexampleのたびにDBIOするのはどう考えても無駄なコストだ。特にただ単にメソッドの振る舞いをテストするようなときは`build`、`build_stubbed`で十分だと思われる。むしろデフォルトを`build`、`build_stubbed`にして問題が発生したときに初めて`create`を使うことを考慮する、くらいでいいかもしれない。
参考:https://robots.thoughtbot.com/speed-up-tests-by-selectively-avoiding-factory-girl
https://robots.thoughtbot.com/use-factory-girls-build-stubbed-for-a-faster-test)

アンチパターン2:異常に根深いassociationと遠隔操作のごときtrait
=
上にも少し話題にあげたけど、あまりassociationを深くしすぎると融通が利かなくなるので、二段階異常のassociationについてはstubメソッドで対応する、みたいにしたほうがいい気がする。そして、これをtraitで管理するとどういう風になるのかというと、

```.rb
Model One
 belongs_to Two
 belongs_to Three

Model Two
#a/bの二種類を取りうる

Model Three
#c/dの二種類を取りうる

Model Four
belongs_to Two
#e/fの二種類を取りうる

```
みたいな関連になってるときに、
`with_Two_is_a_and_Four_is_e_and~`みたいな直接ではない関連を制御するためのtraitが出てきだす。そうなると辛くて、すべてのパターンを網羅するようにfactoryを定義していく義務みたいなのが生じてくる。しかし、一段階より大きい深さの関連についてはstubでごまかす、みたいな風にしとくと、factory自体はそこまで複雑にならずに済む。factoryの定義とテストが密結合だと、今までは同じfactoryで済んでたケースが仕様が変わってあるケースだけ先のほうの関連objectの何かしらの設定を変更しないといけない、となったときに、trait職人みたいになってくるのはつらい。やはりfactoryは直接関連しているobjectにのみ責任を持つべきだと思う。([デメテルの法則](http://ja.wikipedia.org/wiki/%E3%83%87%E3%83%A1%E3%83%86%E3%83%AB%E3%81%AE%E6%B3%95%E5%89%87))

TODO:[これ](http://stackoverflow.com/questions/17754770/factorygirl-build-stubbed-strategy-with-a-has-many-association)について書く(ちゃんと読む)。


ご意見や新たなアンチパターン、ベストプラクティスをお待ちしております。この記事は加筆修正していく予定です。
コマンド一発でファイルを削除して上書きする方法


  zshだと簡単で`>!`でファイルを上書きすることができます。

  通常は、以下のコマンドでは出力先がある場合、上書きすることができません。

  ```bash:
  $ touch test.txt

  $ echo hello > test.txt
  ```

  しかし、`zsh`だと以下のように上書きできます。

  ```bash:
  $ touch test.txt

  $ echo hello >! test.txt

  $ cat test.txt
  hello
  ```
埋め込み Undertow でアクセスログを残す

サーブレットコンテナとしても使える [Undertow](http://undertow.io/) ですが、Jetty と同様、Jar に一緒に入れて使うこともできます。しかしその際の access log (よくみる [CLF](http://en.wikipedia.org/wiki/Common_Log_Format) 的なアレ)のとり方があまりドキュメントとしてインターネットにない感じだったので書く。

基本的にはメインになる `HttpHandler` をラップし、ログだけ残す仕事をしてくれる [AccessLogHandler](https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/accesslog/AccessLogHandler.java) を使えば良い:

~~~~~~~~~~~~~~~~~~~~~~~~~~~Main.java
public static void main(String[] args) throws Exception {
    Logger accesslogger = LoggerFactory.getLogger("accesslog");
    HttpHandler mainHanlder = exchange -> {
        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
        exchange.getResponseSender().send("Foo");
    };
    HttpHandler handler = new AccessLogHandler(
         pathHandler,
         accesslogger::info,
         "combined",
         Main.class.getClassLoader());
    Undertow.builder()
            .addHttpListener(8080, "0.0.0.0")
            .setHandler(handler)
            .build().start();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~

第2引数の [AccessLogReciever](https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/accesslog/AccessLogReceiver.java) にはいくつかバンドルされている実装があるが、ログの制御は logback に一元化したいため今回はこうした。
mod_macro: /$appname で gunicorn アプリを複数定義する


## macro.conf

~~~xml
<Macro App $appname $port $base >
	# Gunicorn アプリケーションを /$appname の apache Loctionで受ける
    <Location /$appname/ >
      ProxyPass http://127.0.0.1:$port/$appname/
      ProxyPassReverse http://127.0.0.1:$port/$appname/

	  # Gunicorn アプリに SCRIPT_NAME を渡す
      RequestHeader set SCRIPT_NAME /$appname

    # RequestHeader set X-FORWARDED-SSL "on"
    # RequestHeader set X-FORWARDED_PROTO "https"
    </Location>

	# Django /$appname/static ファイルはリバースプロキシしない
    <Location /$appname/static/ >
        ProxyPass !
    </Location>

	# /$appname/static をapacheで配信させる
    Alias /$appname/static $base/web/static

</Macro>


<Macro Site $base>
 # サイト全体の定義
 ServerAdmin admin@you.com

 ProxyPreserveHost On

 LogLevel warn
 ErrorLog  $base/web/etc/apache2/logs/apache.error.log
 CustomLog $base/web/etc/apache2/logs/apache.access.log combined

 <Location / >
    Require all granted
 </Location>
</Macro>

<Macro Certs $site>
# 証明書関連 : /etc/apache/ssl/$site にシンボリックリンク作っておくとか
SSLEngine on
SSLCACertificateFile /etc/apache2/ssl/$site/ca.cert.pem
SSLCertificateFile /etc/apache2/ssl/$site/cert.pem
SSLCertificateKeyFile  /etc/apache2/ssl/$site/key.pem
</Macro>
~~~

# you.com.conf

- 先に macro.conf が読み込まれていること
- ` sudo a2enmod macro proxy proxy_http rewrite headers`

~~~xml
<VirtualHost *:80>
   ServerName   https://you.com
   ServerAlias  you.com
   RewriteCond %{HTTPS} off

   Use Site /home/vagrant/projects/yoursite
   
	# ここからgunicornアプリごとの設定ファイル
   Include sites-enabled/app1.inc
   Include sites-enabled/app2.inc
</VirtualHost>

<VirtualHost *:443>
    ServerName   https://you.com
    ServerAlias  you.com
    SetEnv HTTPS ON

    Use Certs you.com
    Use Site /home/vagrant/projects/yoursite

    RequestHeader set X-FORWARDED-SSL "on"
    RequestHeader set X-FORWARDED_PROTO "https"

	# ここからgunicornアプリごとの設定ファイル
   Include sites-enabled/app1.inc
   Include sites-enabled/app2.inc
</VirtualHost>
~~~

## $appname.inc

- たとえば app1.inc
- TCP9000で gunicornで受ける
- /etc/apache2/sites-enabledにシンボリックリンクしておく

~~~
Use App app1 9000 /home/vagrant/projects/yoursite/app1
~~~

## gunicornアプリ

- supervisord.conf.d/app1.ini とか

~~~ini
[program:app1]

command=/home/vagrant/.anyenv/envs/pyenv/versions/wordpress/bin/gunicorn -c /home/vagrant/projects/yoursite/web/app/gunicorn.py app.wsgi:application  -b 127.0.0.1:9000
user=vagrant
autostart=true
autorestart=true
redirect_stderr=true
process_name=app1
~~~

## django でSCRIPT_NAMEの対応
- ミドルウエアでsettingsにパッチする

- settings.py

~~~py
MIDDLEWARE_CLASSES += (
    'app.middleware.SettingsMiddleware',   
)
~~~

- middleware.py

~~~py
from django.conf import settings

URLS = [
    'STATIC_URL',
    'LOGIN_URL',
    'LOGOUT_URL',
    'LOGIN_REDIRECT_URL', ]


class SettingsMiddleware(object):
    def process_request(self, request):
        prefix = request.META.get('SCRIPT_NAME')

        if prefix:
            for i in URLS:
                val = getattr(settings, i, None)
                if val and not val.startswith(prefix):
                    setattr(settings, i, prefix + val)
~~~
Android 開発スタートアップ


android 開発を始めるにあたって、環境構築から簡単なアプリを実機で動かすまで。
androidに関する予備知識ほぼゼロな感じです。
実機もサブ機なのであまり使い込んでいません(苺)。

PCは、

* MacBook Air 13in
* OSX(10.10.3)

実機は、

* HUAWEI P7-L10
* Android(4.4.2)

です。

# 開発環境構築

開発環境はとりあえず、オフィシャルなandroid用IDEであるらしい、AndroidStudio を使います。

http://developer.android.com/sdk/index.html

からDL。

DL後の流れは

http://techacademy.jp/magazine/5238

が大変参考になりそうです。

が、起動しようとしたら java ランタイムが無いと怒られました。

http://developer.android.com/sdk/index.html#Requirements

によると、

* Java Runtime Environment (JRE) 6
* Java Development Kit (JDK) 7

が必要との事。

https://support.apple.com/kb/DL1572?viewlocale=en_US&locale=en_US

からDLしてインストールします。

再度 AndroidStudio を立ち上げます。

途中エミュレータを高速にするHAXM(Hardware Accelerated Execution Manager by Intel)をインストールしたりして、普通に完了しました。

# サンプルプロジェクト作成

AndroidStudio を起動して、 Start a new Android Studio project を選択。

## New Project

以下を埋めていきます。

* Application name: アプリの名前
* Company Domain: 使用するドメイン ex) dev.test.com とか
* Project location: プロジェクトのパス

Package name は Application name と Company Domain から自動生成されます。

アプリ名などの命名ルールは以下を参考にさせて頂きました。

http://qiita.com/Reyurnible/items/2de397b80391189af8e4

## Target Android Devices

とりあえず、 Phone and Tablet だけチェック。
Minimum SDK はデフォルトの 4.0.3 のまま。

## Add an activity to Mobile

Blank Activity を選択

## Customize the Activity

Activity Name は MainActivity としておきます。
それに伴い、Layout Name、Title、Menu Resource Name が変わっていくのでそれらはそのままで。

で、 Finish。

New Project で指定したパスにプロジェクトが作成されます。
作成されるとAndroidStudioでそのプロジェクトが開かれる。

# 実機の設定

実機でのデバッグを有効にするには、USBデバッグをONにする必要がある。

実機をPCに繋いだ状態で、

設定 > 開発者向けオプション で USBデバッグをONにできるが、OS ver 4.2以降では、
開発者向けオプションが非表示になっている。

それを表示するには 設定 > 端末情報 で ビルド番号を 7回タップすると、
開発者向けオプションが表示される。

# アクティビティの編集

app.res.layout.activity_main.xml を適当に(ちゃんと分かってない)。

# アプリ実行

AndroidStudio の上部のツールバーのrunボタン(右向きの三角のボタン)を押すと、
繋いでいる実機名が表示されるはずなので、それを選んで OK で実機で実行されるはず。  

# おしまい

iOSの開発を始めた頃は実機で動かすのにプロビジョニングファイルの作成やらなんやらで四苦八苦した記憶があるけど、
それに比べるとかなりあっさりとしたものです。この辺の敷居の低さは素晴らしいです。

まあ、全く意味のないアプリを動かしただけなのでまともなアプリを作るとすると腐る程ハマりポイントはあるはずですね。

あと、AndroidStudio ですが、私が使用している 13in ディスプレイだと少々手狭な予感がしますね。

アクティビティの編集にGUIベースでドラッグ/ドロップでパーツ(Widgets)を配置できるのですが、
ちょっとこのサイズだと使いづらそうです。

アクティビティは xml なのでテキストベースでの編集もできるはずですが、android の開発スタイルの主流はどうなんでしょうね。

その辺りは今後やりつつ自分にあったのものを身に付けたいですね。

ちなみに、今回AndroidStudioインストール後の流れは

http://developer.android.com/training/basics/firstapp/index.html

を参考にしています。

本家のドキュメントなので(比較的英語もわかりやすいし)もう少し目を通してみようと思います。
Sensuの監視から、電話の一斉通知と対応履歴を管理する

サーバ、システム保守する上で監視は要です。ただし監視すること自体は本質ではなく、障害が発生した時に、いかに早く気づきスムーズに対応できるかが重要です。


Sensuからメールだけじゃなく、自社の障害対応管理ツール「Reactio」というサービスを利用して電話での一斉通知とチャットでの対応する方法を共有します。

# 概要

- Senseの設定
 - 初期設定 
 - handlersの登録
- Reactioの設定
 - プロジェクトのAPIキーの登録
 - インシデント作成プログラムの作成
- まとめ

# Sensuの設定

Sensuとは？ (https://sensuapp.org/)
Ruby製の監視ソフトウェア。AWSなどのクラウド環境に強く、APIを利用した外部連携が得意。

![Screen Shot 2015-06-08 at 11.52.18 AM.png](https://qiita-image-store.s3.amazonaws.com/0/9416/bb0d5fa4-b81b-e7fa-1c38-5fbb936830b5.png)


## 初期設定

初期設定と各種リファレンスはこちらの記事を参考に（割愛）
http://qiita.com/spesnova/items/f9a8c9661861cc453ead


## hadlersの登録

参考）https://sensuapp.org/docs/latest/getting-started-with-handlers

- Sensuに登録した監視リソースに下記を登録

```lang:/etc/sensu/conf.d/reactio_handler.json 
{
  "reactio": {
    "api_key": "<APIキー>",
    "organization": "demo"
  },
  "handlers": {
    "reactio": {
      "type": "pipe",
      "command": "/etc/sensu/handlers/reactio_handler.rb",
      "serverities": ["critical"]
    }
  }
}
```

# Reactioの設定

Reactioとは？ (https://reactio.jp)
監視システムで検知した障害対応を、迅速に行い対応がそのまま記録され管理できるツール。

![Screen Shot 2015-06-08 at 11.50.58 AM.png](https://qiita-image-store.s3.amazonaws.com/0/9416/16865cea-824e-f5d1-ee6a-db77e8cbaed6.png)


## プロジェクトのAPIキーの登録

本家のブログを参考（割愛）
http://blog.reactio.jp/entry/2015/05/26/161408

## インシデント作成プログラムの作成

reactioのRuby版APIクライアントを利用してプログラムを作る
参考）http://blog.reactio.jp/entry/2015/05/13/172036

```lang:reactio_handler.rb
#!/usr/bin/env ruby
#
# Sensu Reactio Handler
# ===

require 'rubygems' if RUBY_VERSION < '1.9.0'
require 'sensu-handler'
require 'reactio'
require 'timeout'
require 'json'

class ReactioHandler < Sensu::Handler

  def event_name
    "#{@event['client']['name']}/#{@event['check']['name']}"
  end

  def handle
    return unless @event['action'].eql?('create')
    return unless @event['check']['status'].eql?(2)
    begin
      timeout(10) do
        create_reactio_incident
        puts "reactio -- incident #{event_name} created."
      end
    rescue Timeout::Error
      puts "reactio -- timed out while attempting to #{@event['action']} a incident -- #{event_name}"
    end
  end

  private

    def create_reactio_incident
      reactio.create_incident(
        "#{event_name} #{@event['check']['output']}",
        detection: 'internal',
        notification_text: '対応をお願いします',
        notification_call: false
      )
    end

    def reactio
      Reactio::Service.new(
        api_key: settings['reactio']['api_key'],
        organization: settings['reactio']['organization']
      )
    end
end
```

以上でセットアップ完了です。


# まとめ

## 実際に障害が起きた時の流れ

1. 監視対象サーバに問題が発生
2. Sensuにて監視対象サーバの状態を検知して、アラート発報
    3. メールにてアラートを受信
    4. ReactioのAPIで自動でインシデント作成
5. Reactioでインシデント登録
    6. 一斉通知機能で、プロジェクト関係者に電話通知（音声読み上げ）
7. Reactioのグループチャットに集結して障害対応
8. 通知先、通知内容、チャットの会話すべてが記録される
ある日急にベイグラントが起動しなくなった

**「何もしていないのに急に」**とか、パソコン初心者のようなセリフを吐きながら仕事ができない状況に。
ベイグラントを起動しようとしたら以下のようなエラーが。

<div class="code-frame" data-lang="text"><div class="highlight"><pre>
Bringing machine 'default' up with 'virtualbox' provider
Vagrant cannot forward the specified ports on this VM,since they
would collide with some other application that is already listening
on these ports. The forwarded port to 8080 is already in use
on the host machine.

To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

config.vm.network :forwarded_port, guest: 8000, host: 1234

Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding.
</pre></div></div>

ポートが被っていると言うがそんなはずは。

`netstat -aon | findstr 80`

該当なし。しばらく悩む。

とりあえず Vagrantfile のポート記述部分をコメントアウトして起動してみる。
うごいた。しかし、今度は linux 画面で以下のようなエラーが。
<div class="code-frame" data-lang="text"><div class="highlight"><pre>
Cheching filesystems
/dev/mapper/VolGroup-Lv_root: Superblock last mount time (Thu Jun 11 01:32:48 2015,
now = Mno Jun 8 01:50:43 2015) is in the future.
/dev/mapper/VolGroup-Lv_root: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
(i.e., without -a or -p options)
</pre></div></div>

あ～。
そういえばテストで日付を変えるときに windows の方を変えましたな。
もう一度 windows の日付をさらに先の日付に変えてみるといけました。
ついでに Vagrantfile も元に戻してみる。
うごいた。

**ポート関係なかった。**というお話でした。
あと、やっぱり自分がなんかしてた。
日付の根本的な解決方法はわからないので、休日ごとに詰めれるのを待つという対応。
VagrantfileにPostgresqlインストール追記。

よく使わせていただいている素敵な[scotch](https://box.scotch.io/)というVagrantBoxにPostgresqlを入れるシェルを追記。

~~~ ruby:Vagrantfile
Vagrant.configure("2") do |config|

  config.vm.box = "scotch/box"
  config.vm.network "private_network", ip: "192.168.11.11"
  config.vm.hostname = 'testsite.dev'
  config.vm.synced_folder 'www', "/var/www", :mount_options => ["dmode=777", "fmode=666"]
  config.vm.provision "shell", inline: <<-EOT
        # postgresqlのVer9.4を入れる準備
        echo deb http://apt.postgresql.org/pub/repos/apt/ wheezy-pgdg main > /etc/apt/sources.list.d/pgdg.list
        apt-get install wget ca-certificates
        wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
        apt-get update
        apt-get upgrade
        # インストール
        apt-get -yV install postgresql-9.4 postgresql-common postgresql-client-common php5-pgsql expect
        # linuxのpostgresユーザーにパスワード付与
        expect -c "
        spawn passwd postgres
        expect Enter\ ;  send pass\n;
        expect Retype\ ; send pass\n;
        expect eof exit 0
        "
        # linuxのpostgresでdbのpstgresのパスワード付与
        sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'pass';"
        # ローカルのMacから繋がるようにする
        echo "listen_addresses = '192.168.11.11'" >> /etc/postgresql/9.4/main/postgresql.conf
        echo "host postgres postgres 0.0.0.0/0 trust" >> /etc/postgresql/9.4/main/pg_hba.conf
        # 再起動
        /etc/init.d/postgresql restart
        /etc/init.d/apache2 restart
  EOT
end
~~~

Postgresql入りのBoxを探してもいい感じのなかったのでシェル使いました。
Herokuが本番なら開発もPostgresqlで行きたいですよね。
hamlをjadeに変換する


RubyのHTMLテンプレートエンジン[Haml](http://haml.info/)のファイルを、JSのテンプレートエンジン[Jade](http://jade-lang.com/)に変換する方法

テンプレート機能 (変数を入れるとか) を使わずに、ただのalt-HTMLとして使っているなら、かなり簡単に自動変換できる。

## 準備

```
gem install haml
npm install -g html2jade
```

## 変換

一旦 `haml` コマンドを使ってHTMLに変えたあと、`html2jade` コマンドでJadeに変える。


```ruby:haml2jade.rb
Dir.glob("./**/*.haml").each do |haml|
  jade = haml.gsub(/\.haml$/, ".jade")
  `haml #{haml} --style ugly | html2jade --donotencode --noemptypipe --bodyless > #{jade}`
end
```

* `haml --style ugly` でインデントなしのHTMLを出力
	* 余計な空白をできるだけ無くす
* `html2jade --donotencode --noemptypipe --bodyless`
	* 日本語などをエンコードしない
	* `|`だけの空行が出来るのを防ぐ
	* いらない`html`, `body`タグが出来るのを防ぐ
枠線だけ色のついたフキダシをCSSで作る

# 今回作るもの

枠線の色が**#000000**、フキダシ内の色が**#FFFFFF**になっているフキダシをCSSのbefore要素、after要素を使って作ります。
「吹き出しの背景色と枠線の色が違う」みたいなデザインを形にする時に使ってみると良いかもしれません。

# 完成デモ
https://jsfiddle.net/2ubgs38e/

# 作成手順

##① フキダシにしたい要素を作成
 
```html
<div class="balloon">
    <!-- フキダシ文言等を挿入 -->
</div>
```

##② 白の三角形、黒の三角形を作る

```css
.balloon:before,
.balloon:after {
    position: absolute;
    left: 50%;
    top: 100%;
    border: solid transparent;
    content: '';
    height: 0;
    width: 0;
    border-width: 14px;
    margin: 0 0 0 -14px;
}
.balloon:before {
    border-top-color: #000000;
}
.balloon:after {
    border-top-color: #FFFFFF;
}
```

※margin-leftで位置をずらしているのは、中央揃えにするためです。作りたい見た目に応じて、この辺りは調整してください。

##③ 白の三角形の位置をずらして、フキダシ線を表現する

```css
.balloon:before {
    border-top-color: #000000;
    margin-left: -14px;
}
.balloon:after {
    border-top-color: #FFFFFF;
    margin: -1px 0 0 -14px;
}
```

手順②の時点で重なっていた2つの三角形の内、白の三角形をmargin-topのネガティブマージンでずらします。
今回はフキダシのborder-widthが1pxなので、-1pxだけずらします。

# 備考
CSSのtranslateプロパティを使って作ることも出来ますが、今回はIE8をサポートするケースを考慮し、before要素とafter要素のみで作成してみました。 

ツッコミ、ダメ出し歓迎です。

おわり
AppleScriptでスクリーンセーバを呼び出す


AppleScriptでスクリーンセーバを呼び出すには、
下記のようにスクリプトエディタで書きます。

```AppleScript:screensaver.scpt
tell application "System Events"
	set ss to screen saver "Flurry"
	start ss
end tell
```

Automaterにサービスとして登録すれば、
キーボードショートカットに登録できるので簡単に呼び出せます。

また、システム環境設定のセキュリティとプライバシーにある
「スリープとスクリーンセーバの解除にパスワードを要求」を設定すれば
画面のロックもすることができるので便利です。