OmniAICreator/Qiita-1.07M huggingface dataset:
２つのオブジェクトを全インスタンス変数の値で比較する


```ruby
class User
  attr_reader :first_name, :last_name, :group

  def initialize(first_name, last_name, group)
    @first_name = first_name
    @last_name = last_name
    @group = group
  end 

  def ==(another)
    self.instance_variables.all? do |v|
      self.instance_variable_get(v) == another.instance_variable_get(v)
    end
  end
end

user1 = User.new("yamada", "taro", "A")
user2 = User.new("yamada", "taro", "A")
user3 = User.new("yamada", "taro", "B")

p user1 == user2 # => true
p user1 == user3 # => false
```
iOSアプリのレビュー期間参考サイト

備忘録

### Average App Store Review Times
http://appreviewtimes.com/

ユーザーからの投稿を集計して、
グラフ化しています。

### App Review Status
https://developer.apple.com/support/appstore/
※最近場所が変わった気がします。（2014/07/04）

**Apple公式**
5営業日以内にレビューに入る割合を
新規、バージョンアップでそれぞれ表示しています。

**以前に比べると、早くなった印象ですが、
混んでいるかどうかの判断ぐらいにした方が安全です。**

### 特急審査（Request Expedited Review）について
キャンペーンに間に合わないレベルの
理由の場合、却下される事があるので、
基本的には、出来ない前提で制作スケジュール組む事が必要です。
Railsのアップデート


`4.1.1`から`4.1.4`にアップデートした時の作業ログ

# 作業用ブランチの作成

```console
$ git checkout -b RailsUpdate
```

# Rails以外のライブラリをアップデート&コミット

やらなくてもいいけど、この機会にあげられる奴はあげておく。

```console
$ bundle update
$ git commit -a -m 'bundle update'
```

# テストを流しておく

```console
$ rspec
```

# Railsのアップデート

```console
$ vim Gemfile
```

```diff
-gem 'rails', '4.1.1'
+gem 'rails', '4.1.4'
```

```console
$ git commit -a -m 'update rails version'
$ bundle update rails
$ git commit -a -m 'bundle update rails'
```

# テスト

```console
$ rspec
```

必要に応じて、手動でテスト。

# マージ＆後始末

```console
$ git checkout master
$ git merge RailsUpdate
$ git branch -d RailsUpdate
```
Elasticsearch::Persistence::Model で Dynamic Attribute


```ruby
class User
  include Elasticsearch::Persistence::Model

  def initialize(attrs = {})
    set_attributes(attrs)
    super attrs
  end

  def set_attributes(attrs = {})
    attrs.each do |attr, value|
      set_attribute(attr, value)
    end
  end

  def set_attribute(attribute, value)
    attribute = attribute.to_sym
    unless self.class.attribute_set.map { |attr| attr.name }.include? attribute
      self.class.attribute attribute, value.class
    end
    send "#{attribute.to_s}=", value
  end

  def []=(attribute, value)
    set_attribute(attribute, value)
  end

  def method_missing(meth, *args, &block)
    if meth.to_s =~ /(.+)=$/
      set_attribute($1, args.first)
    else
      super
    end
  end
end

```
「The working copy requires a newer version of Subversion than Xcode supports」の対処法


上記警告がプロジェクトを開いた直後に表示された場合

```bash	
cd /Applications/Xcode.app/Contents/Developer/usr/bin/        
mkdir bak.svn
mv svn* bak.svn
ln -s /usr/local/Cellar/subversion/1.7.8/bin/svn* /Applications/Xcode.app/Contents/Developer/usr/bin/
```
を実行して再起動すると警告がでなくなります。

/usr/local/Cellar/subversion/1.7.8/ の部分はSubversionのインストール場所やバージョンによって異なります。

2回ほどこれに出くわして2回とも今のところ問題は発生していないです。自分の環境ではXcode5.1.1で出たので上記方法で対応。

自己責任で。

参考：http://stackoverflow.com/questions/15179683/the-working-copy-requires-a-newer-version-of-subversion-than-xcode-supports
file_rec/asyncとfile_rec/gitを自動的に切り換える

