OmniAICreator/Qiita-1.07M huggingface dataset:
Array#uniq! は重複要素が削除されなかった場合 nil を返す


```
def uniq_array
  
  ~ 配列にセットする処理 〜

   ary.uniq!
end

```

上記のような、取得した値を配列にセットして最後に重複を削除して返す処理を書いてたんですが、どうもある場合に ```nil``` が返ってきていました。

[マニュアル](http://docs.ruby-lang.org/ja/2.0.0/method/Array/i/uniq.html)を見てみると原因が書いてありました。

```
uniq は配列から重複した要素を取り除いた新しい配列を返します。 uniq! は削除を破壊的に行い、削除が行われた場合は self を、 そうでなければnil を返します。
```
確認してみます。

``` 
[1] pry(main)> ary1 = %w(1 2 3)
=> ["1", "2", "3"]
[2] pry(main)> ary2 = %w(1 1 3)
=> ["1", "1", "3"]
[3] pry(main)> p ary1.uniq
["1", "2", "3"]
=> ["1", "2", "3"]
[4] pry(main)> p ary2.uniq
["1", "3"]
=> ["1", "3"]
[5] pry(main)> p ary1.uniq!
nil
=> nil
[6] pry(main)> p ary2.uniq!
["1", "3"]
=> ["1", "3"]
```
重複が無かった場合に 破壊的メソッドは ``` nil ``` が返ってます。
そもそも、配列を返してを使うんだから、破壊的メソッド ```uniq!``` を使う必要はなかったんですが。。。
ntpdとntpdateを同時に実行する方法


##経緯
Qiitaを最近書き始めるようになり、過去の対応内容を見返していました。
改めて記事を書こうと思い、調べてみるともっとよい方法が見つかったので、共有したいと思います。

※ そもそもntpdとntpdateを共存させる必要あるの？という面は、ここでは述べません。

##当時の対応

```
the NTP socket is in use, exiting
```

上記メッセージがサーバから届き、調べてみると同時には実行できないとのこと。
当時は「2つも時刻合わせはいらないね」ってことで、1つだけにしました。

##ntpdとntpdateは同時実行できない!?

この記事を書いていて、検証も兼ねてサーバで実験してみました。
環境：CentOS 5.9 (Final)

```
#  service ntpd status
ntpd (pid  2471) を実行中...
# ntpdate (NTPサーバ)
 4 Mar 23:49:38 ntpdate[24301]: the NTP socket is in use, exiting
```

確かに、今でも実行できません。
では、こうすると

```
# ntpdate -u (NTPサーバ)
 4 Mar 23:56:42 ntpdate[24400]: adjust time server 202.224.32.4 offset -0.000102 sec
```

実行することができました！

```
# man ntpdate
-u      Direct ntpdate to use an unprivileged port for  outgoing  packets.  This  is  most  useful when behind a firewall that blocks incoming traffic to privileged ports, and you want to  synchronize  with  hosts  beyond the firewall. Note that the -d option always uses unprivileged ports.
```

-u オプションを付けることで、ntpdが使用しているポートとは、別のポートを利用して同期を実行してくれるとのこと。

とても勉強になりました！

参考記事(感謝!)：
元RX-7乗りの適当な日々
[ntpdが動いている環境で、ntpdateを実行する](http://d.hatena.ne.jp/rx7/20100921/p1)
jQueryで簡易EventEmitterもどき

```js
var a = $({});

a.on('customEvent1', function(event, b, c, d) {
  console.log(b, c, d);
});
a.trigger('customEvent1', [1, 2, 3]);  // 1 2 3

a.one('customEvent2', function(event, b, c, d) {
  console.log(b, c, d);  // 1 2 3
});
a.trigger('customEvent2', [1, 2, 3]);  // 1 2 3
a.trigger('customEvent2', [1, 2, 3]);  // 
```

ブラウザでEventEmitter的なもの使いたいなあ……とjQueryで適当にやってみたら動いた。
ちょっとしたところで使うにはまあまあ良いのでは！？とは思いつつもどうなんだろうなーとも。

素直に[ブラウザ向けのEventEmitter](https://github.com/Wolfy87/EventEmitter)使った方がいいかなあ。
非表示要素はCapybaraのfindで検索対象になるのか


`display: none` で非表示にした要素は、Capybaraのfindやallの検索対象になるのでしょうか？

結論からいうと、「デフォルトでは非表示要素は検索対象にならない」です。

リファレンスを見ると下記の記述があります。

[Module: Capybara::Node::Finders](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders)

>  visible (Boolean) —
> Only find elements that are visible on the page. Setting this to false finds invisible andvisible elements.

つまり、visibleオプションを付けることでfindの動作を変えられるということです。要約すると以下のようになります。

```
visible: true  #=> display: noneのものは検出しない
visible: false #=> display: noneでも検出する
```

## visibleオプションはどちらがデフォルト？

ただ、この記述ではどちらの状態がデフォルトなのかわかりません。
そこでソースを見に行ってみます。

[lib/capybara/query.rb](https://github.com/jnicklas/capybara/blob/master/lib/capybara/query.rb)

`def visible`ありますね。`visible`オプション指定がないときは、
`Capybara.ignore_hidden_elements`を見て判定しているようです。

こいつは[lib/capybara.rb](https://github.com/jnicklas/capybara/blob/master/lib/capybara.rb)にありました。

> [ignore_hidden_elements = Boolean]  Whether to ignore hidden elements on the page (Default: true)

デフォルトはtrueなので、見えないものは探さないってことになります。つまり、

```
visible: true  #=> display: noneのものは検出しない（デフォルト）
visible: false #=> display: noneでも検出する
```

ということですね。

## おまけ
### デフォルト動作の設定

Capybaraのデフォルトの動作を変えたければ、`ignore_hidden_elements`を予め変更してあげれば良いのです。
つまり、spec全体で非表示要素も検索対象に加えたければ、spec_helper等で次のように定義します。

`Capybara.ignore_hidden_elements = false`


### visibleオプションは色々なところで使える

visibleオプションは他のマッチャーなどでも使えます。

```
have_selector('.hoge', visible: false)
```

のようにすることで、非表示要素であってもspecの対象にすることができます。


###「非表示であること」のテスト

下記のように記述すると非表示なのか、そもそも存在しないのかが区別できません。

```
expect(page).not_to have_selector('.hoge')
```

従って、`visible: false`を使って以下のようにすると良い感じです。

```
expect(find('.hoge', visible: false)).not_to be_visible
```

--


※以上は、もともとblogで書いた記事をQiitaに移植したものです。個人的に何度も役に立っているので。

http://upinetree.hatenablog.com/entry/2014/01/21/231953
windowsの開発環境は一瞬で整うwith chocolatey

windowsの開発環境はpower shellの入っている環境なら手作業をほとんどなくして整えることが可能だ。
`chocolatey`を使います。インストールするのはピカイチに簡単。コマンドプロンプトから以下をコピペして実行してね。

```bat
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
```

勝手にインストールが始まるから放置しとく、結構すぐ終わった気がする。
Windows updateを怠ってたりすると.NETがねぇよって言われることあるけど再起動したら勝手に入ってた。
ちなみにホームページは[Chocolatey Gallery](https://chocolatey.org/)です。

`chocolatey`はmacでいうhomebrewとかdebian,ubuntuでのapt-getといったパッケージ管理ソフトなんだけど、こいつの真価はxml形式で記述したファイルを使えば簡単にインストールするパッケージを管理できることだと思う。
だから以下のようにひとつずつインストールする必要などない。

```bat
cinst vim
chocolatey install vim
```

みたいな感じで、どちらでもインストールできるだけど、コマンドプロンプトの実行時のディレクトリにxmlファイルがあれば一瞬だし後からも分かりやすい。

```xml:packages.config
<?xml version="1.0"?>
<packages>
    <package id="GoogleChrome" />
    <package id="Firefox" />
    <package id="Gpg4win" />
    <package id="ctags" />
    <package id="curl" />
    <package id="git" />
    <package id="hg" />
    <package id="dropbox" />
    <package id="mingw" />
    <package id="mingw-get" />
    <package id="nodejs" />
    <package id="python" />
    <package id="python3" />
    <package id="ruby" />
    <package id="Everything" />
    <package id="Apple_iCloud_Control_Panel" />
    <package id="winmerge" />
    <package id="Desktops" />
    <package id="imagemagick" />
</packages>
```

idにインストールしたいパッケージを記述しておけばオーケーです。あとは

```bat
cinst packages.config
```

これだけでxmlに記載されているパッケージを全てインストールして、PATHも設定してくれる。
これでそれぞれのWebページに訪れてひとつひとつインストールする作業は一気に楽になるよね。

パッケージ一覧については

```bat
chocolatey list
```

で取得できるので、ここから必要なパッケージをダウンロードするといいよ。

パッケージを更新する場合は

```bat
chocolatey upgrade
```

でアップデートできます。
jQuery.notifyBarでCakePHPのフラッシュメッセージを表示させる

CakePHP+jquery.notifyBar

どっちも自分的にはよく使うので
備忘録として。

View/Layoutファイルに記述しておくと以後あまり意識しなくてすむ。

Session->flash() でメッセージを取得して
あとはjsでかきこんでやる。

ポイントとしてはerrorの時はnotifyBarを勝手に閉じないようにすることと、CSSクラスをかえてやること。
もっと状況でやりようはあるけど、とりあえず。
AppContorller に
 
```php:
function _flashSucess($message) {
$this->Session->setFlash($message,'default', array('class' => 'success'));
}
function _flashError($message) {
$this->Session->setFlash($message,'default', array('class' => 'error'));
}
```

というように作っておくと汎用的に使いやすいかも。
$messageは、メッセージ内容によるがどっかでエスケープしとかないと
クォートが重なってjavascriptのエラーがでることも。

```php:フラッシュメッセージ取得
<?php
$flashMsg = $this->Session->flash();
?>
```

```js:notifyBar
<script>
$(function() {
	<?php if(!empty($flashMsg)) : ?>
		var msg = '<?= $flashMsg ?>';
		var close = false;
		var cssClass = 'success';
		if(msg.match(/error/i)) {
			close = true;
		}
		$.notifyBar({
			html: msg,
			close: close,
			cssClass: cssClass
		});
	<?php endif ?>
});
</script>
```
APIがフック(detour形式)されてるなと思ったら


1. windbgを起動

2. フックされていると思うプロセスにアタッチ

3. 以下のコマンドを叩く

```
0:001>!chkimg <モジュール名> -d
```

例えばntdllのAPIがフックされていると思ったら

```
0:001>!chkimg ntdll -d
```

多分IATフックの場合は上記のコマンドじゃわからないと思う
UITabBarControllerのTabBarItemのタイトルが勝手に変わってしまう場合の対処

UITabBarControllerに設定したUINavigationControllerのrootViewController内で

self.title = @"hoge"

とすると、TabBarItemのタイトルも連動して変わってしまいます。
NavigationBarのタイトルは変更したいけど、TabBarItemのタイトルを変えたくない場合は

self.navigationItem.title = @"hoge"

を使いましょう。
tmuxとMacVimでOS Xのクリップボードと連携

# 概要

[MacVimでコピーした文字列が自動的にクリップボードに入るようにしたい(:set clipboard=unnamed) - 結城浩のはてな日記](http://d.hatena.ne.jp/hyuki/20130803/vim)と[tmuxでOSXのクリップボードと連携 - Qiita](http://qiita.com/kenjiskywalker/items/a138a1af836f11e51ae8)を見て、これは便利と両方設定したらtmux上のvimでコピーしてもクリップボードに入らないことに気づきました。

で、ググってみると
[Sharipov Ruslan : tmux 1.8 + vim/MacVim: easy OSX clipboard integration](https://coderwall.com/p/g-d8rg)というページを見つけました。

```
alias vim="reattach-to-user-namespace vim"
```

とエイリアスを定義しておけば良いとのことです。

# セットアップ

reattach-to-user-namespaceはhomebrewでインストールします。

```
$ brew install reattach-to-user-namespace
```

tmux.confの設定は以下のようにします。tmuxのプリフィクスをC-zに変更しています。

```~/.tmux.conf
# Set prefix to C-z
unbind C-b
set-option -g prefix C-z
bind C-z send-prefix

# Use vim keybindings in copy mode
setw -g mode-keys vi

# Setup 'v' to begin selection as in Vim
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe
unbind -t vi-copy Enter
bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"
```

~/.vimrcには以下のように設定します。

```~/.vimrc
set clipboard=unnamed,autoselect
```

~/.bashrcには以下のように設定します。

```~/.bashrc
alias vim='reattach-to-user-namespace /Applications/MacVim.app/Contents/MacOS/Vim'
```

# コピーの操作方法

* tmuxでコピー
    * 範囲の選択開始: ```C-z [ Space```
    * 範囲選択: ```hjkl```や```0```や```$```など
    * コピー実行: ```Enter```
* vimでコピー
    * 範囲の選択開始: ```v```
    * 範囲選択: ```hjkl```や```0```や```$```など
    * コピー実行: ```y```
RubyMotionでDeployGateを利用する

と言っても、ほとんどやってることはこちらと一緒です。
[DeployGateでiOSアプリを配布する方法 - Qiita](http://qiita.com/k_kinukawa/items/bbb3e98239e51fc3c803)

RubyMotionの場合、ipaファイルを作成するのは[元々コマンド一発](http://rubymotion.jp/RubyMotionDocumentation/guides/project-management/index.html#_distribution)でできるので↓と同じようなことをする時もめっちゃ楽です。

[Xcode - iPhoneアプリをmakeコマンド一発でビルドしてDeployGateで自動配布する方法 - Qiita](http://qiita.com/k_kinukawa/items/42c240a9e9e8b6cb4923)

こんな感じ。簡単ですね！

```bash
#!/bin/bash
rake archive && \
dgate push ainame build/iPhoneOS-7.0-Development/deploygate-sample-app.ipa
```

＊まだベータ版のようですが、今のうち参加すると、今後も無料で使い続けられるそうです。
[DeployGate - Beta Program](https://deploygate.com/beta_program)
MacのRubyのバージョンを 2.1.1 に上げてみた


##brew & ruby-build のアップデート
```
brew update
brew upgrade ruby-build
```

でも新しいruby2.1.1が表示されない。

```
rbenv install -l

...
2.0.0-rc1
2.0.0-rc2
2.1.0-dev
2.1.0-preview1
jruby-1.5.6
...
```

##ruby-buildを最新の状態にする
githubからpullする。

```
cd ~/.rbenv/plugin/ruby-build
git pull origin master
```

表示された。

```
rbenv install -l

...
2.1.0-rc1
2.1.1
2.2.0-dev
...
```

##rbenv で ruby2.1.1 をインストール
`rbenv` でインストール。

```
rbenv install 2.1.1
```

ちゃんとインストールされたか確認。

```
rbenv versions

  system
  1.9.3-p392
  1.9.3-p448
* 2.0.0-p247 (set by /Users/masamitsu/.rbenv/version)
  2.1.1
```


##ruby2.1.1 をデフォルトのバージョンに設定

```
rbenv global 2.1.1

rbenv versions

  system
  1.9.3-p392
  1.9.3-p448
  2.0.0-p247
* 2.1.1 (set by /Users/masamitsu/.rbenv/version)
```

ちゃんと変更されてます。


##アプリで使ってない古いバージョンをuninstall

```
sudo rbenv uninstall 1.9.3-p392
sudo rbenv uninstall 1.9.3-p448
```
ベーシック認証で8文字までしかパスワードが有効にならない問題

某所にBasic認証を設定したところ、パスワードの先頭8文字がマッチしていれば認証が通るという摩訶不思議現象に悩まされまして、そのメモ。

結論から言うと、オプション指定なしでhtpasswdコマンドを利用してパスワードを生成すると、上記のような現象となる。

http://httpd.apache.org/docs/2.2/programs/htpasswd.html
> -dコマンドを利用するとcrypt()を利用してパスワードを生成する。
> これは最大8文字まで利用するという制限があって、httpd2.2.17までは標準で利用されていた。

参考までに、PHPでも同様の問題がある。
http://php.net/manual/ja/function.crypt.php

> 標準の DES ベースの場合、crypt() はstr の最初の 8 文字しか使用しません。
> つまり、最初の 8 文字が同じである長い文字列は、 同じ salt を使う限り同じ結果となります。

## 対応方法

以下のオプションを利用しましょう

> -m Use MD5 encryption for passwords. This is the default (since version 2.2.18).
> -s Use SHA encryption for passwords. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif).

ただ、md5もshaも、パスワード管理としては強度弱かったような気がするんだけど、どうなんだろうねー。
日本語入力モードをいろんなキーを起点に解除する。


いろいろなところで日本語入力モードがONになったままの不幸を味わったので、とりあえず解除の起点となりそうで、かつ、日本語入力では使わないキーを解除のキーにしてみた。

CTRLとか人によってはモード切り替えで使いそうなのでなんですが…

Keyremap4Macbookをいれて、private.xmlに以下を追加して有効化。

```xml 
<item>
	<name>Key with EISUU</name>
	<identifier>private.key_with_eisuu</identifier>
	<autogen>--KeyToKey-- KeyCode::CONTROL_L,  KeyCode::JIS_EISUU,  KeyCode::CONTROL_L</autogen>
	<autogen>--KeyToKey-- KeyCode::Q,   KeyCode::JIS_EISUU,  KeyCode::Q </autogen>
	<autogen>--KeyToKey-- KeyCode::ESCAPE,  KeyCode::ESCAPE,  KeyCode::JIS_EISUU</autogen>
	<autogen>--KeyToKey-- KeyCode::J,  VK_CONTROL,  KeyCode::J,  VK_CONTROL,  KeyCode::JIS_EISUU</autogen>
</item>
```
PlayFramework2.x ログの設定でSyslogAppenderを使う

2系からPlay frameworkのロギングがlog4jではなくlogbackになっています。

http://logback.qos.ch/

AppenderとLoggerの設定をおこなうという設定方法の概念はlog4jとあまりかわらないのでlog4jを触ったことがあればすんなり受け入れられると思います。

Appenderは下記URLで標準のものをチェックできます。
よく使うのはFileやSyslogでしょうか。

http://logback.qos.ch/manual/appenders.html

playで設定するにはconf/logger.xmlを作成します。
LOCAL3で出力する場合は下記のように書きます。

```xml:conf/logger.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel" />
  <appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
    <syslogHost>localhost</syslogHost>
    <port>514</port>
    <facility>LOCAL3</facility>
    <suffixPattern>%date - [%level] - [%thread] %logger %msg</suffixPattern>
  </appender>
  <logger name="play" level="INFO" />
  <logger name="application" level="INFO" />
  <root level="INFO">
    <appender-ref ref="SYSLOG" />
  </root>
</configuration>
```


違う名前にしたい場合は起動オプション-Dlogger.xxxxを指定します。
xxxxの部分にはresource, file, urlを利用できます。

```shell-session:command
./target/universal/stage/bin/[yourapp] -Dlogger.resource=logger-prod.xml
```

**SyslogAppenderはTCPでログを転送します**。syslogサーバで受け取る側がplay起動時にTCPで待ち受けていて接続可能である必要があります。

rsyslogの場合は/etc/rsyslog.confに下記の設定を追加してあらかじめrsyslogを再起動しておく必要があります。

```php:/etc/rsyslog.conf追記TCP+UDP待ち受けとlocal3出力
$ModLoad imudp
$UDPServerRun 514
$InputTCPServerRun 514

local3.*     /var/log/myapp.log
```

これでログローテーションを設定、Fluentdでソースを上記ファイルにして運用すると楽です。
Fluentd用のAppenderなどあればその方が効率がいいのかもしれませんがrsyslogの実績を考えると当面この方が安心です。
17歳で年齢を計算する。

Ushio@githubさんの投稿「ゆかりんの年齢を計算する」
http://qiita.com/Ushio@github/items/88e42961ad3b78acd837
のネタにあいのりです。
あまりテストとかしていないです。間違っているかも？？？
エラー処理もないです。

```java:BD17.java
import java.util.Calendar;

public class BD17 {
    private final static int bdY = 1976;
    private final static int bdM = 2;
    private final static int bdD = 27;

    private final static int age = 17;
    
    public void showBD17() {
        Calendar nowCal = Calendar.getInstance();

        Calendar bdCal = Calendar.getInstance();
        bdCal.set(Calendar.YEAR, bdY);
        bdCal.set(Calendar.MONTH, bdM - 1);
        bdCal.set(Calendar.DATE, bdD);
        int m = 0;
        int d = 0;

        bdCal.add(Calendar.YEAR, age);
        while (bdCal.get(Calendar.YEAR) != nowCal.get(Calendar.YEAR) || bdCal.get(Calendar.MONTH) != nowCal.get(Calendar.MONTH)) {
            bdCal.add(Calendar.MONTH, 1);
            m++;
        }
        if (bdCal.get(Calendar.DATE) > nowCal.get(Calendar.DATE)) {
            bdCal.add(Calendar.MONTH, -1);
            m--;
        }
        while (bdCal.get(Calendar.DATE) != nowCal.get(Calendar.DATE)) {
            bdCal.add(Calendar.DATE, 1);
            d++;
        }

        System.out.printf("%d歳%dヶ月%d日", age,m,d);
    }
}
```
CUDAのnsightが重い！とcomputeprofが動かない！問題への対処法

CUDAを使って開発しているときにnsightやcomputeprofを使えると非常に便利ですが、手元の幾つかの環境でnsightが重くてまともに使ってられない、computeprofに至ってはそもそも動かないという状況になったので対処法をまとめておきます。ただし、この対処法でもしばらくすると落ちることが頻繁にあるので、だれかもっと良い方法を知っていたら是非教えて下さい。

#nsightの対処法
nsightはEclipseベースなのでよくあるEclipseが重い！問題と同じ解決方法で対処できます。
CUDAのインストールディレクトリのlibnsight/nsight.iniを以下のようにします。

```text:nsight.ini
-showsplash
org.eclipse.platform
--launcher.defaultAction
openFile
-vm
../jre/bin/java
-vmargs
-Dosgi.requiredJavaVersion=1.6
-Xms256m
-Xmx1024m
-XX:MaxPermSize=256m
-XX:CompileCommand=exclude,java/lang/reflect/Array,newInstance
```

何をしたかというと-Xm～を書き換えてJVMで使うメモリサイズを増やしただけ。これで動作は快適になります。ただし、最初に書いたように環境によっては結構落ちます。

#computeprofの対処法
computeprofも上と同じようにすると起動できます。
CUDAのインストールディレクトリのlibnvvp/nvvp.iniを以下のようにします。

```text:nvvp.ini
-data
@user.home/nvvp_workspace
-vm
../jre/bin/java
-vmargs
-Xms256m
-Xmx1024m
-XX:MaxPermSize=256m
```

これでとりあえずは動きます。
これで非常に見やすいcomputeprofが使い放題です。
ある期間(A)に変更されたファイルのうち、ある期間(B)に変更されているものを抜き出す


期間AのコミットIDの開始〜終了を A1, A2 、期間Bを B1, B2 で表す。

```
git diff A1..A2 --name-only | xargs git diff B1..B2 --name-only
```
アプリ作るときのコンセプト

#Who is your audience? 
Your app content and experience will differ depending on whether you’re writing a children’s game, a to-do list app, or even a test app for your own learning.

#What is the purpose of your app?
 It’s important for an app to have a clearly defined purpose. Part of defining the purpose is understanding what one thing will motivate users to use your app.

#What problem is your app trying to solve?
 An app should solve a single problem well instead of trying to offer solutions to multiple distinct problems. If you find that your app is trying to solve unrelated problems, you might consider writing multiple apps.

#What content will your app incorporate? 
Consider what type of content your app will present to users and how they’ll interact with it. Design the user interface to complement the type of content that’s presented in the app.

[Start Developing iOS Apps Today](https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/AppDevelopmentProcess.html#//apple_ref/doc/uid/TP40011343-CH4-SW1 "Start Developing iOS Apps Today")
Typesafe Activatorを使ってPlay2のProjectを作成してHerokuで動かす


はじめに
=======

ちょっとJavaのライブラリをWebService化したいと思ってせっかくなので PlayFramework2(以下、play2)をやってみようと思いました。
ただ、play2を始めるまでに、sbtとか色々準備しなきゃなのかなーと思っていたら、良い意味で裏切られまして、異様に簡単でした。
最初のDownloadの時間とかはそこそこかかりますが、作業自体は非常に少なくて済みます。
[Typesafe Activator](http://typesafe.com/activator) というのがとにかくすごかったです。

事前準備
---------

以下のものが既に入っているとします。

* JDK1.6 or 1.7 
* [heroku toolbelt](https://toolbelt.heroku.com/) 
* herokuにアカウント（すぐに作れます）

Versionなど
----------

今回試した環境のVersionです。

* MacOSX: 10.9.2
* Typesafe Activator: 1.0.13 
* play 2.2.1 built with Scala 2.10.2 
* JDK1.7: build 1.7.0_51-b13
* heroku: heroku-gem/2.20.1 

手順
======

Typesafe Activator で play2の雛形を作る
-----------------

### Step1
http://www.playframework.com/download の左側に `Download Activator 1.0.13 (256MB)` 等とある部分からZIPファイルをDownloadして、適当なDirに展開します。

### Step2

その中にある `activator`というファイルを実行します。
しばらくすると、勝手にブラウザに

![スクリーンショット 2014-03-04 17.53.49.png](https://qiita-image-store.s3.amazonaws.com/0/11124/f14bd0ff-cc83-88de-fa35-7281d981008f.png "スクリーンショット 2014-03-04 17.53.49.png")

という画面が表示されます。

### step3

この中の
![スクリーンショット 2014-03-04 17.54.27.png](https://qiita-image-store.s3.amazonaws.com/0/11124/003bbb97-eca9-ed6b-a86e-4c8649f646e4.png "スクリーンショット 2014-03-04 17.54.27.png")
の部分で、下のリストから 「`Hello Play Framework!`」 というのを選んで、下の「`CREATE`」ボタンを押します。

### step4
またしばらくすると、勝手にブラウザが開き、
![スクリーンショット 2014-03-04 17.58.17.png](https://qiita-image-store.s3.amazonaws.com/0/11124/6911e7d5-a99a-ba1c-244e-6780acd0a2ac.png "スクリーンショット 2014-03-04 17.58.17.png")

というような画面が表示されます。

これで`Run the app`とかするとまず、Local環境でplayのhello world的なものが実行できてしまいます。
単体テストやソースコードの編集もWebブラウザからできます。
IDEAやEclipseのProjectファイルもWebブラウザでボタンを押せば作成されます。

げに恐ろしい話です。

HerokuのApp用の設定をする
------------------

[HerokuのDocument](https://devcenter.heroku.com/articles/getting-started-with-play)自体少し古い気がするので、必要のない作業もあるかもしれませんが、今回は下記の手順でOKでした。

まず、先ほどProjectを作ったDirに行きます。

### Procfileの作成
```text:Procfile
web:    target/universal/stage/bin/hello-play -Dhttp.port=$PORT
```

`hello-play`の部分は Project名になるそうです。
参考： http://qiita.com/kazumax1027/items/9c8f6bee723eee598c55

### conf/dependencies.yml

```yml:conf/dependencies.yml 
# Application dependencies

require:
    - play 2.2.1
```

### system.properties

これはJava1.7を使うときのみ必要です。（そうでなければjava1.6になります）

```text:system.properties  
java.runtime.version=1.7
```

HeorkuにPushする
===============

Project作成
-----------

```bash:cmd
heroku login
heroku create
```


Push
-----

```bash:cmd
git init
git add .
git commit -m init
git push heroku master
```

Webサイト確認
----------

下記のコマンドでブラウザでPushしたサイトが開きます。

```bash:cmd
heroku open
```

これは便利ですねー


余談
====

ちなみにですが、playのconsoleなどには下記のコマンドで入れます。

```bash:cmd
./activator play
```
複数ファイルからgrep置換する


```console
find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;
```

mac だと
`invalid command code`
とかエラー吐かれるようなので、

```console
find /path/to/files -type f -exec sed -i "" 's/oldstring/new string/g' {} \;
```

だとOKだった。

`illegal byte sequence`　で怒られる場合は

```console
export LC_CTYPE=C 
export LANG=C
```

するとうまくいった。
Unity Cache Serverで他のチームに差をつける


Unityでチーム開発をしている開発者のみなさん、Cache Serverは使ってますか？
Asset Serverからの更新時など、ファイルのインポートが速くなるので、開発効率がかなり変わってきますよね。

しかしこのCache Server、コマンドラインのプログラム(中身はNode.jsで動作するJavascript)しかないので、サーバーで起動するとターミナルを閉じたり、ログオフしたりすることができなくなってしまいます。

これはダサい。はやくなんとかしないと…。

というわけでCache Serverをデーモンとして常駐させるインストーラーを作成しました。
Mac OS X用です。

# インストール方法

はいこれ！

```
$ curl -s https://raw.github.com/tnayuki/unitycache-osx-installer/master/install.sh | sudo bash -s http://netstorage.unity3d.com/unity/CacheServer-4.3.4.zip
Password: <パスワード>
Downloading Unity Cache Server...
Installing Unity Cache Server...
Creating group for Unity Cache Server...
Creating user for Unity Cache Server...
Starting Unity Cache Server...
```

コマンド一行でUnity Cache Serverがインストール・常駐します。
各種stlコンテナでのループ中の要素の削除


remove_if使えよと言われればそれまでですが普段使う感じだとループ中に消したりする事が多いので…


## vector

```
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);

vector<int>::iterator it = v.begin();
while (it != v.end()) {
	if (*it == 20) {
		it = v.erase(it);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << *it << endl;
	++it;
}
```

## deque

```
deque<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);

deque<int>::iterator it = v.begin();
while (it != v.end()) {
	if (*it == 20) {
		it = v.erase(it);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << *it << endl;
	++it;
}
```

## list

```
list<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);

list<int>::iterator it = v.begin();
while (it != v.end()) {
	if (*it == 20) {
		it = v.erase(it);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << *it << endl;
	++it;
}
```

## map

```
map<int, int> v;
v[10] = 10;
v[20] = 20;
v[30] = 30;

map<int, int>::iterator it = v.begin();
while (it != v.end()) {
	if (it->second == 20) {
		v.erase(it++);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << it->first << " " << it->second << endl;
	++it;
}
```

## multimap

```
multimap<int, int> v;
v.insert(make_pair(10, 10));
v.insert(make_pair(20, 20));
v.insert(make_pair(30, 30));

multimap<int, int>::iterator it = v.begin();
while (it != v.end()) {
	if (it->second == 20) {
		v.erase(it++);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << it->first << " " << it->second << endl;
	++it;
}
```

## set
```
set<int> v;
v.insert(10);
v.insert(20);
v.insert(30);

set<int>::iterator it = v.begin();
while (it != v.end()) {
	if (*it == 20) {
		v.erase(it++);
	} else ++it;
}

it = v.begin();
while (it != v.end()) {
	cout << *it << endl;
	++it;
}
```

とここまでやったけどmultisetとかは多分同じなので以下略…。。。

---

おおまかにvectorとかdequeとかシーケンスコンテナと呼ばれる奴はeraseの帰り値にイテレーターを返すのでそれが次のイテレーターになる。

mapとかsetとかは連想コンテナと言われる奴っぽく、eraseしたイテレーターは無効なアドレスを察すらしいので、 `it++` を渡してイテレーターのコピーをしつつ要素を削除、かつイテレーターを勧める → コピーされたイテレーターを使って連想コンテナの要素を削除 というノウハウがあるらしい [ここがわかりやすかった](http://d.hatena.ne.jp/Ox8000ffff/20100225/1267201650)

---

たしかにこんな感じのコードを書くと違うっぽい。イテレーターの中身が書き変わってる。

```
cout << "OK" << endl;

{
	set<int> v;
	v.insert(10);
	v.insert(20);
	v.insert(30);
	
	set<int>::iterator it = v.begin();
	while (it != v.end()) {
		cout << *it << endl;
		
		if (*it == 20) {
			v.erase(it++);
		} else ++it;
	}
}

cout << endl;

cout << "NG" << endl;

{
	set<int> v;
	v.insert(10);
	v.insert(20);
	v.insert(30);
	
	set<int>::iterator it = v.begin();
	while (it != v.end()) {
		cout << *it << endl;
		
		if (*it == 20) {
			v.erase(it);
		}
		
		it++;
	}
}
```

## まとめ

多分eraseでイテレーターが帰ってきたら `it = v.erase(it);` で、voidだったら `if (XXX) { v.erase(++it); } else it++;` で、みたいな感じの覚え方でざっくり大丈夫

全然気にしたことなかったけど各所でイテレーターとかループ回す時は前++のほうが効率がいいって書いてあるのでこれから気をつけます
Mac OSでEnterpriseDBからGUIインストールしたPostgreSQLのサービス停止など

[EnterpriseDBからダウンロードしてGUIインストール](http://www.enterprisedb.com/products-services-training/pgdownload#osx)したPostgreSQLは、pgAdminなんかも入ってて楽なんだけど、サービスも自動起動するようになったりしてMacBook Airなんかのモバイルではちょっと電力的に不安を感じたりしたので止め方など。

## サービスの停止
PostgreSQLサーバーのdaemonが停止

    $ sudo launchctl unload /Library/LaunchDaemons/com.edb.launchd.postgresql-x.x.plist  

## サービスの削除
PostgreSQLサーバーの自動起動をやめる。削除ではなくバックアップとしてmvでもよい

    $ sudo rm /Library/LaunchDaemons/com.edb.launchd.postgresql-x.x.plist 

## 手動でのPostgreSQLサーバーの起動/停止
自動起動を停止したので、必要に応じてPostgreSQLサーバーを起動したい場合。

    $ sudo -u postgres pg_ctl -D /Library/PostgreSQL/x.x/data start
    $ sudo -u postgres pg_ctl -D /Library/PostgreSQL/x.x/data stop
iOSの標準キーボード上のジェスチャーを認識する方法

拙作のArrow Noteではキーボード上のジェスチャーを認識して利用しています。これをプライベートメソッドなどを使わずに実現する方法を開示致します。ただし、UIViewの階層を辿ることは非推奨なので、自己責任でお願いします。
以下ではプロパティのtextViewとgestureRecognizerはInterface Builderによって設定されるものとします。

```objc:Objective-C
@interface ViewController : UIViewController
@property IBOutlet UITextView *textView;
@property IBOutlet UIGestureRecognizer *gestureRecognizer;
@end

@implementation ViewController
-(void) viewDidLoad
{
    self.textView.inputAccessoryView
        = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
}

-(void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter]
         addObserver:self
            selector:@selector(keyboardDidShow:)
                name:UIKeyboardDidShowNotification
              object:nil];
    [[NSNotificationCenter defaultCenter]
         addObserver:self
            selector:@selector(keyboardWillHide:)
                name:UIKeyboardWillHideNotification
              object:nil];
}

-(void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter]
         removeObserver:self
                   name:UIKeyboardDidShowNotification
                 object:nil];
    [[NSNotificationCenter defaultCenter]
         removeObserver:self
                   name:UIKeyboardWillHideNotification
                 object:nil];
}

-(void) keyboardDidShow:(NSNotification*)notif
{
    [self.textView.inputAccessoryView.superview
        addGestureRecognizer:self.gestureRecognizer];
}

- (void)keyboardWillHide:(NSNotification*)notif
{
    [self.textView.inputAccessoryView.superview
        removeGestureRecognizer:self.gestureRecognizer];
}

@end
```
SeleniumでHTMLを出力する方法

# はじめに
* こんなときに役に立ちました
 * テストは手動でコンソールから実行すると成功するのに、Jenkinsから実行すると失敗する 
 * 目視で見ようかと思ったが、Jenkinsから実行するとブラウザがバックグラウンドで起動して見えない
 * かといってフォアグラウンドで実行する方法はググったが分からなかった 
 * 詰んだ orz...

# 現在表示しているページのHTMLを取得する
* 原始的ですが、Javascript式を挿入してgetElementほげほげで取得します
 * あとはputsで出力するなり、ファイルに書き出すなりすればブラウザでその決定的瞬間に出会えるのです

```rb
# idにdocが付いている要素があると仮定している
page.evaluate_script("document.getElementById('doc').innerHTML")
```

* page.evaluate_scriptの引数に指定したものがJavascript式として評価される
* ID以外にも要素の指定はタグ名やクラス名指定などでも可能

----

実はもっと簡単に取得する方法があるのかもしれない。。と思いながら記事書いてみました！

# ～ただの宣伝～
* [全国のSeleniumer必読](http://qiita.com/oh_rusty_nail/items/b8ba525d31ea7c522856)
* Seleniumerといっていますが、Selenium, SauceLabs, Travis, Jenkinsに関するノウハウ書いているのでよかったら参考にしてみてください
yum(rpm)インストしたパッケージのchangelogを確認する

yum使って新しいパッケージに鮮度維持してるけど、あのCVEの対策って入っているんだろうか、って際に確認する方法。

```bash
$ rpm -q --changelog {package名}
```


例えばCentOS 6.5にて、httpd-2.2.15-29で試したら下記が出てきた。

```bash
$ rpm -q --changelog httpd | head
* 火  8月 13 2013 Karanbir Singh <kbsingh@centos.org> - 2.2.15-29.el6.centos
- Roll in CentOS Branding

* 金  8月 02 2013 Jan Kaluza <jkaluza@redhat.com> - 2.2.15-29
- mod_dav: add security fix for CVE-2013-1896 (#991368)

* 月  4月 29 2013 Joe Orton <jorton@redhat.com> - 2.2.15-28
- mod_rewrite: add security fix for CVE-2013-1862 (#953729)

* 木  3月 07 2013 <jorton@redhat.com> - 2.2.15-27
$
```
VirtualBoxのVMのDISK増量


●環境

VirtualBox 4.2.10
Vagrant 1.3.5
guest-os ubuntu server 12.04
host-os osx mavericks

●背景

boxを4Gで作ったが、色々入れるとスグに半分消費。
なので、1G増量。

●作業内容

1.
VMのイメージ格納フォルダを調べる。
VirtualBoxマネージャーで対象VMの「設定」→「ストレージ」で、
イメージの格納パスを取得。
※osxで普通にインストールしたならここになる？
~/VirtualBox\ VMs/XXXX_xxxx
XXXXX：VM名
xxxx：なんかの通番

コンソールで、格納フォルダに移動。

2.
元のイメージをクローン（可変サイズイメージにする）
VBoxManage clonehd box-disk1.vmdk box-disk1_ex.vdi --format VDI --variant Standard

※元イメージをbox-disk1.vmdkとする
※vmdkファイルはそのまま、拡張する事ができない。なので、可変サイズのクローンを作成する必要がある。

3.
クローンイメージをリサイズ
VBoxManage modifyhd box-disk1_ex.vdi --resize 5120
※サイズはMBで指定（4G→5120M：5G）

4.
GParted、クローンイメージのマウントとVM起動

Gpartedのダウンロード
http://sourceforge.jp/projects/gparted/releases/

VirtualBoxマネージャーで対象VMの「設定」→「ストレージ」で、マウントし、VM起動。
※OracleVirtualBoxのスプラッシュが出ている時に、f12を押すと起動diskを選択出来る。

Gpartedで、diskを拡張して(割当はしない)、Gpartedシャットダウン
シャットダウン後、Gpartedのマウントを除去

5.
vm起動-ログインし、rootで作業

df -h
※拡張前のサイズを確認

fdisk -l
※対象diskの確認

lvextend -l +100%FREE 対象diskパス
※サイズ拡張

resize2fs 対象diskパス
※サイズ拡張反映(これしないと反映されない)

df -h
※拡張後のサイズを確認

6.
後処理。
2.の元イメージを削除。
win8　ストアアプリを出す前に・・

windows8向けのストアアプリを出す場合、以下を確認した方が良さそうです。

★ストアアプリの認定要件の確認
http://msdn.microsoft.com/ja-jp/library/windows/apps/hh694083.aspx

上記ページに記載がされています。

★ストアアプリ認定試験の実施
http://msdn.microsoft.com/ja-jp/library/windows/apps/hh694081.aspx

上記のテストキットを使って、APIのテスト・構成チェックなどを自動で行ってくれるようです。
Ansibleでuser作ったときのパスワードではまる

Ansibleのuserモジュールではユーザーを作成し、パスワードを設定することができる。このときパスワードにはハッシュを入力しないといけないそうな。
もちろん平文入れてました。
# userモジュールのパスワード設定方法：
お好みのパスワードをハッシュ化してからplaybookへどうぞ。
## パスワードをハッシュ化
```
python -c 'import crypt; print crypt.crypt("gitgit", "$1$SomeSalt$")'
$ $1$SomeSalt$WVHO24A0LENyKJQ9e7aI3/

```

## playbookに書く
``` user/tasks/main.yml
---
- name: create git user.
  user: name=git
        password=$1$SomeSalt$WVHO24A0LENyKJQ9e7aI3/
        groups="wheel"
```


## 参考
http://longkey1.net/blog/2014/01/22/ansible-add-user-password/
Ruby installer for Windows で gem install nokogiri

Ruby installer for Windows はここ http://rubyinstaller.org/downloads/ のバイナリです。

`gem install nokogiri` したとき、nokogiriのバイナリリリースがインストーラーのRubyバージョンより遅れていると、ソースからネイティブライブラリをビルドしようとして、libxml2 がないという例の問題が発生します。 http://www.kaoriya.net/blog/2013/03/29/

経緯的には、nokogiriが入らないとBerkshelfが使えないというのが問題になりました。vagrant-berkshelfプラグインが終わってるから何とかしたいのです。Vagrantはomnibusだけにして、レシピはホストOSであらかじめ取ってくるようにさせたかった。簡単だと思ったらWindowsですごい落とし穴が...


以下、nokogiri の面倒を、最小労力でなんとかしようとした手順です。

Rubyを `C:\Ruby200-x64` にインストールしていたとします。環境変数のPATHに `"C:\Ruby200-x64\bin"` が通っている前提です。


ダウンロードサイトからDevKit `DevKit-mingw64-*-*-sfx.exe` をダウンロードして `C:\Ruby200-x64-DevKit` に展開します。

Git Bash で DevKit を初期化します。

```
$ cd /c/Ruby200-x64-DevKit/
$ ruby dk.rb init
$ ruby dk.rb install
```

必要なライブラリをダウンロードして展開します。これは Git Bash でやります。DevKitのbashにはビルド以外のコマンドが全く入ってないからです。

```
$ cd /c/Ruby200-x64-DevKit/home/username/
$ mkdir libxml2
$ cd libxml2

$ curl -O ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz
$ tar xzf libxml2-2.9.1.tar.gz

$ curl -O ftp://xmlsoft.org/libxml2/libxslt-1.1.28.tar.gz
$ tar xzf libxslt-1.1.28.tar.gz

$ curl -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz 
$ tar xzf libiconv-1.14.tar.gz
```

DevKitの `msys.bat` を叩いてもうひとつシェルを開きます。

```
$ cd libxml2

$ cd libxml2-2.9.1
$ ./configure
$ make
$ make install
$ cd ..

$ cd libxslt-1.1.28
$ ./configure
```

ここでそのままmakeするとエラーになるので、手でパッチを当てます。まあ強引ですが急ぐので。

```diff
libxslt/security.c

- ret = mkdir(directory, 755);
+ ret = mkdir(directory);
```

再開

```
$ make
$ make install
$ cd ..

$ cd libiconv-1.14
$ ./configure
$ make
$ make install
$ cd ..
```

これでDevKitの `/usr/local` にいろいろ入るのでそのままDevKitのgemで...

```
gem install nokogiri --platform=ruby -- \
 --with-xml2-include=/usr/local/include/libxml2 \
 --with-xml2-lib=/usr/local/lib \
 --with-xslt-dir=/usr/local
 --with-iconv-dir=/usr/local
```

Git Bash から使いたいので

```
export PATH=/c/Ruby200-x64-DevKit/local/bin:$PATH
```

的なことを `.bashrc` かWindowsの環境変数でやっておきます。(DLLは `LD_LIBRARY_PATH` じゃないんですね)

あとは

```
$ gem install berkshelf
$ berks -v

Berkshelf (2.0.14)

Copyright 2012-2013 Riot Games
...
```

おめでとうございます。
RabbitMQ+Bunnyを使った優先度付きキュー

RabbitMQで優先度付きキューが必要だったのですが、http://www.rabbitmq.com/specification.html を見ても、２段階の優先度対応が planned の状態で結局まだ実装がない状態でした。

キューを複数用意して対応するのがよいのでは的な情報があったので、その考えをベースに自分の都合にあった優先度付きキューの実装をしたので、gem で公開しました。

  https://rubygems.org/gems/bunny_priority_queue
  https://github.com/kikumoto/bunny_priority_queue

言語は、ruby で bunny ライブラリに依存しています。

アイデアとしては、優先度別のキューを用意し、Consumerはすべてのキューを Subscribe して、メッセージの着信があったときに着信したキューより優先度の高いキューにメッセージないかをチェックし、あればそちらを処理、なければ着信したのを処理するようにしています。

また最優先以外のキューにTTLでタイムアウトを設定することで、キューにメッセージが一定時間滞留すると、Dead Letter Exchange 送りにして、１つ上の優先キューにメッセージを詰み直すということをしています。

インストールは Gemfile に

```rb
gem "bunny_priority_queue"
```

を書いて

```rb
bundle install
```

してください。

とりあえず Producer と Consumer で使う値をまとめておきます。別にこうである必要はないです。
なお、優先度の高い順に優先度の名前を付けておくことが必要です。

```rb:common.rb
# -*- coding: utf-8 -*-

EXCHANE_NAME = "sample_exchange"
QUEUE_PREFIX = "sample_queue"


PRIORITY_HIGH   = "high"
PRIORITY_NORMAL = "normal"
PRIORITY_LOW    = "low"

PRIORITIES = [
    PRIORITY_HIGH,
    PRIORITY_NORMAL,
    PRIORITY_LOW,
]
```

Consumer は以下のような感じです。

```rb:consumer.rb
# -*- coding: utf-8 -*-

require 'bunny_priority_queue'
require_relative './common.rb'

begin
  conn = Bunny.new.start
  exchange = conn.create_channel.direct(EXCHANE_NAME)

  q = BunnyPriorityQueue.create(
      QUEUE_PREFIX,
      PRIORITIES,
      exchange
  )

  q.bind

  q.subscribe(:block => true) do |delivery_info, properties, body|
    puts "routing_key: #{delivery_info.routing_key}"
    puts "properties : #{properties}"
    puts "payload    : #{body}"
  end

ensure
  conn.close
end
```

Producer は以下のような感じです。

```rb:producer.rb
# -*- coding: utf-8 -*-

require 'bunny_priority_queue'
require_relative './common.rb'

begin
  conn = Bunny.new.start

  exchange = conn.create_channel.direct(EXCHANE_NAME)

  q = BunnyPriorityQueue.new(
      QUEUE_PREFIX,
      PRIORITIES,
  )

  exchange.publish("normal", :routing_key => q.name(PRIORITY_NORMAL))
ensure
  conn.close
end
```

とりあえず、自分が必要な感じで作ってみたものですが、需要があれば幸いです。
まだまだ荒削り感たっぷりなので、適宜 Pull Req. などでガシガシ突っこんでください。
手軽にWebアプリケーションを作る。

#まず始めに

これを読めばこんなアプリケーションが作れるようになります。( http://milk-cocoa.github.io/chat/ )簡単なWebチャットアプリです。

![スクリーンショット 2014-09-02 20.55.59.png](https://qiita-image-store.s3.amazonaws.com/0/20848/dc4f5409-7265-716b-9d35-35227da60678.png)


このようなリアルタイムWebアプリケーションを作るには、例えばWebSocketという技術が必要です。WebサーバにNode.jsを利用したりします。データベースにMySQLを使うか、MongoDBなどのNoSQLを使うか。サーバをAWSにするか、HerokuやAzure等のPaaSを利用するか、考えなければいけません。そんな面倒なことを一切考えないで済む方法があるんです。milkcocoaを使いましょう。

milkcocoa : https://mlkcca.com/

( 弊社のサービスです ;) )

今回はmilkcocoaを利用した開発方法をご紹介しようと思います。

* 2015/5/2 追記 2015/5/7にmilkcocoaが新バージョンになるのに合わせて解説を変更しております。

#開発スタート

まずはhttps://mlkcca.com/ で開発者登録をしましょう。そして、ダッシュボードでアプリの登録をします。
![uploading detail.png...](https://dl.dropboxusercontent.com/u/6931359/qiita/detail.png)

「Javascriptで始めよう！」と書いてある場所のコードをコピーすれば準備環境です、今回はとりあえずmilkcocoaが用意してくれているサンプルソースを使ってみましょう。ソースコードはGithubにあります。この中で一番簡単な、chat(https://github.com/milk-cocoa/chat )を使ってみましょう。デモはこちら(http://milk-cocoa.github.io/chat/ )にあります。まずこのソースコードをZipなどでダウンロードします。次に"your app id"のところに、あなたがmilkcocoaで作ったアプリのapp idを入力します。（あなたが入力したものでなく、seai9xxxxxxのように自動生成されるものです。）


    var milkcocoa = new MilkCocoa("seai9xxxxxx.mlkcca.com");


とりあえず、これで動きます。
localhostでapacheなどのサーバをたてて動かすか、[bitballoon](https://www.bitballoon.com/) のようなホスティングサービスを利用して確認しましょう。HTMLファイルを直接ブラウザで開いても良いです。

次はソースコードを解説します。


#ソースコード解説

解説をするソースコードはこちら( https://github.com/milk-cocoa/chat/blob/master/index.html )です。1.から2.までの番号を付けてコメントを書いています。順番に説明していきます。

1.はmilkcocoaとの接続設定です。先ほど、ここのapp idを編集しましたね。milkcocoaで作成したアプリケーションIDとのひも付けを行います。

2.でmessageデータストアを作成します。たくさんのmessageを入れておく箱を作成するような感覚です。

    var ds = milkcocoa.dataStore("message");


3.でmessageがたくさん入るデータストアにクエリをかけます。コールバックでデータが返ってきます。

```js
//3."message"データストアからメッセージを取ってくる
ds.stream().sort("desc").next(function(err, datas) {
  datas.forEach(function(data) {
    renderMessage(data.value);
  });
});
```


4.では"message"データストアのプッシュイベントを監視します。つまり他の誰かが、このデータストアにデータをpushした時に、ここで登録したコールバックが呼ばれます。

    //4."message"データストアのプッシュイベントを監視
    ds.on("push", function(e) {
      renderMessage(e.value)
    });


5.はPostボタンが押されたときに実行します。データストアにメッセージデータをプッシュします。

    //5."message"データストアにメッセージをプッシュする
    ds.push({
      content : $("#content").val()
    });
    $("#content").val("");


これで簡単な解説は終わりです。
redirectActionでリクエストパラメータを含める方法

# RedirectActionの設定方法

1つのActionクラスから別のActionクラスへリダイレクトする方法として、resultの形にredirectActionがあります。以下に設定例を示します。

```java
@Namespace("/")
@Results({
	@Result(name = ActionSupport.SUCCESS,
			type = "redirectAction",
			params = {
				  "actionName" , "otherAction"
			}
	),
})
public class redirectAction extends ActionSupport {
	@Action("redirection")
	public String sampleRedirect() throws Exception {
		return SUCCESS;
	}
}
```

これにより、/redirection をリクエストすると、/otherAction へリダイレクトします。

# RedirectActionの特徴

リダイレクトなので、以下の特徴があります。

* リダイレクト元のActionとリダイレクト先のActionとではリクエストパラメータを共有しません。
* ブラウザに表示されるURLは、リダイレクト先のURLになります。

# 動的にURLも指定できる

Struts2の特徴として、設定値に変数を設定できます。
これはアノテーションでの設定でも同じです。

```java
@Namespace("/")
@Results({
	@Result(name = ActionSupport.SUCCESS,
			type = "redirectAction",
			params = {
				  "actionName" , "%{actionName}"
				  "namespace" , "%{namespace}"
			}
	),
})
public class redirectAction extends ActionSupport {
	@Action("redirection")
	public String sampleRedirect() throws Exception {
		return SUCCESS;
	}

	private String actionName;
	public String getActionName() {
		return actionName;
	}
	private String namespace;
	public String getNamespace() {
		return namespace;
	}
}
```

# リダイレクト先にリクエストパラメータを引き継ぐ方法

Actionアノテーションのparamsに、追加するパラメータ名と値の設定もできます。
もちろん変数も可能です。次の例は、リダイレクト先のリクエストパラメータに対して、storeValの名前でActionクラスにあるstoreValの値を含める例です。

```java
@Namespace("/")
@Results({
	@Result(name = ActionSupport.SUCCESS,
			type = "redirectAction",
			params = {
				  "actionName" , "%{actionName}"
				, "namespace" , "%{namespace}"
				, "storeVal" , "%{storeVal}"
			}
	),
})
public class redirectAction extends ActionSupport {
	@Action("redirection")
	public String sampleRedirect() throws Exception {
		return SUCCESS;
	}

	private String actionName;
	public String getActionName() {
		return actionName;
	}
	private String namespace;
	public String getNamespace() {
		return namespace;
	}
	private String storeVal;
	public String getStoreVal() {
		return storeVal;
	}
	public String setStoreVal(String storeVal) {
		this.storeVal = storeVal;
	}
}
```
bundle clean は大事

bundle update したら RSpecがSegmentation faultでゲロゲロになった方へ

rake spec なら通るのに rspec -fs -c spec/models/hogehoge...rb はゲロゲロとなりました

therubyracer と libv8の関係をいろいろ調査してバージョンダウンを繰り返してましたが、もうお手上げ状態。。。

bundle clean --force

あれ？動いた。
MySQLの数値型における桁数指定

ZEROFILLしない場合は意味ないけど、なんとなくつけてたので
改めて意味ないってことの自戒をこめて。

MySQL-5.5

まずは以下のDDLでテーブルを作成します。

```sql
CREATE TABLE TEST_TABLE
(
    ID INT PRIMARY KEY AUTO_INCREMENT
    , tiny TINYINT(1) ZEROFILL NOT NULL
    , bool BOOLEAN NOT NULL
    , num0z INT(0) ZEROFILL NOT NULL 
    , num0 INT(0) NOT NULL 
    , num1 INT(1) ZEROFILL NOT NULL 
    , num11 INT(11) ZEROFILL NOT NULL 
    , numz INT ZEROFILL NOT NULL
    , num INT NOT NULL
)
ENGINE=InnoDB
DEFAULT CHARSET=ujis;
```

```shell-session
mysql> desc TEST_TABLE;
+-------+------------------------------+------+-----+---------+----------------+
| Field | Type                         | Null | Key | Default | Extra          |
+-------+------------------------------+------+-----+---------+----------------+
| ID    | int(11)                      | NO   | PRI | NULL    | auto_increment |
| tiny  | tinyint(1) unsigned zerofill | NO   |     | NULL    |                |
| bool  | tinyint(1)                   | NO   |     | NULL    |                |
| num0z | int(10) unsigned zerofill    | NO   |     | NULL    |                |
| num0  | int(11)                      | NO   |     | NULL    |                |
| num1  | int(1) unsigned zerofill     | NO   |     | NULL    |                |
| num11 | int(11) unsigned zerofill    | NO   |     | NULL    |                |
| numz  | int(10) unsigned zerofill    | NO   |     | NULL    |                |
| num   | int(11)                      | NO   |     | NULL    |                |
+-------+------------------------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
```

こんな感じのテーブルになる。
個人的にはZEROFILLなんて1度も使ったことのない幻の機能なのでどうでもいいのだけど、
`int zerofill`が`int(10) unsigned zerofill`になるのはよくわからない。

```shell-session
insert into TEST_TABLE(tiny, bool, num0z, num0, num1, num11, numz, num) values
(0, 0, 0, 0, 0, 0, 0, 0),
(100, 100, 100, 100, 100, 100, 100, 100),
(1, 1, 1, 1, 1, 1, 1, 1);
```

データを突っ込んでselectしてみるとこんな感じ。
tinyint(1)にもint(1)にも100が入りますね。これは常識。

```shell-session
mysql> select * from TEST_TABLE;
+----+------+------+------------+------+------+-------------+------------+-----+
| ID | tiny | bool | num0z      | num0 | num1 | num11       | numz       | num |
+----+------+------+------------+------+------+-------------+------------+-----+
|  1 |    0 |    0 | 0000000000 |    0 |    0 | 00000000000 | 0000000000 |   0 |
|  2 |  100 |  100 | 0000000100 |  100 |  100 | 00000000100 | 0000000100 | 100 |
|  3 |    1 |    1 | 0000000001 |    1 |    1 | 00000000001 | 0000000001 |   1 |
+----+------+------+------------+------+------+-------------+------------+-----+
3 rows in set (0.00 sec)
```

http://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html
によると、TRUE、FALSEはそれぞれ単に1, 0のエイリアスであるため、bool列に格納された100はTRUEでもFALSEでもありません。
PhoneGap(Cordova) の iOSシミュレータや実機でのデバッグ方法



デバッグ用メモ。
PhoneGap でエラーや何も反応しない時に原因を探るための方法。


## iOS シミュレータを立ち上げる

Xcodeからか、以下でシミュレータの起動

```
phonegap run ios
```


## Safari で開発ツールを表示

* メニューのSafariをクリック
* メニューの環境設定をクリック
* ウィンドウが開くので詳細のアイコンをクリック
* 一番下の「メニューバーに”開発”メニューを表示」にチェックを入れる

## Safari

* Safari のメニュの「開発」をクリック
* iPhone Simulator をクリック
指定されたコマンドの場所を表示

バッチファイルで書いた `which` コマンドです。

[which コマンドを作る](http://www.atmarkit.co.jp/fwin2k/win2ktips/319which/which.html)

を参考に、システム環境変数 PATHEXT を参照して拡張子を補完するようにしました。

```bat:which.bat
@echo off

set SELF=%~n0
set HELP=使用方法: %SELF% ファイル名 [...]

setlocal enabledelayedexpansion
  :: cmd.exe のビルトインコマンド
  set B=assoc  color  endlocal  if     popd    rename    time   ^
        break  copy   erase     md     prompt  rmdir     title  ^
        call   date   exit      mkdir  pushd   set       type   ^
        cd     del    for       move   rd      setlocal  ver    ^
        chdir  dir    ftype     path   rem     shift     verify ^
        cls    echo   goto      pause  ren     start     vol
  
  if "%*" == "" (
    echo %HELP% >&2
    exit /b 1
  )
  
  :: 検索対象にカレントフォルダを追加
  set PATH=.;%PATH%
  
  set s=
  for %%c in (%*) do (
    :: 拡張子を含んでいるか確認
    if "%%~xc" == "" (
      for %%e in (%PATHEXT%) do (
        for /f %%f in ("%%c%%e") do (
          if exist "%%~$PATH:f" (
            set s=%%~$PATH:f
          )
        )
      )
    ) else (
      if exist "%%~$PATH:c" (
        set s=%%~$PATH:c
      )
    )
    :: ビルトインコマンドか確認
    for %%b in (%B%) do (
      if /i "%%c" == "%%b" (
        set s=%%c is a shell builtin
      )
    )
    
    if "!s!" == "" (
      echo %~n0: no %%c in ^(%PATH%^)
      exit /b 1
    )
    echo !s!
  )
endlocal
goto :EOF
```

実行すると

```
C:\>which
使用方法: which ファイル名 [...]

C:\>which cd
cd is a shell builtin

C:\>which ping.exe
C:\WINDOWS\system32\ping.exe

C:\>which ping
C:\WINDOWS\system32\ping.exe

C:\>which kshibamo
which: no kshibamo in (.;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem)
```
Rails4 DB連携なしモデルでバリデーション機能を使う

# Goal

* RailsでActiveRecord機能モデルを使うときは、必ずバックエンドでDBと紐付いていなければならない
* 今回は、たとえばCSVファイルのCRUDなどRails4でDB連携しないモデルを作成したい
* RailsのActiveModelが搭載するvalidation機能・callback機能を使って、モデル呼び出し側が意識することなく自動でオブジェクトをチェックするエコシステムをつくりたい

# Milestone

* rails generate modelを実行するとDBと関連付けられてしまうため、これは使わない
  * ActiveRecordを継承したモデルが作成されてしまう、migrationファイルが作成されてしまう
* モデルクラスを新規作成し、クラスにActiveModelモジュールをMixInさせることで、必要な機能だけをクラスに取り込むことができる（Rails3とRails4ではやりかたがけっこう違うらしい）
* include ActiveModel::Modelによってvalidationが使えるようになる
* (追記) ActiveModel::ModelをincludeしていればCallbacksはincludeしなくてもOKでした
  * // include ActiveModel::Callbacksによってコールバックが使えるようになる

# Example

* フォームを使ってアップロードされてきたcsvファイルをそのままサーバに保存するケース

```rb:app/models/csv.rb
class Csv
  include ActiveModel::Model
  #include ActiveModel::Callbacks

  attr_accessor :operator_id, :type, :data_csv
  define_model_callbacks :save

  before_save {
    self.valid?
  }

  validates :file_path, presence: true
  validates :type, presence: true, numericality: true
  validates :data_csv, presence: true

  def save
    run_callbacks :save do
      @uploaded_file_str = self.data_csv.read
      File.open(self.file_path, 'wb') do | new_file |
        new_file.write(@uploaded_file_str)
      end
    end
  end
end
```

### ベーシックなクラスに機能をMixIn

```rb
class Csv
  include ActiveModel::Model
  #include ActiveModel::Callbacks
```

* include ActiveModel::Modelによってvalidatesメソッドなどが有効に
  // include ActiveModel::Callbacksによってコールバック機能が有効になる
* ActiveRecord継承のモデルでない場合、validatesメソッドに'on'を渡しても作動せず、またbefore_saveなどのメソッドがデフォルトで使えないので、コールバックを明示的に指定する
* モデル呼び出し側で、model.valid?のようにバリデーションを実行したいだけならばコールバック機能を使う必要はない


### コールバックを使ってValidation自動実行をつくる

Csvモデルに定義されたsaveメソッドにコールバックを設定する
define_model_callbacks定義をいれることで、デフォルトでは、before_save, around_save, after_saveが有効になる

```rb
define_model_callbacks :save
```

さらに、before_saveなどのイベントを発火させるためにsaveメソッドをrun_callbacksでラップする

```rb
def save
  run_callbacks :save do
    # save時に実行させたい実装
  end
end
```

before_saveなどのタイミングで実行させたいロジックを実装する
ブロックでなくてもメソッドを指定してもいい

```
before_save {
  self.valid?
}
```

# References

* http://nextat.co.jp/staff/archives/56
* http://api.rubyonrails.org/classes/ActiveModel/Callbacks.html
楽観ロックしつつ一括更新したい。

SQLでやる方法、これしか思いつかない。

```sql
UPDATE users SET updated_at = now(), lock_version = lock_version + 1
WHERE id IN (1,2) AND CONCAT(id,'-',lock_version) IN ('1-1','2-2');
```

うまい方法無いのかなー。
Go 1.4 の環境構築 Homebrew + Vim 編 (2014.12)


## インストール

```console
$ brew install go
```

Windows や Linux 向けのバイナリを作りたい場合は `--cross-compile-common` オプションを付けましょう。

```console
$ brew install go --cross-compile-common
```


## ディレクトリとパスの設定


go get などでインストールする場所 GOPATH になるディレクトリを作成します。
ここでは `~/go1.4` とします。

```
mkdir ~/go1.4
```

GOROOT, GOPATH と、それぞれの /bin を PATH に設定します。
(環境変数 GOROOT はソースからビルドした場合には必須ではありませんが、設定しておくと何かと便利です。)

```bash:.bashrc
export GOPATH=$HOME/go1.4
export GOROOT=/usr/local/opt/go/libexec
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
```

## vim-go のインストール

vim-go を使えば、 vim での Go の開発環境のセットアップを省力化できます。 Go の定番ツール (goimports, go vet など) もインストールしてくれます。 neobundle を使っている場合は .vimrc に `NeoBundle 'fatih/vim-go` を追加します。

```vim
call neobundle#begin(expand('~/.vim/bundle/'))

NeoBundle 'Shougo/neobundle.vim'
NeoBundle 'fatih/vim-go'
" ...

call neobundle#end()
```

vim を起動して、 `:NeoBundleInstall` した後、 `:GoInstallBinaries` を実行しましょう。必要なツール群が GOPATH にインストールされます。

あとは [vim-go の README](https://github.com/fatih/vim-go#mappings) を参考に、好みのキーマップをしてください。
VBの人の2次元配列は・・・ジャグ配列

VBやもっと古いソースでは大量の2次元配列が出てくるとおもいます。

``` csharp
new ar_rect int[,] { { 1, 0 },
                     { 0, 4 },
                     { 5, 0 } };
```

VB.NETで階層的にループするために機械的にこう置き換えると思います。

``` csharp
var ar_jag = new int[][] { new int[] { 1, 0 },
                           new int[] { 0, 4 },
                           new int[] { 5, 0 } };
```

　VBの人は実際に必要な物がこうであっても2次元配列を
使うので気を付けましょう。

``` csharp
var dic = new Dictionary< Tuple<int,int> , int >(){
	 { Tuple.Create(0,0) , 1 }
	,{ Tuple.Create(1,1) , 4 }
	,{ Tuple.Create(2,0) , 5 }
};
```

　頻発するなら、この例のTupleよりも、メンバーにx,yやrow,columnを持った
Point某を作っても良いと思います
ActiveRecordのdestroyでバリデーションをやりたい


どうも、ばばです。

## destroyするときにバリデーションを走らせたい

たとえば、『destroy出来る条件』みたいなのがあって、その条件をパスしないと消せない、的な感じにしたいとする。
あり得るとしたら、『TwitterとGitHubの両方の認証手段がある（Qiitaみたいにね）んだけど、両方消しちゃったらログインする方法が無くなっちゃうから、両方とも消すことは出来ない』みたいな事がしたかったとする。
方法としては、

1. `destroy`アクションの中で弾く
2. バリデーションを書く

の2つの方法がぱっと思いつくと思う。ただ、バリデーションの方はちょっと特殊なことをやらなきゃいけないし、アクションの中で書くのは『えーそれモデルの仕事でしょー』感がハンパない。負けた感ある。

というわけで、今回はバリデーション側でなんとかスマートに解決させることは出来ないか、っていうのをやってみようと思う。

## before_destroyを活用する

`before_destroy`については、[ActiveRecord::Callbacks](http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html)に詳しく書いてある。

たとえば、こんな使い方をする。

```ruby:user.rb
class User < ActiveRecord::Base
  before_destroy { |record| Post.destroy_all(user_id: record.id) }
end
```

いや、`dependent`オプションでやれよ、っていうのは気にしないで。

また、こいつ、メソッド名を渡すことも可能だ。

```ruby:user.rb
class User < ActiveRecord::Base
  before_destroy :delete_all_his_posts

  private

  def destroy_all_his_posts
    self.posts.delete_all
  end
end
```

これを利用してどうにかしてみよう。

たとえば、`save`メソッドは、`true`か`false`を返してくる。`true`なら保存成功、`false`なら保存失敗だ。
しかし、destroyは基本的に自分自身を返してくる。これに『もし何かに引っかかってエラーになったら、`false`を返す』ようにしたら、`save`と同じような挙動にすることが出来るのではないか。

```ruby:login_provider.rb
class LoginProvider < ActiveRecord::Base
  belongs_to :user

  before_destroy :user_should_have_at_least_one_login_provider

  private

  def user_should_have_at_least_one_login_provider
    # もしユーザーのLoginProviderが1つしか無いのに、消そうとしていたら
    if self.user.login_providers.length == 1
      errors.add :base, '少なくとも1つ、ログイン用の認証が必要です'
      return false
    end
  end
end
```

すると、

```ruby
if @login_provider.destroy
  redirect_to user_login_providers_path, notice: '削除しました'
else
  redirect_to user_login_providers_path, notice: '削除できませんでした'
end
```

こんなことが出来るようになる。
もちろん、Viewで`@login_provider.errors`を表示すれば、ちゃんと『少なくとも1つ、ログイン用の認証が必要です』と表示される。
ちょっと強引だけど、こんなことをしなきゃいけない時点でだいぶレール踏み抜いてる感があるので、まぁ仕方ないかなぁ。

だいたいそんな感じ( ˘ω˘)