久々に[unite.vim](https://github.com/Shougo/unite.vim)をアップデートしたらfile_rec/gitなるsourceが追加されていた。ドキュメントによるとfile_rec/asyncよりgitディレクトリでは高速に動作するとのことだったので、カレントディレクトリに .git ディレクトリがあるかどうかで切り換えるようにした。確かに若干速くなったような...?

```vim
NeoBundle 'Shougo/unite.vim'

function! DispatchUniteFileRecAsyncOrGit()
  if isdirectory(getcwd()."/.git")
    Unite file_rec/git
  else
    Unite file_rec/async
  endif
endfunction

nnoremap <silent> <C-p> :<C-u>call DispatchUniteFileRecAsyncOrGit()<CR>
```
Facebook/Twitter/Google+/はてぶのSNSボタン高速化2(async + delay)

ページ内でSNSボタンの表示にdelayを入れてずらす事で体感速度を向上させました。

要点は **script.async = true** と **setTimeout(function(){...}** です。


はてなブックマーク読み込み。
scriptタグで完結していたものをjavascriptに展開。

元はscriptタグで書かれていました。

```html
<script type="text/javascript" src="http://cdn-ak.b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
```

delay入れるために展開しました。

```js
$(function() {
  setTimeout(function(){  
    var script = document.createElement('script');
    script.src = "http://cdn-ak.b.st-hatena.com/js/bookmark_button.js";
    script.charset = "utf-8";
    script.async = true;
    $('body').append(script);
  }, 5000);
});
```

Twitter

```js
!function(d,s,id){
  setTimeout(function(){  
    var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
    if(!d.getElementById(id)){
      js=d.createElement(s);js.id=id;
      js.async = true;
      js.src=p+'://platform.twitter.com/widgets.js';
      fjs.parentNode.insertBefore(js,fjs);
    }
  }, 6000);
}(document, 'script', 'twitter-wjs');
```

Google+

```js
window.___gcfg = {lang: 'ja'};
(function() {
  setTimeout(function(){  
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/platform.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  }, 7000);
})();
(function() {
  setTimeout(function(){  
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  }, 8000);
})();
```

Facebook

```js
(function(d, s, id) {
  setTimeout(function(){  
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=247875698724916";
    fjs.parentNode.insertBefore(js, fjs);
  }, 4000);
}(document, 'script', 'facebook-jssdk'));
```

ページ内で完結できる方法としてはここまででしょうか。これ以上速くするとなると、オフィシャルから配布されているタグを使わない、またはサーバーサイドで処理して返すなどの対応が必要になりそうです。
クロージャの実装

前回の記事([スコープの見え方について調べてみた](http://qiita.com/kou_tana77/items/98eda9f01a183c29b8b8))の記事の内容を踏まえた上で、クロージャの実装について見てみる。

```py
def counter(x):
	pprint(locals())
	def count():
		pprint(locals())
		y = x
		x += 1
		return y
	return count
c = counter(10)
print c()
print c()
print c() 
```
は、動きそうに見えるが、動かすと、次のようにエラーになる。

```text:実行結果
{'x': 10}
{}
Traceback (most recent call last):
  File "tes004.py", line 12, in <module>
    print c()
  File "tes004.py", line 7, in count
    y = x
UnboundLocalError: local variable 'x' referenced before assignment
```

関数counter()の引数xは、counter()のローカル変数として見える。
内部関数count()から変数xを参照だけするだけであれば、変数xはcount()のローカル変数として参照できるが、代入コード(``x += 1``⇒これは参照のコードでもある)があるため、count()関数ブロックで定義される変数として動こうするが、代入の前に参照が実行行われるためエラーとなる。
外側の関数で定義された変数の参照はできるが、代入(書き換え)はできない。

次は、上手く実行できるパターン。

```py
def counter(x):
	pprint(locals())
	y = [x]
	def count():
		pprint(locals())
		z = y[0]
		y[0] += 1
		return z
	return count
c = counter(10)
print c()
print c()
print c() 
```

```text:実行結果
{'x': 10}
{'y': [10]}
10
{'y': [11]}
11
{'y': [12]}
12
```

このコードも、内部関数count()で変数yを書き換えているように見えるが、変数yで参照できるリストの中身を書き換えているだけなので、正常に動く。
例えば、``y[0] += 1``を``y = [y[0] + 1]``のようにすると、エラーになる。これは変数yを書き換えようとしているため。
このため、参照先がリストでなく、クラスとかであっても、参照先を更新することはできる。

次は、クラスで実装した例。

```py
class tcls():
	def __init__(self, x):
		self.x = x

def counter(x):
	pprint(locals())
	y = tcls(x)
	def count():
		pprint(locals())
		z = y.x
		y.x += 1
		return z
	return count
c = counter(10)
print c()
print c()
print c() 
```

```text:実行結果
{'x': 10}
{'y': <__main__.tcls instance at 0x0222F788>}
10
{'y': <__main__.tcls instance at 0x0222F788>}
11
{'y': <__main__.tcls instance at 0x0222F788>}
12
```
ssh関連メモ

##パスワードなしでリモートアクセス##
* macでパースワードを保存してくれるので、一回ログインしたら、次回からパスワード省略できる
* linuxではssh-agentを使用ようにする

>
以下のリンクで参照
[ssh-agent で快適 ssh 生活](http://www.snowelm.com/~t/doc/tips/20030625.ja.html)

```shell-session
echo -n "ssh-agent: "
source ~/.ssh-agent-info
ssh-add -l >&/dev/null
if [ $? == 2 ] ; then
	echo -n "ssh-agent: restart...."
	ssh-agent >~/.ssh-agent-info
	source ~/.ssh-agent-info
fi

if ssh-add -l >&/dev/null ; then
	echo "ssh-agent: Identity is already stored."
else
	ssh-add
fi
```

[Understanding ssh-agent and ssh-add](http://joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add/)

##リモート操作
[SSHを利用したリモートサーバに対するコマンド実行](http://pen.agbi.tsukuba.ac.jp/~RStiger/hiki2/?%A5%EA%A5%E2%A1%BC%A5%C8%A5%B5%A1%BC%A5%D0%A4%CB%C2%D0%A4%B7%A4%C6%A4%CE%A5%B3%A5%DE%A5%F3%A5%C9%BC%C2%B9%D4)

##SSHコネクションReuse
```~/.ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p
```
~/.ssh直下にsocketファイル作成
``ssh -M -N -f hostname``
コネクション存在チェック``ssh fwolf.com -O check``
コネクション削除``ssh fwolf.com -O exit``
[ssh的连接重用](http://www.fwolf.com/blog/post/385)
[Objective-C] UIActionSheetの特定のボタンをdisabledにする


特定の条件下では`UIActionSheet`のとあるボタンを非活性化したい、という要望があると思います。
その場合にボタンを識別してdisableにする方法を調べたのでメモしておきます。（[参考](http://stackoverflow.com/questions/1163289/how-to-disable-button-in-uiactionsheet)）

```actionsheet.m
// `sheet`はUIActionSheetのインスタンス
for (UIView *view in [sheet subviews]) {
	if ([view.description hasPrefix:@"<UIAlertButton"]) {
		UIButton *btn = (UIButton *)view;
		// キャンセルボタンは非活性化の対象にしない
		if ([btn.titleLabel.text isEqualToString:@"cancel"]) {
			continue;
		}
		if (/* disabledにしたい判定 */) {
			btn.enabled = NO;
		}
	}
}
```
日本語ドメインの仕組み

[http://日本語.jp/](http://日本語.jp/) は 内部的には[http://xn--wgv71a119e.jp/](http://xn--wgv71a119e.jp/)に変換されてアクセスされる。

`xn--英数字`となる文字はpunycodeと呼ばれる。
2003年ごろまでは`zq--英数字`だった様子。

で、どうやって変換するか調べてみたところ、

[idnkit download - JPNIC](https://www.nic.ad.jp/ja/idn/idnkit/download/)から`idnkit-1.0(tar + gzip; 583KB)`でidnconvを使い変換する。

```bash:
$ wget https://www.nic.ad.jp/ja/idn/idnkit/download/sources/idnkit-1.0-src.tar.gz
$ ./configure
$ make
```

```bash:日本語->punycode
$ echo http://日本語.jp/ | ./tools/idnconv/idnconv
http://xn--wgv71a119e.jp/
```

```bash:punycode->日本語
$ echo http://xn--wgv71a119e.jp/ | ./tools/idnconv/idnconv -reverse
http://日本語.jp/
```

# 日本語ドメインでのApache設定

URL: http://てすと.jp/

idnconvを使い`てすと.jp`が`xn--88jzah.jp`であることを知る。

```apache:
<VirtualHost *:80>
        ServerName xn--88jzah.jp
        ServerAdmin webmaster@localhost
        DocumentRoot /srv/xn--88jzah.jp/
        ErrorLog ${APACHE_LOG_DIR}/xn--88jzah.jp.error.log
        CustomLog ${APACHE_LOG_DIR}/xn--88jzah.jp.access.log combined
        <Directory /srv/xn--88jzah.jp/>
                Require all granted
        </Directory>
</VirtualHost>
```

/srv/xn--88jzah.jp/index.html を作成し、
http://てすと.jp/index.html をブラウザでアクセスすると表示されることを確認。
Chromeを簡単に再起動させる方法

URL欄に

`chrome://restart`

と入力してエンター、これだけ。直前のウィンドウやタブを復元したい場合は[Session Buddy](https://chrome.google.com/webstore/detail/session-buddy/edacconmaakjimmfgnblocblbcdcpbko)あたりを入れておくとよいかも。
Docker入門: 1日目

# Docker？

## Dockerとは？
[こちら](http://www.publickey1.jp/blog/14/dockerdockerfiledocker_meetup_tokyo_2.html)をご参照。

## Dockerの運用
[#04 作業の流れと用語を理解しよう - ドットインストール](http://dotinstall.com/lessons/basic_docker/27704)

# MacでDockerを使ってDebian環境を作る

## インストール


1. [こちら](https://github.com/boot2docker/osx-installer/releases)からDocker for OSX Instller(Boot2Docker-1.0.1.pkg)をダウンロード
1. インストーラを起動し、Virtual BoxとDocker for OSXをインストール

## 初期化

1. アプリケーションフォルダからboot2dockerを起動

または

```
$ boot2docker init
$ boot2docker start
$ export DOCKER_HOST=tcp://$(boot2docker ip 2>/dev/null):2375
```

## Dockerの起動と停止

起動
`$ boot2docker start`
停止
`$ boot2docker stop`

## Debianを動かす

1. [Docker Hub Registry](https://registry.hub.docker.com/)からDebianのイメージを[検索](https://registry.hub.docker.com/_/debian/)
1. Debianイメージをダウンロード
1. Debianイメージからコンテナを作成

起動する。

```
$ docker start
2014/07/04 09:42:38 Waiting for VM to be started...
.......
2014/07/04 09:42:59 Started.
2014/07/04 09:42:59 Your DOCKER_HOST env variable is already set correctly.

$ 
```

イメージ、コンテナがまだなにもない状態。

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

$ 
```

Debianイメージをダウンロードする。

```
$ docker pull debian:latest
Pulling repository debian
63f650c4db34: Download complete 
511136ea3c5a: Download complete 
2e5f1fce06be: Download complete 

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
debian              latest              63f650c4db34        2 days ago          85.18 MB

$
```

コンテナを作り、コンソール上で起動する。

```
$ docker run -it debian /bin/bash
root@83a10b218035:/#
```

## 確認

Debianの中にいます。

```
root@83a10b218035:/# uname -a
Linux a680e2a7e30e 3.14.1-tinycore64 #1 SMP Mon Jun 2 04:19:19 UTC 2014 x86_64 GNU/Linux

root@83a10b218035:/# cat /etc/debian_version
7.5

root@83a10b218035:/# exit
```

Dockerの終了したプロセスを確認します。

```
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
a680e2a7e30e        debian:latest       /bin/bash           3 minutes ago       Exited (127) 1 seconds ago                       sleepy_fermi

$
```

## 続く

[Docker入門: 2日目](http://qiita.com/akaneyuki/items/603901cdbab5c94de772)

# 参考

* [Installing Docker on Mac OS X](http://docs.docker.com/installation/mac/)
* [いまさら聞けないDocker入門（1）](http://www.atmarkit.co.jp/ait/articles/1405/16/news032.html)
* [いまさら聞けないDocker入門（2）](http://www.atmarkit.co.jp/ait/articles/1406/10/news031.html)
横浜へなちょこプログラミング勉強会のお題の結果をRubyでチェックするために

## 背景
* 横浜へなちょこプログラミング勉強会のお題で、プログラミングを練習している
* http://yhpg.doorkeeper.jp/　の問題より、JavaとC++のテストコードを用意されたけど、rubyで直接的に使えない

## 目的
* 結果を簡単的にチェックするために、結果チェック部分を実装してみる

## コード
* https://gist.githubusercontent.com/alingogo/8818c5eb553d0e383058/raw/fdb51f8db8f22d1f5699ce17083d64ffd8f728e3/parse_check_data.rb

## 使い方

```rb
require File.dirname(__FILE__) + "parse_check_data.rb"

def slove(a)
  a
end

ParseCheckData.check(DATA) do |data|
  slove(data)
end

__END__
/*#0*/ test( "1", "1" );
/*#1*/ test( "2", "1" );
```

## 最後の話
* No Ruby No Life
Objective Cが嫌いな人達へ

巷はSwiftで盛り上がってますが、僕はObjective Cが結構好きです。
で、Objective Cが嫌われる大きな理由がブラケットを使った文法だと思うので、それをちょっと綺麗に書くテクニックを紹介します。

まず普通の書き方

```objc
UIWindow *window = [UIApplication sharedApplication].delegate.window;
UIView *view = [[UIView alloc]init];
```

ここで、クラスメソッドに対してもプロパティ記法で書く事ができます。

```objc
UIWindow *window = UIApplication.sharedApplication.delegate.window;
UIView *view = UIView.alloc.init;
```

あと、alloc+initの代わりに、newを使うとよりシンプルになります。

```objc
UIView *view = UIView.new;
```

ブラケットが減るだけで、こんなにモダンな感じに。
ほら、Objective Cもそんなに悪くないでしょ？

あ、一点デメリット。XCodeの補完が効かないです。
新しいだけのアイデア

モバイルデザインパターン（ http://www.amazon.co.jp/dp/487311568X ）という本の中で
アンチパターンについて述べている箇所で、新しいだけのアイデアはいらないという一節がありました。

ちょうど読んでいる別の本の中で「直感的にわかる」ことの理由として「過去に徹底的にそのことについて考え、演習をして答え合わせまで行う経験をしている」から、と説明されていました。

UIにふれる際にユーザが「徹底的に考え演習、答え合わせ」の流れを意識的に行っているとは思いませんが、無意識に数々のUIにふれ、パターンを経験として蓄積しているのだと思います。
モバイルデザインパターンに良い例として挙げられているものも真新しいものでは無く、見たり、触れた事があるものばかりでした。

直感的を捉え違えた斬新（奇抜）なUIは使いづらい「新しいだけのアイデア」になってしまうのでUIを検討する際にはよくよく考える必要がありますね。

*"新規性を求めるならコアとなる機能の適用に注力し、インターフェースデザインについてはベストプラクティスに従うべき"*
git pull の時に"You asked me to pull ..."と言われた時

# 概要
##### git pull で下記のメッセージが表示され，上手くマージ出来ない時の対処法．
<pre>
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.
If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "master"]
    remote = &lt;nickname&gt;
    merge = &lt;remote-ref&gt;

    [remote "<nickname>"]
    url = &lt;url&gt;
    fetch = &lt;refspec&gt;

See git-config(1) for details.
</pre>
# 対処法
##### 1. .git/configに[branch]と[remote]の設定を追記
* デフォルトだと以下のようになる．
<pre>
[remote "origin"]
        url = https://&lt;your repository's url&gt;.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
</pre>

##### 2. git push時に設定値をセット
<pre>
$ git push -u origin master
</pre>
備忘：MySQLでテーブルサイズを確認するためのSQL

参考：[http://d.hatena.ne.jp/sho-yamasaki/20120405/1333640589](http://d.hatena.ne.jp/sho-yamasaki/20120405/1333640589)

特定のデータベースの、テーブル毎のサイズを取得するSQL

```sql
select
	table_name,
	table_comment,
	table_rows, 
	avg_row_length,  
	round((data_length + index_length)/1024/1024) as total_size_MB, -- 合計サイズ
	round(data_length/1024/1024) as data_size_MB, -- データサイズ
	round(index_length/1024/1024) as index_size_MB -- インデックスサイズ
from INFORMATION_SCHEMA.TABLES
where table_schema = 'データベース名'
order by total_size_MB desc, data_size_MB desc, index_size_MB desc, table_name
```
sphinxでのIOErrorを直す

ある時に`sudo port upgrade outdated`すると、それ以降にsphinxでビルドしようとすると、怒られる件。エラー文の最後は次のようなもの。

```shell-session
IOError: [Errno 13] Permission denied: '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/EGG-INFO/top_level.txt'
```

問題は、この`top_level.txt`というファイルの権限が、

```shell-session
-rw-r-----  1 root  wheel     9B Feb 13 12:55 top_level.txt
```

となっているからダメだと言われている。

```shell-session
sudo chmod a+r /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/EGG-INFO/top_level.txt
```

permissionを開けて上げると、エラーがでなくなった。なんでこんなことになっているのかは、未だ不明。
PandocをDockerコンテナにして使う


Pandoc入りのDockerコンテナを作って、ローカルのツールとして使う方法です。
（といっても普通のDockerfileですが）

## 使い方

例えば、以下のようにするとMarkdownをHTMLに変換できます。

```sh
$ docker pull ksoichiro/pandoc
$ docker run -t -i -v `pwd`:/workspace ksoichiro/pandoc pandoc sample.md -s -o sample.html
```

`pwd`の部分で、変換対象のファイルがある位置をDockerコンテナのボリュームに割り当てています。
docker pullとdocker runだけですので、dockerが使えるマシンであればpandoc用のインストール手順を踏むことなくすぐに使えます。

### Automated Build Repository

[こちら(Docker Hub)](https://registry.hub.docker.com/u/ksoichiro/pandoc/)にあります。

### Dockerfile

[こちら(GitHub)](https://github.com/ksoichiro/dockerfiles/blob/master/pandoc/Dockerfile)にあります。

## 使いどころ

Pandocを使ってドキュメント生成するようなプロジェクトの場合、上記のDockerfileやシェルスクリプトを、ソースコードと同じようにリポジトリの中で管理してしまいます。

これにより、(開発環境をDockerで構築するのと同じですが)以下のようなメリットが得られると思います。

* ドキュメントの生成手順まで含めてコード化・バージョン管理できる
* マシン内に他のバージョンのPandocがあっても影響されない
* 環境を各マシンで統一でき、常に同じものを生成できる
* 導入手順を簡略化できる
rails4でbootstrap3をcustomする。

bootstrapの調整方法がわかったので、ここで共有します。

#方法
`@import`する前に、変更したい[bootstrap customize]の値を指定します。

##navbarの背景色を変更する
`navbar`の背景を白くするために、`$navbar-default-bg`を設定します。

````app/assets/stylesheets/bootstrap_overwrite.css.scss
$navbar-default-bg: #FFF;
@import "bootstrap-sprockets";
@import "bootstrap";
````

##navbarが小さくなる閾値を変更する

幅が400px以下になったらnavbarを畳ませるために、`$grid-float-breakpoint`関連を設定します。

````app/assets/stylesheets/bootstrap_overwrite.css.scss
$grid-float-breakpoint: 400px;
$grid-float-breakpoint-max: ($grid-float-breakpoint -1);
@import "bootstrap-sprockets";
@import "bootstrap";
````

以上です。
指摘などがあればよろしくお願いします。

####参考
https://github.com/twbs/bootstrap-sass/issues/203
[bootstrap customize]
[bootstrap customize]:http://getbootstrap.com/customize/#less-variables
Xamarin.Forms から Webブラウザで開く


Xamarin.FormsからWebブラウザアプリ(Chrome,Safari)でURLを開くサンプルです。`DependencyService`を利用します。


## プロジェクトの作成

新規にソリューションを作成します。種類は`Blank Apps (Xamarin.Forms Portable)`、名前は`OpenWebBrowserSample`にします。


## PCLプロジェクト

OpenWebBrowserSampleプロジェクトにインターフェース`IWebBrowserService.cs`を作成します。

```c#:IWebBrowserService.cs
using System;

namespace OpenWebBrowserSample.Services
{
	public interface IWebBrowserService
	{
		void Open(Uri uri);
	}
}
```


## iOSプロジェクト

OpenWebBrowserSample.iOSプロジェクトに`WebBrowserService.cs`を作成し、OpenWebBrowserSampleプロジェクトで定義した`IWebBrowserService`インターフェースを実装します。

```c#:WebBrowserService.cs
using System;
using OpenWebBrowserSample.iOS;
using Xamarin.Forms;
using MonoTouch.UIKit;

[assembly: Dependency(typeof(WebBrowserService))]

namespace OpenWebBrowserSample.iOS
{
	public class WebBrowserService : IWebBrowserService
	{
		public void Open(Uri uri)
		{
			UIApplication.SharedApplication.OpenUrl (uri);
		}
	}
}
```


## Androidプロジェクト

OpenWebBrowserSample.Androidプロジェクトも同様に`WebBrowserService.cs`を作成し、OpenWebBrowserSampleプロジェクトで定義した`IWebBrowserService`インターフェースを実装します。

```c#:WebBrowserService.cs
using System;
using Android.Content;
using OpenWebBrowserSample.Android;
using Xamarin.Forms;

[assembly: Dependency(typeof(WebBrowserService))]

namespace OpenWebBrowserSample.Android
{
	public class WebBrowserService : IWebBrowserService
	{
		public void Open (Uri uri)
		{
			Forms.Context.StartActivity (
				new Intent (Intent.ActionView,
					global::Android.Net.Uri.Parse(uri.AbsoluteUri) ));
		}
	}
}
```

`Forms.Context`からコンテキストを取得して`StartActivity`メソッドを実行します。インテントに含めるUriは`Android.Net.Uri`型に変換する必要があります。


## 使用例

```c#:
var uri = "http://xamarin.com/";
DependencyService.Get<IWebBrowserService> ().Open(new Uri(uri)); // open in WebBrowser
```
Julia + PyQtGraph でグラフを描画する(3)

[『プログラミング言語 Julia でグラフを描画する』](http://qiita.com/akmiyoshi/items/a2aca5369c8e3c11ae59) でとりあえずサンプルを動かすことに成功したが、自分の(Julia言語の)プログラムで作ったデータを使ってグラフを描画するにはどうしたら良いかを調べることにした。
3D空間にグラフを描画するサンプルを作ってみた。(PyQtGraphのサンプルを参考にして、計算処理部分を Julia 側に移植しました)
例によって、Julia で求めた計算結果を PyQtGraph でグラフ表示するようになっている。(環境を作って是非動かしてみてください)

* GLLinePlot.jl (Julia のソースコード)は、Python のソース内の graph_run() という関数に配列を渡す。グラフの描画は Python にお任せ。。
* GLLinePlot.py (Python のソースコード)では、Julia から渡された配列を基に3Dグラフを描画する(51個の折れ線グラフ)。
* PyCall を用いて Python のコードを呼び出す際には、C:\julia-0.2.1-win32\bin がロードパスに含まれるので、GLLinePlot.jl および GLLinePlot.py の両方共を C:\julia-0.2.1-win32\bin 配下に保存しておくこと。
* ソースコードを保存する際には文字エンコーディングは utf-8 にしておくこと。
* サンプルを起動するには、GLLinePlot.jl (Julia のソースコード) をエクスプローラーからダブルクリックする。

> 注記：環境構築については、[『プログラミング言語 Julia でグラフを描画する』](http://qiita.com/akmiyoshi/items/a2aca5369c8e3c11ae59) を参照してください。

![2014-0704-0623.png](https://qiita-image-store.s3.amazonaws.com/0/32879/5033012b-bec1-9b1b-2d2f-40f8d6c87830.png)
↑マウスでドラッグしたりカーソルキーを押すと3Dグラフが回転します。マウスホイールを回すと拡大・縮小ができます。

```jl:GLLinePlot.jl(C:\julia-0.2.1-win32\binに保存すること)
# -*- coding: utf-8 -*-

using PyCall

nx = 100
ny = 51
x = linspace(-10, 10, nx)
y = linspace(-10, 10, ny)
z = zeros(Float64, length(x), length(y))

for iy = 1:length(y)
    for ix = 1:length(x)
        d = (x[ix]^2 + y[iy]^2)^0.5
        z[ix, iy] = 10 * cos(d) / (d+1)
    end
end

@pyimport GLLinePlot
GLLinePlot.graph_run(x, y, z)
```

```python:GLLinePlot.py(C:\julia-0.2.1-win32\binに保存すること)
# -*- coding: utf-8 -*-

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np

def graph_run(plot_data_x, plot_data_y, plot_data_z):

    app = QtGui.QApplication([])

    w = gl.GLViewWidget()
    w.resize(600,400)
    w.opts['distance'] = 40
    w.show()
    w.setWindowTitle(u'Julia+PyQtGraph サンプル')

    x = plot_data_x
    y = plot_data_y
    for i in range(len(y)):
        yi = [y[i]]*len(x)
        z = plot_data_z[:,i]
        pts = np.vstack([x,yi,z]).transpose()
        plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,len(y)*1.3)), width=(i+1)/10., antialias=True)
        w.addItem(plt)

    app.exec_()
```
PostgreSQLをDebian GNU Linuxでbuildする

#PostgreSQLをDebian GNU Linux でソースコードからビルドする方法

##ソースコードをダウンロードする。

ここから9.3.5をダウンロード
http://www.postgresql.org/ftp/source/


##必要な開発者用ファイルをインストールしてconfigure & make install

　apt-get やmakeが出来る権限のユーザーで次のコマンドを実行。

```bash:pgbuild.sh
#開発者用ライブラリをインストール
apt-get install -y libkrb5-dev libssl-dev libxml2-dev libxslt1-dev \
	libossp-uuid-dev libedit-dev libgssapi-krb5-2 libldap2-dev \
	python2.7-dev libperl-dev

bzip2 -dc postgresql-9.3.5.tar.bz2 | tar xf - 

echo "plz comment out KEEPONLYALNUM"

nano postgresql-9.3.5/contrib/pg_trgm/trgm.h

#ビルド

cd postgresql-9.3.5

./configure \
	--with-includes=/usr/local/include \
	--with-includes=/usr/include/mit-krb5 \
	--with-includes=/usr/include/python2.7 \
	--with-libs=/usr/lib \
	--with-libs=/usr/local/lib \
	--with-libs=/usr/lib/x86_64-linux-gnu \
	--with-gssapi --with-krb5 --with-openssl \
	--with-pam --with-ldap \
	--with-libxml --with-libxslt --with-ossp-uuid --with-python \
	--with-perl --with-readline --with-libedit-preferred \
	-enable-nls='Japanese' \
	ARCHFLAGS='-arch x86_64'

make check
make install　#インストール

#所々の設定
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres:postgres /usr/local/pgsql/data
initdb

#スタートスクリプトの設定
cp ./contrib/start-scripts/linux /etc/init.d/postgres
chmod 755 /etc/init.d/postgres

#PostgreSQLサーバーのデーモンをスタート
/etc/rc.d/init.d/postgres start

```

以上、一発で通るか分かりませんが、順序良くこれらを実行していけば無事にビルドできるはず。

##pg-trgmを使って日本語全文検索をしたい人へ

　PostgreSQLをソースコードからビルドする目的はおそらくこれだけだろう。pg-trgmはデフォルトの設定でビルドされたバイナリだと日本語検索が正しくされないからだ。よって **”contrib/pg_trgm/trgm.hの#define KEEPONLYALNUMをコメントアウト”** する。
　その後、前述のconfigure & makeを行えばOKである。

##via
* http://qiita.com/oukayuka/items/7b3f98fffca3e79e8374
 
#終わりに

　個人用のメモ感覚で書いたのでなにか分かりにくい所、間違っている所があればコメントなどで……。
[Ruby] 3行RSSパース

[[Ruby] NokogiriとFaradayで3行RSSパース](http://qiita.com/aKenjiKato/items/834d7bfed838c9c5aab8) で、
コメント欄で色々教えてもらったので、それを踏まえてもう一度。

前回からの変更のキモは、

* `open-uri`があればFaradayいらない
* `rexml/document`があればNokogiriいらない
* Ruby Gemsが不要なのでGemfileいらない

です。

```rb:main.rb
#!/usr/bin/env ruby

require 'rexml/document'
require 'open-uri'

REXML::XPath.match(REXML::Document.new(open(ARGV[0]).read), '//xmlns:item/xmlns:title').map { |node| puts node.text unless /^PR:/.match(node.text) }
```
実行してみましょう。

```console
$ ruby main.rb http://rss.rssad.jp/rss/slashdot/slashdot.rss
医療機関での携帯電話等の使用に関する新たな指針案、意見を募集中
「tomocha.moe」というドメインが取得できない問題、発生
英国ISPによるWebサイトのフィルタリング、有害でないサイトも多数ブロック
JR東日本・中央線飯田橋駅ホーム、200m移設へ
Amazon、退職後すぐにGoogleに転職した元社員を契約違反で訴える
Orkut、9月に終了へ
東工大、RNAの長さを制御する仕組みを解明
NTT、人工原子や人工分子の作製に成功
KADOKAWAとTwitter、共同でTwitterタイムライン上で電子書籍を読めるサービスを開始
「盗撮ができる運動靴」販売者が逮捕される
```

参考

* [rexml/document](http://docs.ruby-lang.org/ja/2.1.0/library/rexml=2fdocument.html)
* [open-uri](http://docs.ruby-lang.org/ja/2.1.0/library/open=2duri.html)
2048の得点計算方法と理論上の最高得点

ハマってしまいました。
http://gabrielecirulli.github.io/2048/

# 得点計算方法
- 2048では、値 2^(n-1) のタイルを2つくっつけると値 2^n のタイルになり、得点 2^n が加算される。
- 2 のタイルだけで 2^n のタイルを作るまでの得点を a[n] とする
- 4 を作るには 2 を 2 つくっつければ良く、その時の得点は 4
    - a[2] = 4
- 2^n を作るには、2^(n-1) を 2つ作り、最後にその2つをくっつける（途中経過がどうあれ、こうなる）。2^(n-1) を作るのに a[n-1] 点、2^n を作って 2^n 点だから、合計は 2a[n-1] + 2^n
    - a[n] = 2a[n-1] + 2^n
- 両辺 2^n で割り、b[n] = a[n]/2^n とすると、b[n] = b[n-1] + 1, b[2] = 1
- これを解いて、b[n] = n - 1, a[n] = (n-1)2^n
- 2048 = 2^11 だから、 2048 が出来るまで 2 のタイルしか出なかったとすると、a[11] = 20480 点得ることになる。
    - 2048 を作った時にだいたい 2 万点くらいなのはこのため。
- 4 が出現した場合、はじめの「2 と 2 で 4 を作る」というフェーズが無くなるので、2 だけ出現する場合より 4 点少なくなる。
    - つるかめ算と同じ理屈で、「現在までに 4 が何回出たか」がこれによって計算できる

# 理論上の最高得点
- 盤面が以下のようになった時が最高得点である

```
   4    8   16   32
 512  256  128   64
1024 2048 4096 8192
2^17 2^16 2^15 2^14
```

- 4 が出現すると 4 点少なくなる
- 4 を使わないと、上の盤面にならない
- 従って、要所要所では 4 が出現しつつも、ほとんどの時点で 2 が出現するようなパターンが最高得点であるはずだ。
- 盤面に存在している数字から、「全部 2 だった時の得点」が計算できる。4が出現した個数を数えることで、理論上の最高得点を計算する。

## 3 マスあれば 2 だけを使って 8 を作れる
次の手順に従って、3 マスあれば 2 だけで 8を作ることが可能：

```
[2][ ][ ]
→
[2][ ][2]
→
[2][ ][4]
→
[2][2][4]
→
[2][4][4]
→
[2][ ][8]
```

## n マスあれば、2 だけを使って 2^n を作れる
- n-1 マスあれば 2^(n-1) を作れる、と仮定する。
- n マス空いている時、まず n-1 マス 使って 2^(n-1) を作る。
- すると、n マスのうち 1 マスが 2^(n-1) によって専有されているものの、残りの n-1 マスを使ってもう1つ 2^(n-1) が作れる。
- 2^(n-1) が 2 つ作れたので、最後にこれを合わせて 2^n を得る。
- 前項と合わせて、数学的帰納法により、n マスあれば 2^n を作れる。

盤面は 16 マスあるので、2^16 までは 2 を使って作ることが出来る。

## 2 マス残っているときに 8 を作るのに必要な 4 の数

以下の手順で、4 が 1 度だけ出現すれば、 2 マスで 8 を作ることが出来る
```
[2][ ]
[2][2]
[4][4] （ここで 4 出現）
[2][8]
```

## 3 マス残っている時に 16 を作るのに必要な 4 の数
想像がおっつかないのでもういっこだけ確認してみる。

```
[ 2][  ][  ]
（中略）
[ 2][  ][ 8] （3 マスあれば、2 だけを使って 8 を作る事ができる）
[ 2][ 2][ 8]
[ 4][ 4][ 8] （ここで 4 出現）
[ 2][ 8][ 8]
[ 2][ 2][16]

```

## n-1 マス残っている時に 2^n を作るには 4 が 1 度だけ出現すれば良い
- n-2 マス残っている時に 2^(n-1) を作るには 4 が 1 度だけ必要と仮定する。
- n-1 マス残っていれば、 2 だけを使って 2^(n-1) を作ることが可能
- 2^(n-1) が 1 マス専有しているため、残りは n-2 マスある
- 仮定より、4 が 1 度だけ出現すれば 2^(n-1) を作れる
- 2^(n-1) が 2 つ作れたので、これをもって 2^n を得る。4 は 1度だけしか出現していない。
- 数学的帰納法により、命題は正しい。

## 4 は最低 何度出現するか？

```
   4    8   16   32
 512  256  128   64
1024 2048 4096 8192
2^17 2^16 2^15 2^14
```

- 上図において、16 マスを使って 2^17 を作るために 4 が 1 度だけ出現する（1 回目）
- 残った 15 マスを使って 2^16 を作るために 4 が 1 度だけ出現する（2 回目）
- （中略）
- 残った 2 マスを使って 8 を作るために 4 が 1 度だけ出現する（15 回目）
- 最後の 1 マスは、どうせ動かせないので、実は 2 でも 4 でも構わない。なんなら 3 でも構わない。

## 以上により
- 2^17 を 2 だけで作ると a[17] 点得る。
- 2^16 を 2 だけで作ると a[16] 点得る。
- （中略）
- 8 を 2 だけで作ると a[3] 点得る。
- 最後のマスは加算されない。
- 最後に、実際には 4 が 15回出現しているので、4 点 × 15 回分は嘘であるから引かなければならない。
- 以上により、理論上の最高得点は 3932100 点である。

```
  a[ 3] =      16
  a[ 4] =      48
  a[ 5] =     128
  a[ 6] =     320
  a[ 7] =     768
  a[ 8] =    1792
  a[ 9] =    4096
  a[10] =    9216
  a[11] =   20480
  a[12] =   45056
  a[13] =   98304
  a[14] =  212992
  a[15] =  458752
  a[16] =  983040
  a[17] = 2097152
+             -60
------------------
          3932100
```

![スクリーンショット 2014-07-04 2.13.14.png](https://qiita-image-store.s3.amazonaws.com/0/38864/bbe166da-4eb3-bb5d-5146-a4b840d4b2e6.png)
Socket.IOを活用したリアルタイムWebサイト構築事例

#Socket.IO Meetupで発表した資料
[SmartFX](http://smartfx.minkabu.jp)でのSocket.IO活用事例という題でLTを行ってきました。
[英語版](http://www.slideshare.net/ssuser69ee9b/socketio-on-smartfx)
[日本語版](http://www.slideshare.net/ssuser69ee9b/smart-fxsocketio)

Socket.IOの作者がいらしているということもあって、英語のパワポで挑戦したものの、初めてのLTということもあり、自分でも何をいっているかわからなかったため、記事で補足します。

#Socket.IO-reqevについて
[socket.io-reqev](https://github.com/takeshy/socket.io-reqev)は、EventEmitterを活用することで、モジュール同士の結合をなくすというJavaScriptでよく使われる戦略を使っています。

イベントを送りたいモジュールは、socket.ioにまったく依存することなく、イベントをただemitするだけで、その内容がクライアントに届くようになります。
そのため、Socket.IO-ReqEv使いたくなくなった場合の対応も容易ですし、Socket.IO-ReqEv以外にもログのようなモジュールを簡単にはさめます。
また、NameSpaceに対してどのモジュールが結びついているのか、モジュールが何のイベントを送信しているのかがすぐ把握でき、保守もすごく楽です。

さらにイベントだけでなく、単にその時点の情報を取得したいという場合にrequestという仕組みがあるため、Push通信のために使うというのではなく、APIサーバとして使うことが可能です。

SmartFXでは、ユーザ情報などSNS的要素はWebサーバ、為替レートなどのマーケット情報は、Socket.IOサーバというように、扱うサーバによって扱う情報をまったく分けることで、DBの構造の変更が別のサーバに影響を与えないようになっています。

内部的に指定されたNameSpaceのroomしか管理していないので、直接Socket.IOオブジェクトのオプションをいじったり、違うNameSpaceをつかって、Socket.io-reqevを使わずに処理を行うことも可能です。


#Socket.IOサーバの運用について
やってることはドロくさいのですが、まあ、実運用ってそんなものでしょう？
リバースプロキシとかでやるとかっこいいとは思いますが、そのリバースプロキシ自体の冗長化を考える必要がでてきたり、コネクションはったままのSocket.IOに対してどうdeployをするかといったことを考えると、なんだかんだで今回のやりかたが今のところベターなのではと感じています。

#その他
英語化は会社の同僚の方がほとんど手直ししてくれたのにうまく発表できなくて、正直すまんかった。
Nginx + Rapid SSL更新超簡易版


超簡易版として残しておきます。

# cert.keyを作成

rapid sslのサイトにてCSRと秘密鍵を生成。CSRは次の手続きに進むために必要。
秘密鍵はサーバに置いておくのでcert.keyとして保存。

# cert.pemを作成

手続きを進めると、サーバー証明書と中間証明書がメールで送られてくる。
それらをファイルで連結して、cert.pemとして保存。

``` cert.pem
-----BEGIN CERTIFICATE-----
〜
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
〜
-----END CERTIFICATE-----
```

# nginxの設定

証明書をサーバに保存して、nginxで証明書のパスを指定。
nginxを再起動すると証明書が切り替わってる。

```
server {
    listen               443;
    server_name          www.example.com;
    ssl                  on;

    ssl_certificate      /path/to/cert.pem;
    ssl_certificate_key  /path/to/cert.key;
    
    ssl_protocols        SSLv2 SSLv3 TLSv1;
    ssl_ciphers          HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;

    ...
}
```


# 再起動時に求められるパスワードを無効にする

```
# cp cert.key cert.key.org
# openssl rsa -in cert.key.org -out cert.key
```
submoduleからsubtreeに移行するときにハマったことども

# まとめ
git subtree add するときには、取り込むリポジトリのヒストリも取り込んでいることを意識しましょう。

# 実行したコマンド
メインのプロジェクトの中で、submoduleとして別プロジェクトのリソースを管理しているような構成のリポジトリがあったとします。

```
<PROJECT_ROOT>
├─ 諸々の開発リソース
└─ Library1（submoduleとして管理しているライブラリ）
     └─ Library1のリソース一式
```

こんなコマンドを実行して、submoduleで管理していたライブラリをsubtreeに移行しました。

```zsh
# masterから作業用ブランチを作成
git branch -b working

# submoduleを解除し、リソースを全て削除
git submodule deinit ./Library1
git rm -rf ./Library1
git commit

# Library1をsubtreeとして追加する
git remote add lib1 git@github.com:someuser/Library1.git
git subtree add --prefix Library1 lib1 master --squash
# この時点でマージコミットが実行されるため、ひとまずsquashしてみる
git checkout master
git merge working --squash
git push origin master
```

実行後、リソースは問題なく追加できていたのですが……以下のような現象に苦しめられました。

## 現象
```git subtree pull```等のコマンドを実行しようとしても、コマンドが正常終了しない。

## 原因
masterをworkingにマージするとき、```--squash```オプションをつけていたため
```git subtree add```実行時のマージコミットも纏められてしまい、どのリポジトリから何を参照しているのか判らない状態になっていた。

## 対策した内容
```git subtree add```で追加したLibrary1を削除した後、もう一度```git subtree add```で取り込み直す。
```git merge master```を実行するとき、```--squash```オプションをつけずに実行する。

```zsh
# masterから作業用ブランチを作成
git branch -b retry

# submoduleを解除し、リソースを全て削除
git rm -rf ./Library1
git commit

# Library1をsubtreeとして追加する
git remote add lib1 git@github.com:someuser/Library1.git
git subtree add --prefix Library1 lib1 master --squash
# git subtree addで発生したマージコミットはsquashしない
git checkout master
git merge retry
git push origin master
```
Rails Guideのサンプルコードの syntax error を修正してプルリクエストを送る

# Rails Guideのサンプルコードの syntax error を修正してプルリクエストを送る

## 概要
Rails Guideの誤記を確認し、修正のプルリクエストを送るまで

## 経緯
Rails Guide の *Active Record Validations* を読んでいたところ
気になるサンプルコードが。

**5.5 Combining Validation Conditions** のサンプルコード

http://guides.rubyonrails.org/active_record_validations.html#combining-validation-conditions

~~~ruby
class Computer < ActiveRecord::Base
  validates :mouse, presence: true,
                    if: ["market.retail?", :desktop?]
                    unless: Proc.new { |c| c.trackpad.present? }
end
~~~

*if* シンボルの行末にカンマがない。 *syntax error* かな？
*validation* の *if/unless* 列挙のパターンは使ったことがないので、
本当に *syntax error* か確認してみよう。

## 確認

ちょうど *Rails4* の動作確認をしていたので *Rails* のプロジェクトは起動中。
上記のサンプルのケースにあうモデルを作ろう。
まずは *generate* と *migration* 。

~~~bash
$ rails g model computer mouse:string trackpad:boolean
$ rake db:migrate
~~~

モデルとテーブルができたので、各メソッドのValidation呼び出しが通るように適当にモデルを変更する。

~~~ruby
class Computer < ActiveRecord::Base
  validates :mouse, presence: true,
                    if: ["market.retail?", :desktop?]
                    unless: Proc.new { |c| c.trackpad.present? }

  class Market
    def retail?
      true
    end
  end

  def market
    Market.new
  end

  def desktop?
    true
  end
end
~~~

そして、 *rails console* (pry) で動作確認

~~~bash
$ rails c
[1] pry(main)> c = Computer.new
SyntaxError: /home/vagrant/work_rails/blog/app/models/computer.rb:4: syntax error, unexpected ':'
                    unless: Proc.new { |c| c.trackpad.present? }
                           ^
from /home/vagrant/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/activesupport-4.1.1/lib/active_support/dependencies.rb:443:in `load'
~~~

案の定エラー。
では、カンマを付けてみる。

~~~bash
$ rails c
[1] pry(main)> c = Computer.new
=> #<Computer id: nil, mouse: nil, market: nil, type: nil, trackpad: nil, created_at: nil, updated_at: nil>
~~~

問題なくインスタンスを作成できました。
やはり、 *syntax error* のようなのでプルリクエストを作成します。

前に一回 Rails Guilde のプルリクエストはマージしてもらっているので手順はわかってる。

* [はじめてのPull Request。Rails GuidesにPull Requestを送ってみたら瞬殺でマージされた](http://d.hatena.ne.jp/tbpg/20140214/1392387704)

上記の手順で1文字カンマを足すだけの簡単なお仕事です。

## プルリクエスト作成完了

https://github.com/rails/rails/pull/16038

## しばし待つ

しばし待つ・・・と思ったら *1分と立たずにマージされました*
前回プルリクエストした時もあっという間にマージされたし、 *Rails* コミッター陣のマージは神速。

## 参照

* Rails Guide. Active Record Validations の 5.5 Combining Validation Conditions

http://guides.rubyonrails.org/active_record_validations.html#combining-validation-conditions

* GitHubのRails Guide

https://github.com/rails/rails/blob/master/guides/source/active_record_validations.md
Dockerでpm2


pm2でNode.jsをプロセスを起動すると、pm2自身はすぐに終了してしまう。
なのでDockerのCMDでpm2を開始してもコンテナは停止してしまう。

こまったーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー。

全然困らなかった。

pm2に `--no-daemon` というオプションが追加されていたので、それでOKでした。

https://github.com/Unitech/pm2/issues/259

## Dockerfileやら何やら

**Dockerfile**

```docker
FROM node

WORKDIR /nodeapp

ADD package.json /nodeapp/
ADD index.js /nodeapp/

RUN npm install

EXPOSE  1337

CMD ["node_modules/pm2/bin/pm2", "--no-daemon", "start", "index.js"]
```

**package.json**

```json
{
  "name": "docker-pm2",
  "version": "0.0.1",
  "description": "Docker pm2 example",
  "main": "index.js",
  "author": "5t111111",
  "dependencies": {
    "pm2": "latest"
  }
}
```

**index.js**

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

## 起動

```console
$ docker build .
```

```console
$ docker run -P -d <イメージID>
```

```console
$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                     NAMES
f89174a4ac15        392c405d84f6        node_modules/pm2/bin   48 seconds ago      Up 47 seconds       0.0.0.0:49169->1337/tcp   sad_shockley
```

```console
$ curl -i localhost:49169
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Thu, 03 Jul 2014 14:57:45 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Hello World
```
zshのメニュー補完で候補をインタラクティブに絞り込む

`zsh`で補完を`menu-complete`にすると補完候補が多い場合に候補選択が面倒ですが、設定次第で候補をインタラクティブに絞り込めるようになります。
※ 使用したのは`zsh 5.0.2`


## メニュー補完絞り込み設定例

```zsh:.zshrc
autoload -Uz compinit && compinit -u
zstyle ':completion:*' menu select interactive
setopt menu_complete
```

`zshrc`などに上記の設定を追加すると、補完開始と同時に絞り込み機能が有効になり、以下のように`Functions/Zle/`というパスを`F/Zl/`というキー入力で絞り込むことが出来るようになります。

![menuselect-interactive.png](https://qiita-image-store.s3.amazonaws.com/0/30947/41f962f5-6e48-e661-b541-991c9c1395e8.png)

※`setopt menu_complete`を設定しない場合は補完開始直後に絞り込みが開始されず、再度補完開始のキーを叩いた時に絞り込みが開始になります。

## メニュー補完のキーバインドを設定して使い易くする

絞り込み機能を有効にすると、設定次第ではメニュー補完での候補移動が出来なくなってしまう場合があります。
自分の場合は`^f`,`^b`,`^n`,`^p`で候補を移動してキー入力で絞り込みを行う事を両立させたかったので、以下のような設定にしてあります。

```zsh:.zshrc
zmodload zsh/complist                                         # "bindkey -M menuselect"設定できるようにするためのモジュールロード
bindkey -v '^a' beginning-of-line                             # 行頭へ(menuselectでは補完候補の先頭へ)
bindkey -v '^b' backward-char                                 # 1文字左へ(menuselectでは補完候補1つ左へ)
bindkey -v '^e' end-of-line                                   # 行末へ(menuselectでは補完候補の最後尾へ)
bindkey -v '^f' forward-char                                  # 1文字右へ(menuselectでは補完候補1つ右へ)
bindkey -v '^h' backward-delete-char                          # 1文字削除(menuselectでは絞り込みの1文字削除)
bindkey -v '^i' expand-or-complete                            # 補完開始
bindkey -M menuselect '^g' .send-break                        # send-break2回分の効果
bindkey -M menuselect '^i' forward-char                       # 補完候補1つ右へ
bindkey -M menuselect '^j' .accept-line                       # accept-line2回分の効果
bindkey -M menuselect '^k' accept-and-infer-next-history      # 次の補完メニューを表示する
bindkey -M menuselect '^n' down-line-or-history               # 補完候補1つ下へ
bindkey -M menuselect '^p' up-line-or-history                 # 補完候補1つ上へ
bindkey -M menuselect '^r' history-incremental-search-forward # 補完候補内インクリメンタルサーチ
```


この中で一番重宝しているのは`accept-and-infer-next-history`です。
これを設定したキーを叩くと選択した補完候補がディレクトリの場合に候補を決定し、更にそのディレクトリ内で直ぐメニュー補完を開始してくれるのでキータイプをかなり減らすことが出来ます。

これで候補が多い場合でもメニュー補完を快適に使えるようになりました。
rootだけtty無しのsudoを許可

Chef、Capistrano、ansibleを触ったことがある人なら誰もが通る道。
いざ実行すると失敗するアレである。

# デフォルトでttyなしのsudoは拒否

デフォルトでttyなしの sudo が許可されてないことが多いので、なるべくしてそうなる。
ssh で sudo 付きコマンドを実行されるのを防ぐとかなんとか…

```:/etc/sudoers
Defaults    requiretty
```

# ユーザ別許可設定

上記の設定をコメントアウトしてしまう手もあるが、ノーガード感があるので却下。
そもそもrootでのssh接続なんて許可してないし、rootなのにsudoがどうとか小さい話じゃないか、
という気がしてきたのでrootだけ許可してみた。
ユーザ指定の書き方はこう↓

```:/etc/sudoers
Defaults    requiretty
Defaults:root    !requiretty
```

グループも同じ↓

```:/etc/sudoers
Defaults    requiretty
Defaults:%wheel    !requiretty
```

# コマンド別許可設定

ちなみにコマンド別の拒否設定はこう↓

```:/etc/sudoers
Defaults    requiretty
Defaults!/path/to/command    !requiretty
```

# 参考

AWS OpsWorksではこうしてた。
1行目でコマンドをリストして、2行目でまとめて `!requiretty` してるように見える。

```:/etc/sudoers.d/opsworks-agent
aws ALL=NOPASSWD:/opt/aws/opsworks/current/bin/chef_command_wrapper.sh, /opt/aws/opsworks/current/bin/chef-client, /opt/aws/opsworks/current/bin/opsworks-agent-uninstaller
Defaults:aws !requiretty

```

大幅な編集リクエスト求む。
Windowsのメモ帳でソースコードを保存してはいけない

# 問題

~~Windowsのメモ帳で文字コードをUTF-8で保存すると必ずBOM有りになります。~~

このBOMが曲者で原因不明のコンパイルエラーになったり、差分比較ツールでファイルの先頭に謎の差分が出てきたり、Gitでバイナリ扱いになったりと何一ついい事がありません。

~~また、文字コードにUnicodeを選択して保存すると、実際はUTF-16で保存されます。
紛らわしいですね。~~

## 追記
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/5a110243-84ed-7fab-91a1-8ea3d3687570.png)
Windows 10 May 2019 Update 1903のメモ帳からBOMなしUTF-8がデフォルトの保存形式になりました。
また紛らわしかったUnicodeがUTF-16 LEとUTF-16 BEになりました。

# 対処方法

## Windows 10 May 2019 Update 1903以降

メモ帳で保存時にUTF-8で保存する。

## Windows 10 May 2019 Update 1903より前

残念な事にメモ帳はBOM無しUTF-8で保存できません。
無用なトラブルを避ける為に、メモ帳の使用は避けましょう。

# 参考

* [バイトオーダーマーク(BOM)](http://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF)
* [メモ帳](http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E5%B8%B3)
* [「メモ帳」に多数の改善、BOMなしUTF-8がデフォルト保存形式に ～「Windows 10 19H1」 - 窓の杜](https://forest.watch.impress.co.jp/docs/news/1157696.html)
ClojureのProtocol

Clojureのdefprotocolについて調べてみた。Javaでいうインターフェースのようなものなんだけど、Clojureは動的型の言語なので、インターフェース(のようなもの)があることで、何がよいのか、というのが今回のテーマです。  
まずは使ってみるところから。

# Protoclの定義
```clj
(defprotocol Hoge
  (foo [this])
  (bar [this a b]))
```
これで、defprotocolを呼び出したネームスペースにfooという関数とbarという関数が定義されます。（ns-internsで確認できます。)  

# protocolの実装
このプロトコルに対する実装を与えるコードは以下のようになります。

```clj
(defrecord Hoge1 []
  Hoge
  (foo [this] "this is Hoge 1")
  (bar [this a b] (str a b)))

(defrecord Hoge2 []
  Hoge
  (foo [this] "this is Hoge 2")
  (bar [this a b] (str b a)))
```

関数を実行すると以下のようになります。

```clj
(foo (Hoge1.))
=> "this is Hoge1"

(foo (Hoge2.))
"this is Hoge2"

(bar (Hoge1.) "a" "b")
=> "ab"

(bar (Hoge2.) "a" "b")
=> "ba"
```
プロトコルを通じて、fooやbarという同一のネームスペース・名前の関数に多態性(第一引数のインスタンスによって関数の振る舞いが変わる)が与えられたのがわかると思います。

# protocolの作成単位
protocolは標準実装を定義することはできないので、一つのプロトコルに沢山の関数を用意すると、レコードを一つ作るたびに実装を行うコードを書かなければいけません。
このため、1つのプロトコルに用意する関数は少なくしたほうが、分かり切った実装を何度も書かなくて済むようになります。


# 参考文献
* [Clojure - protocols](http://clojure.org/protocols)
*  [Clojureのprotocol実践 - 矢野勉の技術ブログ](http://tyano.shelfinc.com/post/75348898784/clojure-protocol)
* [Clojure Programming](http://shop.oreilly.com/product/0636920013754.do)
Mechanizeでページ遷移しながらスクレイピング


ちょっとダルいポイントが有ったのでメモ程度に。
スクレイピング対象サイトとスクレイピングの流れは

* ページャで何ページか一覧ページがある
* 一覧ページのタイトルをクリックすると詳細ページが見れる
* 詳細ページの一部を使用
* また他のタイトルをクリックしていく
* CSVで出力（別にいらないけどメモ代わりに。。）

みたいな感じです。mechanizeだけでやります。

```ruby
require 'mechanize'
require 'csv'

class ScrapingPages

  def initialize
    @agent = Mechanize.new
    @data = []
  end

  def retrieve
    # 1ページ目から10ページ目までスクレイピングする
    (1..10).each do |i|
      page = @agent.get(url(i)
      each_section(page) do |section|
        title = section.css('h2.title > a').first.text
        detail = @page.links_with(text: title).first.click
        @data << {
          title: title,
          detail: detail.links.first.text
        }
      end
    end
  end

  def each_section(page)
    page.search('.articleBox').each do |section|
      yield section
    end
  end

  def url(current_page)
    "https://hogehoge.com/#{current_page}"
  end

  def make_file_as_csv
    CSV.open("./csv/scraping-#{Time.now.to_i}.csv", "wb", encoding: 'Shift_JIS') do |csv|
      csv << %w(title detail)
      @data.each do |record|
        csv << [record[:title], record[:detail]]
      end
    end
  end
end

scraping_pages = ScrapingPages.new
scraping_pages.retrieve
scraping_pages.make_file_as_csv

```


コードは実際のものとちょこちょこ変更箇所あるので流しでいいのですが、ポイントはclickのところ。
mechanizeは中でnokogiriを使っているようで、
上記の@agent, pageとかはmechanizeクラスが親のオブジェクトなのですが、
.cssとか使うと返ってくるオブジェクトがnokogiriクラスのインスタンスオブジェクトが返ってきます。

で、clickメソッドはmechanizeクラスに対してしか使えないので、微妙に工夫が必要。

```ruby
title = section.css('h2.title > a').first.text
detail = @page.links_with(text: title).first.click

# .css('h2.title > a').first.clickとかすると、
# nokogiriがclickメソッド持ってないのでエラーになる。
```

ここです。title変数で一旦クリック個所のテキストを格納しておいて、
mechanizeクラス継承の@pageに対してリンクを辿ってテキストを指定してクリックする、と。

csvはよく忘れるのでメモ程度に載せただけです。

もっと良いやり方あるかもだけど。
Mac便利なシェルコマンドメモ


## nkf: 文字コード変換
### インストール
```bash
$ brew install nkf
```

### 使用例
```bash
$ # 文字列コードを調べる
$ nkf -g data1.sjis.csv
Shift_JIS

$ # UTF-8へ変換[オプション-w]
$ nkf -w data1.sjis.csv > data1.utf8.csv
$ nkf -g data1.utf8.csv
UTF-8

$ # Shift_JISへの変換[オプション-S]
$ # 同じファイル名で変換[オプション--overwrite]
$ nkf -s --overwrite data1.csv
$ nkf -g data1.csv
Shift_JIS 
```

## qpdf: PDFのパスワード操作
### インストール
```bash
$ brew install qpdf
```

### 使用例
```bash
$ # パスワード"test"のロックがかかったPDFファイルを開く
$ qpdf --decrypt --password=test doc.locked.pdf doc.unlocked.pdf
```

## zip: ファイルの圧縮・解凍
### 使用例
```bash
$ # パスワード保護[オプション-e]
$ # 複数のファイルを一つの圧縮ファイルへ[オプション-r]
$ zip -e -r compressed.zip *.png
Enter password:
Verify password:
  adding: test1.png (stored 10%)
  adding: test2.png (stored 14%)

$ # 解凍
$ unzip compressed.zip
```

## tar: ファイル圧縮・解凍
### 使用例
```bash
$ tar zcvf compress.tar.gz data # 圧縮
$ tar zxvf compress.tar.gz # 解凍
```

## wget: ファイルダウンロード
### インストール
```bash
$ brew install wget
```
### 使用例
```bash
$ # ファイル名を指定してダウンロード
$ wget http://google.com -O google.html

$ # 再帰的にリンクをたどる[オプション-r]
$ # 深さを指定する[オプション-l]
$ wget -r -l 10 http://qiita.com

$ # Basic認証のあるサイトからダウンロード
$ wget --user=username --password=pass http://example.com

$ # バックグラウンドでダウンロード
$ wget -b http://http://qiita.com
```
フラットなナビゲーションバー


下部の影がどうしても消せなくて、これが正解なのか分からないけど、なんとかできた。

事前にprefixファイルに下記を追記しています

```objc:***-Prefix.pch
#define RGB(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
```

---

設定はこちら

```objc:AppDelegate.m

// ナビゲーションバーのテキストカラーを設定
[UINavigationBar appearance].titleTextAttributes = @{NSForegroundColorAttributeName: RGB(255, 255, 255)};
    
// ナビゲーションバーの影を消す
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
									forBarPosition:UIBarPositionAny
									barMetrics:UIBarMetricsDefault];

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
    
// ナビゲーションバーの背景色を設定
[[UINavigationBar appearance] setBackgroundColor: RGB(101, 181, 23)];
    
// ステータスバーのテキストカラーを設定
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    
// ステータスバーの背景色を設定
UIView* statusBarBg = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
statusBarBg.backgroundColor = RGB(101, 181, 23);
[self.window.rootViewController.view addSubview:statusBarBg];

```

すごく無理なやり方で気持ち悪いです（汗

簡単な方法をご存知でしたらおしえてください！
注目の開発技術100選 (Develop100)・ゲームエンジンまとめ

~~世界で最も成功したゲーム開発技術ランキング~~ 注目の開発技術100選(Develop 100)
http://content.yudu.com/A2xcc7/Dev100TechList2014/resources/index.htm?referrerUrl=
が公開されていたので、勉強も兼ねてゲームエンジンを抽出したまとめを作りました。

| 順位 | 名称 | 説明 |
|:-----------|:------------|:------------|
| 2     | Unreal Engine | 主にFPS向けな3Dゲームエンジン |
| 3     | Unity | マルチプラットフォームな3Dゲームエンジン |
| 11    | CryENGINE | 主にFPS向けな3Dゲームエンジン |
| 17    | Havok Vision Engine | 多機能なマルチプラットフォーム対応ランタイムテクノロジー |
| 22    | Scaleform Mobile SDK | Flashをゲームに組み込むScaleformのモバイル版 |
| 35    | GameMaker:Studio | 海外インディーズで人気のゲーム開発ツール |
| 37    | ProjectAnarchy | Havokが開発するモバイル向けゲームエンジン |
| 41    | CoronaSDK | FlashLiteの元開発者チームによるモバイル向けゲームエンジン(言語はLua) |
| 43    | Construct2 | HTML5ベースのゲーム製作ツール |
| 44    | PhyreEngine | ソニー製ゲームエンジン。主にPS向け |
| 47    | ShivaEngine | クロスプラットフォームの3Dゲーム開発ツール |
| 57    | Turbulenz Engine | 2D/3Dに対応したHTML5ゲームエンジン |
| 63    | CocoonJS | HTML5ベースのゲームエンジン |
| 64    | Pygame | Python用のゲームライブラリ |
| 69    | HeroEngile | オンラインゲーム開発用プラットフォーム |
| 70    | MonoGame | .NETベースのゲームフレームワーク(XNAを移植) |
| 72    | Torque2D | クロスプラットフォーム対応の2Dゲームエンジン |
| 73    | AppGameKit | DarkBASICでお馴染みのTGC社のクロス(マルチプラットフォーム)開発環境 |
| 75    | GooEngine | HTML5とWebGLベースのグラフィックスエンジン |
| 83    | GameSalad | プログラム不要のマルチプラットフォーム・ゲームエンジン |
| 91    | Rapid2D | Windows用の2Dゲームエンジン |
| 98    | SGX Engine | マルチプラットフォームなグラフィックスエンジン |

まとめていて、ゲームエンジン（ライブラリ含む）にこれだけの種類があったことに驚きました。

Unreal Engine や CryENGINEなどのガチな3Dエンジンから、Construct2やGameSaladなどプログラム不要なゲーム作成ツールまでランクインしていて面白いですね。

最近になってようやく私もマルチプラットフォーム対応のエンジン(GameMaker:Studio)を使うようになったのですが、もうマルチプラットフォームが当たり前というか、……競争が激しすぎです。そうなると、この先生きのこるエンジンがどれになるのか非常に気になります。

ちなみに私が今使っているのは、このリストには書いていないですが、45位にあった「Haxe」という言語の「HaxeFlixel」というクロスプラットフォームなゲームライブラリを使用しています。

そういえば、日本だとモバイル向けなマルチのゲーム開発環境としては Unity か Cocos2d の二強だと思っているのですが、ランキングにCocos2d の名前がありませんでした……。意外に海外では使われていないのでしょうか。

あとこのリストは、私が使ったことないエンジンばかりなので、間違っている情報があるかもしれません。もしあったらごめんなさい。