OmniAICreator/Qiita-1.07M huggingface dataset:
JBoss Data Virtualization でDB仮想化(1)-セットアップ


ビッグデータの活用が本格的になり、散在する複数のデータソースを横断的に分析するために、データをどう取り扱うべきかを考えることが多くなりました。

アプローチ方法として最も一般的なのは「専用の分析環境のDWHにデータを収集する」というものだと思います。実際、ログの収集はfluentdでオブジェクトストレージへ、WebサービスのデータやDBのデータはDWHへデータ連携して取り込むといったソリューションが広く知られるようになりました。

ただし、データ連携でデータソースから分析環境に連携する場合、データソースとのタイムラグが避けられないことや、データの二重管理やガバナンス面での懸念などが考えられます。

そこで、従来からあるもう一つのアプローチが「データベース仮想化」です。

# データベース仮想化のソリューション
データベース仮想化の手法もたくさんありますが、ここで紹介するRed HatのJBoss Data Virtualizationは最もシンプルに複数のデータベースをマッピングして仮想統合できる製品です。

# インストール
## 準備するもの
- Amazon EC2：Windows Server 2008 R2（AMI ID: i-5489ab52、インスタンス: r3.largeくらいだと開発が快適）
    - 公式にはアナウンスされていないが、一般的には以下のようなスペックが利用されているらしいです。

```
○ 本番サーバ
– CPU    Dual Core以上
– RAM    8GB以上
– HDD    60GB以上
○ 開発サーバ
– CPU    Dual Core以上
– RAM    8GB以上
– HDD    60GB以上
○ 開発端末
– CPU    特に指定なし
– RAM    4GB以上
– HDD    アプリケーション：1.5GB以上

開発物：2GB以上
```

- redhatのカスタマーポータルから以下を入手
    - Red Hat JBoss Data Virtualization 6.0.0 Installer
    - Red Hat JBoss Developer Studio 7.1.1 Stand Alone Universal Binary
- JDK 1.6以上をダウンロード
- データソースとの接続用にJDBCドライバーを入手
    - Redshift用にはPostgreSQL JDBCドライバーが使える
    - 今回はMySQLも使うので、Oracleからダウンロードする
- 参考ドキュメント
    - [JBoss Data Virtualization 6.0 Installation Guide](https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Data_Virtualization/6/html/Installation_Guide/index.html)
    - [Red Hat JBoss Developer Studio 7.1 Installation Guide](https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Developer_Studio/7.1/html/Installation_Guide/index.html)

## インストール作業
1. Oracle JDKをダウンロードしてインストールする
2. JDBCドライバーをダウンロードして適当なフォルダに格納しておく
3. JBoss Data Virtualizationのインストーラーを起動してGUIセットアップ

> java -jar jboss-dv-installer-6.0.0.GA-redhat-4.jar

4.Developer Studioのインストーラーを起動してGUIセットアップ

> java -jar jbdevstudio-product-universal-7.1.1.GA-v20140314-2145-B688-2.jar

これだけでセットアップはOK。次回以降に仮想データベースの作成やデプロイをしてみます。
MySQLで簡単にランダムなテストデータを作成する方法


MySQLで大量のダミーデータをテスト用に必要だったため、WEBをググって情報を集めてみました。
SQLだけで実現しているので使いやすいかと思います。

##データ型別のランダムデータ作成方法

INT（1〜100の範囲）

```sql
SELECT CEIL(RAND() * 100);
```

CHAR（10文字）

```sql
SELECT SUBSTRING(MD5(RAND()), 1, 10);
```

CHAR（特定文字列とランダム数値の連結）
※ランダム数値をAUTO_INCREMENT値にすればテーブルでユニークな文字列となる

```sql
SELECT CONCAT('ユーザー', CEIL(RAND() * 100));
```

DATE（2014-07-01から31日の範囲）

```sql
SELECT DATE_ADD('2014-07-01', INTERVAL 31 * RAND() DAY);
```

DATETIME（2014-07-01 00:00:00から31日の範囲）

```sql
SELECT ADDTIME(CONCAT_WS(' ','2014-07-01' + INTERVAL RAND() * 31 DAY, '00:00:00'), SEC_TO_TIME(FLOOR(0 + (RAND() * 86401))));
```

##大量のテストデータの作成方法

テーブルを作成

```sql
CREATE TABLE item (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(10),
  description VARCHAR(30),
  price INT UNSIGNED,
  created_at DATETIME
);
```

テーブルに大量の空データを挿入

```sql
INSERT INTO item () VALUES (); --1行作成
INSERT INTO item (id) SELECT 0 FROM item; --2行になる
INSERT INTO item (id) SELECT 0 FROM item; --4行になる
INSERT INTO item (id) SELECT 0 FROM item; --8行になる
INSERT INTO item (id) SELECT 0 FROM item; --16行になる
-- 20回繰り返すと100万行になる
```

空データを型に合わせてランダムな値に更新

```sql
UPDATE item SET
  name = CONCAT('商品', id),
  description = SUBSTRING(MD5(RAND()), 1, 30),
  price = CEIL(RAND() * 10000),
  created_at = ADDTIME(CONCAT_WS(' ','2014-01-01' + INTERVAL RAND() * 180 DAY, '00:00:00'), SEC_TO_TIME(FLOOR(0 + (RAND() * 86401))));
```

### 参考にしたサイト

[[mysql] 日付と文字列（単語）ランダムデータの入力](http://blog.livedoor.jp/qoozy/archives/52638309.html)
[さくっと100万件レベルのデータのテストデータを作成する方法](http://www.softel.co.jp/blogs/tech/archives/4730)
Adaptorパターン


## 概要
デザインパターンの一つAdaptorパターンの練習用の実装とそれに関するまとめを書いてみました。

## サンプルプログラム
既存のクラスjava.util.Propertiesクラスを使いやすいようにFilePropertyクラスでラップし、FilePropertyクラスを利用する側にFileIOインタフェースを提供し、キーと値のマップを簡単にファイル入出力を行えるようにする。

```Java:FileIO.java
public interface FileIO {
    public abstract void readFromFile(String fileName) throws IOException;
    public abstract void writeToFile(String fileName) throws IOException;
    public abstract void setPropertySet(String key, String value);
}
```

```Java:FileProperty.java
import java.io.*;
import java.util.Properties;

public class FileProperty extends Properties implements FileIO {
    @Override
    public void readFromFile(String fileName) throws IOException {
        load(new FileInputStream(fileName));
    }

    @Override
    public void setPropertySet(String key, String value) {
        setProperty(key, value);
    }

    @Override
    public void writeToFile(String fileName) throws IOException {
        store(new FileOutputStream(fileName), "Output all property");
    }
}
```

たったこれだけです。それではメインクラスで利用してみたいと思います。入力ファイルとして input.txt を準備。

```Java:input.txt
year=2014
month=07
day=29
```

```Java:Main.java
public class Main {
    public static void main(String args[]) {
        FileIO fileio = new FileProperty();
        try {
            fileio.readFromFile("input.txt");
            fileio.setPropertySet("test", "1000");
            fileio.setPropertySet("test2", "aiueo");
            fileio.setPropertySet("test3", "???");
            fileio.writeToFile("output.txt");
        } catch (IOException ex) {
            ex.printStackTrace();
            return;
        }
    }
}
```

実行後の出力ファイルを見てみます。

```Java:output.txt
#Output all property
#Tue Jul 29 21:14:58 JST 2014
day=29
test3=???
test2=aiueo
year=2014
month=07
test=1000
```

ご覧の通り、input.txtに記載されていたキーと値のマップが出力ファイルに記載されています。そして、プログラム上でセットしたキーバリューも無事出力されていることがわかると思います。

## まとめ
・すでに提供されているものと必要なものとのずれをうめることを目的としたデザインパターンの一つ
・実際に既存のプログラムを少し修正するだけで提供できてしまうような要求があったとき、既存のプログラムを修正することでも要件は満たせてしまうが、それは既存のプログラム再度テストしなければいけないことにつながってしまう。
・既存の部品を利用する新しい部品を作ることで、バグが発生しても新しい部品内のバグがあるということがわかっているので管理もしやすくなると考えられる。
・イメージとしては既存のプログラムを利用しやすいようなAPIを作るような感じがした。
knife soloで「FATAL: Cannot find sub command for: ‘solo'」というエラーが出る場合の解決策

# 結論

Chef Soloを使う場合、Chefは公式からではなくgemから入れる。

# 理由

Mac OS Xで、Chefとknife-soloをそれぞれ以下のコマンドでインストールするとする。

```
$ curl -L https://www.opscode.com/chef/install.sh | sudo bash
$ sudo gem install knife-solo
```

このとき、以下のようなことが生じる。

1. `curl -L 〜`により、`/opt/chef`に`knife`コマンドがインストールされる
2. `sudo gem 〜`により、`knife-solo`の依存である`chef`もインストールされる
3. システムの`knife`コマンドは、gemのChefではなく`/opt/chef`を参照している
4. `/opt/chef`からは、gemである`knife solo`は見えないのでエラーとなる

ひとことでいうと、**2つの`knife`コマンドが共存している状態になる**。

ここで`knife solo prepare 〜`などとしても、`knife`からは`knife solo`が見えない。
このとき、タイトルのとおり以下のようなエラーが生じる。

```
FATAL: Cannot find sub command for: ‘solo'
```

公式から入れずとも、`gem install knife-solo`さえすれば自動的に依存である`chef`もインストールされる。
なので、Chef Soloを使うときは`gem install knife-solo`をすればよい。

※ 認識違いがあればコメントください！m(_ _)m

# 参考

- http://jsapachehtml.hatenablog.com/entry/2014/05/25/083527
- http://stackoverflow.com/questions/17115245/how-to-uninstall-chef-client-and-the-whole-chef-package
AWSトレーニング(Systems Operations on AWS)受講記録

# 概要

[AWSトレーニング(Systems Operations on AWS)](http://aws.amazon.com/jp/training/course-descriptions/sysops/)を受講してきました。
受講をするかどうかの判断の助けとなるよう受講記録を残します(内容は変更になる可能性があります)。

# 参加者

 * 講師(テクニカルトレーナー)：1名
  * +ソリューションアーキテクト：1名 ー 夕方から参加して最新のサービスを紹介したり質問に答えたりとサポート的に活動されていた。
 * 受講者：11名
  * AWSをある程度さわっている運用担当者が多い印象。

# 受講概要

 * 1日目から2日目の半分ほどまでVPC、IAM、EC2、AutoScalingといった伸縮自在なアーキテクチャを実現するためのサービスの説明。
 * 2日目から3日目でモニタリング、ロギング、セキュリティ、バックアップ、コスト管理、タグ付けなど伸縮自在な構成に対しての運用、管理に関わる部分の説明。
 * 各章ごとくらいでラボ(演習)や、数回のグループ別(3-4名)でのディスカッションがある。
 * こういう案件ですけど構成どう(こう)したら良いでしょうかみたいな質問にも個別に答えていただける。

# Architecting on AWSと比較して

 * 受講者は少ないがAWSを既にさわっている人が多くディスカッションでややディープな話が出る印象。
 * 全体的にArchitecting on AWSほど詰め込まれた感じがしない。
 * アーキテクチャに関する部分が前提としてあり重複する。運用寄りの話がされるとはいえArchitecting on AWS受講者としてはやや得られる情報が薄い。
 * Architecting on AWSほど多くのサービスを取り扱わない。運用で最低限必要な部分と運用関係のサービスの説明がある感じ。
 * Architecting on AWSではこの場合はこのアーキテクチャみたいなバシッと決まる感があるが、System Operation on AWSはこういう方法があり要件によって判断して使いわけるというところが多くモヤッとする。

# 所感

 * 体系的にAWSインフラの運用・管理に関する知識を習得でき、既にAWSをさわっている人は知識の整理ができ、さわってない人は効率的に知識を習得できる。
  * プロジェクトでAWS使い始めて運用担当者として関わっていくという場合や、AWSで運用しているけど今の運用方法で良いのか悩んでいる場合に利用すると良さそう。
  * 実践的なラボが多く実際の運用の参考になる。
  * ディスカッションを通して他の運用をされている方の話が聞け参考になる。
  * CloudWatch Logsのような新しいサービスについてはトレーニングとして組み込まれていないものの紹介していただけたのが良かった。
 * AWSに疑問に思っていた部分を質問で解消できる。
【SEO】descriptionsタグの文字数ってGoogleに書いてあった

meta descriptionsタグの文字数

１２０だか、１４０だか、、
見るサイトによって全然違います、、

で、結局何文字が妥当なの？

といつも思っていました。

で、別件でGoogleの提供するSEOマニュアルがあることを知り
調べてみると。

https://support.google.com/webmasters/answer/35291?hl=ja

「ページごとに、160 文字以下の固有の説明を設定しましょう。」
とのことでした。 

ボスが言うなら間違いない。
ということで、１６０文字以下で固有の説明を心がければOKということでした。

【追記】
Googleでは、１６０文字がフルに表示されない場合があり、
その点も考慮して、何文字が妥当かが検討されています。

なお、文字数の揺れは、UX改善によりフォントサイズが変動するためです。


tienlenさん、情報提供ありがとうございました。
systemctlでvncserverを自動起動

参考: [Fedora16 入れたはいいが… | okkyの日記 | スラッシュドット・ジャパン](http://slashdot.jp/journal/542689/Fedora16-%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%AF%E3%81%84%E3%81%84%E3%81%8C%E2%80%A6)

* 一度rootでvncserverを起動しpasswordの設定を済ませておく。
* /root/.fonts/にttfを置いておく
* `setxkbmap -model jp106 -layout jp`
  * vnc接続先からさらにvnc接続した時、キー配列がおかしくなることを防ぐ。

```bash:/root/.vnc/xstartup
xsetroot -solid grey
xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#
setxkbmap -model jp106 -layout jp
awesome &
virt-manager
```

```bash:
cp /lib/systemd/system/vncserver.service /etc/systemd/system/vncserver@:1.service
```

```diff:/etc/systemd/system/vncserver@:1.service
 [Unit]
 Description=vncserver

 [Service]
-User=
+User=root
 ExecStart=/usr/bin/vncserver %i

 [Install]
 WantedBy=multi-user.target
```

```bash:
systemctl enable vncserver@:1
systemctl start vncserver@:1
```
Swiftの関数の引数は、常に一つか

[Swiftの関数の引数は、常に一つ](http://qiita.com/dankogai/items/46fedc447dd93d1e0fbc)

単なる用語の混乱の話なんだけど、仮引数 parameter と言ったとき、大抵の場合は、`->`の左側のタプル全体ではなく、その個々の要素を指しているはずなので、「Swiftの関数の引数は、常に一つ」というには、そこで使われている「引数」なる用語は、ほかの部分で使っている「引数」とズレがある可能性を考慮にいれる必要があると思う。

たとえば [_The Swift Programming Language_](https://itun.es/jp/jEUH0.l) 17ページにも、“You can refer to parameters by number instead of by name”のような表現が出てくる。これに「引数は常に一つだから “the parameter” だ」とは言えないですよね。

「関数の引数は常に一つだ」などの異説を出す人がどんどん出てきてバベル的混乱が起きる前に用語集を整備する必要があると思う。
Karmaの ReferenceError: Can't find variable: chai エラーを解決

[フロントエンドエンジニア養成読本](https://gihyo.jp/book/2014/978-4-7741-6578-3)のテストランナーの項を写経してたら思いがけないエラーに遭遇したのでその解決方法。

まずは、本の通り、foo.jsとfoo_spec.jsを書いて設定ファイル(karma.conf.js)を作ってからターミナル上でKarmaを起動します。

すると、

>PhantomJS 1.9.7 (Mac OS X) ERROR
  ReferenceError: Can't find variable: chai

>Chrome 36.0.1985 (Mac OS X 10.9.4) ERROR
  Uncaught ReferenceError: chai is not defined

のエラーが。

そこで、

karma.conf.jsの中を見て、

`frameworks: ['mocha'],`の部分を
`frameworks: ['mocha', 'chai'],`と書き換えて再度ターミナル上でKarmaを起動します。


まだエラーが出ます。
> module.js:340
    throw err;
    ^
Error: Cannot find module 'chai'


念の為にchaiを単独でインストールしてみます。

`npm install chai`


無事、テストが通ります。
> INFO [karma]: Karma v0.12.19 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.7 (Mac OS X)]: Connected on socket 1yosHgWYO8vtW1NoG0JF with id 34000027
INFO [Chrome 36.0.1985 (Mac OS X 10.9.4)]: Connected on socket nTYAK3C5ieGDveSCG0JG with id 84770794
PhantomJS 1.9.7 (Mac OS X): Executed 4 of 4 SUCCESS (0.004 secs / 0.003 secs)
PhantomJS 1.9.7 (Mac OS X): Executed 4 of 4 SUCCESS (0.004 secs / 0.003 secs)
PhantomJS 1.9.7 (Mac OS X): Executed 4 of 4 SUCCESS (0.004 secs / 0.003 secs)
PhantomJS 1.9.7 (Mac OS X): Executed 4 of 4 SUCCESS (0.004 secs / 0.003 secs)
PhantomJS 1.9.7 (Mac OS X): Executed 4 of 4 SUCCESS (0.004 secs / 0.003 secs)
Chrome 36.0.1985 (Mac OS X 10.9.4): Executed 4 of 4 SUCCESS (0.024 secs / 0.003 secs)
TOTAL: 8 SUCCESS
gistをbl.ocks.org以外で動かす

# 背景

先日Qiitaに投稿された[ちょっとしたHTMLはGitHub Gistに置いてbl.ocks.orgで表示するのがお手軽です](http://qiita.com/hnakamur/items/ad1346bc9cfb0288ff60)という記事をはてブ経由で知りました。
自分はもっと前からbl.ocks.orgを知っていましたが、結構なブクマが付いていたので驚きでした。（ホントは悔しかったｗ。内容は自分にとってもへーって感じですごいなぁ色々調べてるなぁと後からこっそり見て感じましたｗ）

ちょうどこれと同時期に@Phiさんが[ログイン不要! 気軽にプログラミングを始められるWebエディタ『runstant』作りました](http://qiita.com/phi/items/e7fe30156c43a7690c1a)を投稿されました。

初めは、この2つは自分の中ではリンクせず、むしろ、gistを使ったbl.ocks.orgだと、gistを編集してから反映されるまでのタイムラグが当時気になり、トライ＆エラーなスタイルでの開発に向かないから、runstant推しって感じでした。

## gistをJSONPで取得できた

[Gist外部埋め込みHTMLをJSONPで受け取る](http://qiita.com/zaneli@github/items/8515089e2a786eed181e)なる投稿を見つけました。

## gistとrunstantが繋がった

そんな訳で、runstantはいつでもどこでも簡単に使えるので、gistの上げた、HTML,CSS,JavaScriptをrunstantで動かすツールを作ってみました。

# 成果物

色々と不具合ありそうなので、以下のGist経由で試して下さい。

- [kjunichi / gist2runstant4Chrome.md
](https://gist.github.com/kjunichi/8d1b214fa511f7b0f8f9)

# コマンドラインツールも鋭意作成中

近々、前述のツールを応用して、引数にgistのurl指定を実装したところですが、
現状は、ローカルファイルのrunstantでの実行のみです。

[Atom.io](https://atom.io/)やEmacs,viなど好みのエディタでrunstantが使えるようになります。（runstantのコンセプトと合わない気も。。）

- [kjunichi/runstant-cli](https://github.com/kjunichi/runstant-cli)

# あとがき

それにしても、CSSは未だに自由に扱えません。まぁ、JavaScriptが自由に扱えたりするわけでもありませんが。

gist2runstantはFirefox上で主に開発して当初はXPathでJSONPで取得したJSONからコードを取り出そうとしていたのですが、Chromeでは、XPathで取得する箇所でエラーになり、これに対応するために、正規表現で取得するようにしてます。なので、Firefoxでも動きます。

# 関連記事

- [JSONPでGitHubのGistからHTMLやJavaScriptのコードを取り出した](https://abrakatabura.hatenablog.com/entry/2014/07/30/214226)
chefでconf一式を反映させたい


chefで例えばapacheやnginxのconf一式（ `/etc/httpd/{conf,conf.d}` や `/etc/nginx` 配下）を作成させたい場合、

* template配下に大量のerbファイルが乱立してメンテコスト増
* 反映したい先のディレクトリ階層も違ったりして一つ一つtemplateで定義してると面倒

という問題があって、これをどうにかするために思いついた方法。

## 背景

chef入門のためとりあえず今までサーバ上で直接いじってたconfをリポジトリ管理にして、それをchefで反映させるところから始めるケースって多いんじゃないかと思います。

confファイルが1つ2つならいいんですが結構数ある場合や階層化させて体系化してる場合とか、まともに書くとrecipeの中身もtemplate配下もゴチャゴチャしてわかりにくい。

特に後から参画した方とか「このconf修正したいけど一々recipe見て該当erb探さなきゃいけない」のが面倒（直感的にわかりにくい）。
ただこれだけなんだけどchef導入の障害になってる気がしたので。

## 設定例

例えばnginxのcookbookを例とした場合、
attributeにこんな感じで基点となるディレクトリ名を定義しておいて、

```ruby:nginx/attributes/default.rb
default['nginx']['template_dir'] = "conf_web"
```

template配下に定義したディレクトリを作ってその配下に管理したいファイル一式を置いて、

```nginx/templates/default/conf_web
$ tree nginx/templates/default/conf_web
nginx/templates/default/conf_web
├── conf.d
│   ├── ssl.conf
│   └── virtual.conf
├── fastcgi.conf
├── fastcgi_params
├── nginx.conf
├── scgi_params
├── conf.d
│   ├── server.key
│   └── server.crt
└── uwsgi_params
```

recipeはこんな感じ。

```ruby:nginx/recipes/default.rb
Chef::Config[:cookbook_path].each{|elem|
  if File.exists?(File.join(elem, "/nginx/templates/default/", node['nginx']['template_dir']))
    conf_dir = File.join(elem, "/nginx/templates/default/", node['nginx']['template_dir'])
    Dir.chdir conf_dir
    confs = Dir::glob("**/*")

    confs.each do |t|
      if File::ftype("#{conf_dir}/#{t}") == "file"
        template "/etc/nginx/#{t}" do
          owner "root"
          group "root"
          mode 00644
          source "#{node['nginx']['template_dir']}/#{t}"
          notifies :restart, "service[nginx]"
        end
      else
        directory "/etc/nginx/#{t}" do
          owner "root"
          group "root"
          mode 00755
        end
      end
    end
  end
}
```

これで対象サーバの `/etc/nginx` 配下に `nginx/templates/default/conf_web` 配下のファイルやディレクトリ一式が作成される。

templateじゃなくてcookbook_fileでも応用可能。


やっぱり黒魔術かなぁ。。。
JAWS-UG CLI #0 参加メモ

2014/07/28(月)、記念すべき **JAWS-UG CLI #0** に参加させていただきました。
ということでメモ晒し。
今回はハンズオン中心だったので少なめ。

# 当日の流れ

## 準備
AWS個人アカウント
aws-cliインストール（参考：http://qiita.com/tcsh）

@tcshさんからCLI、S3についての入門編を聞いた際のメモ
## CLI入門
* awscli使用率はユーザーの2〜3割ぐらい（印象）
SDK使ってんのかな？マネージメントコンソール利用者が多い？
千葉はcli利用者多い気が（JAWS-UG千葉で聞いた際には約6割ぐらい使ってた）

* 従来：java-sdk
ver1.0当たりからawscli中心の流れ

* EMR,cloudfrontはpreview版でなら使える
しかし結構バグ多い…（特にloudfront）

* --profile オプション
config毎にdefaultのみだけ書いてsymlinkで切り替えする方法がおすすめ

* --quely オプション
jqの代替として使用できる（がそれほど高機能ではない。結局はjqはいる）
describe系 filterで絞込 quelyオプションで取り出す
「存在しない」を条件に出来ない

* --debug
AWS APIへの入出力内容を見れる
完全な形ではないので微妙

* 頻繁にversion上がるのでこまめに上げよう
* リファレンスおすすめ

* optionも--押してからだと補完が効く

## S3入門
AWS CLI for S3

* 2つのコマンド群
 * ハイレベルS3コマンド　ハイレベル=簡単な
 * s3apiコマンド

* リソース表記
 * s3://
 * file:// ← カレント file:/// ← フルパス

* ハイレベルS3コマンド $ aws s3
 * 出力はデフォルトでtext形式
 * syncは1000以上のファイルをuploadしようとすると、極端に遅くなる

* s3apiコマンド

## 自己紹介タイム
参加者全員で自己紹介をした際に、aws-cliでやりたいとまたはaws-cl愛を語ったので理由を少し分類

* AWS使い始めたのでコンソールからのみではなく、CLIでも操りたい
* マネージメントコンソールでの作業より高速化できそう
* ワンライナーで書きたい
* 綺麗に書けるようになりたい

自分はsed+awkつぎはぎから卒業したい派

## ハンズオン
ハンズオン内容
[[JAWS-UG CLI] S3:#1 ハイレベルS3コマンドを使ってみる (バケットの作成から静的Webホスティング、削除まで)](http://qiita.com/tcsh/items/edd5d65f1bc2f8d1819a)

上記の記事を元に全員で操作。
途中修正点やtipsを追加修正しながらわいわいと。（コメントの欄）

アップロード時のファイルのacl設定とwebsite hostingの設定部分で、少しハマル方もいたという印象。
オブジェクトのパーミッションは自分も結構わかってない部分多いので気をつけたい。

できたページはこちら
https://s3-ap-northeast-1.amazonaws.com/yuteno/index.html



## LT
2つやってくれました。参加すればこういう話も聞く機会があるということで…
（ほとんどメモとれてなかった…すいません）
### 1分でできるS3 Website hosting
### Docker仮想化について

## 今後の会の方針
* 年内いっぱいは隔週月曜日に会をやりたい
* 次回はRoute53
http://jawsug-cli.doorkeeper.jp/events/13530

* IAM系もやりたいな

## まとめ
aws-cli界隈初の会ということで、環境構築から始まり、
使い慣れている方から、最近使い始めた方まで様々でしたが、
参加者同士で教えあいつつ、新たな発見ありで大変楽しい会でした。

情報取得をワンライナー、構築系コマンドもオプションを書いて残しておくことで、
どういった内容でインスタンスを建てたかがわかり、
今後インスタンスを作成する際はこのコマンドを叩けばOKな状態にもできる。
そんなドキュメント化しやすいことがaws-cliの魅力。
ドキュメント駆動運用目指すぞ！

隔週月曜日19:00-21:00という日程なので、19時定時な自分は毎回参加は難しいですが、
今後も機会があったら参加させていただきたいです。
またQiitaで資料上がったら自習しておきます！

# おまけ
自分の過去のも一応貼っておく
[awscliとjqを設定](http://qiita.com/gacha-ru/items/6e18b7a8cdfdf0029f59)
[「特定のS3バケットのみ操作可能+アカウント内の他のバケットは見れない」ユーザーとバケット設定](http://qiita.com/gacha-ru/items/327f41178885519491bb)
Rails+postgresql+capistrano環境のwercker設定


無料でCIしたいと思って導入した[wercker](http://wercker.com/)。UIきれいですごくいい。

参考：http://devcenter.wercker.com/articles/introduction/

```wercker.yml
box: wercker/ubuntu12.04-ruby2.0.0
services:
    - wercker/postgresql
build:
    steps:
        - bundle-install
        - rails-database-yml:
            service: postgresql
        - script:
            name: echo ruby information
            code: |
                echo "ruby version $(ruby --version) running"
                echo "from location $(which ruby)"
                echo -p "gem list: $(gem list)"
        - script:
            name: Set up db
            code: bundle exec rake db:schema:load RAILS_ENV=test
        - script:
            name: rspec
            code: bundle exec rspec
deploy:
    steps:
        - bundle-install
        - script:
            name: make .ssh directory
            code: mkdir -p "$HOME/.ssh"
        - create-file:
            name: write ssh key
            filename: $HOME/.ssh/id_rsa
            overwrite: true
            hide-from-log: true
            content: $WERCKER_SSH_KEY_PRIVATE
        - script:
            name: set permissions for ssh key
            code: chmod 0400 $HOME/.ssh/id_rsa
        - cap
```

WERCHER_SSH_KEYはwercherの設定画面からkeyを設定します。

### 参考
設定ファイルが正しいかどうかを確認する[validate wercker.yml](http://devcenter.wercker.com/articles/werckeryml/validate.html)にだいぶお世話になりました。問い合わせもすごいちゃんと答えてくれて無料だけど運営すごい頑張ってる。
Vagrant Tips#8 gitをソースからコンパイルして利用する(centos)

##[Vagrant Tipsのサマリページはこちら](http://qiita.com/yukimura1227/items/7e34bb12d36e8aa2e6c3)

# この記事のサマリ
gitをソースからビルドして、さくっとgitが利用できるスクリプトを紹介いたします。

# 対象読者
yumやapt-getでインストールしたgitは古いから、新しいものが使いたい方向け

# 動作確認バージョン
`vagrant version`の結果
Installed Version: 1.7.4

# 経緯
「えっ、私のgit、古すぎっ！！！？？」ってなったので。。。

# gitをソースからコンパイルして利用する
一昔前は、svnやcvsなどの集中管理型のVCS(Version Control System)を利用して、開発をやることが多かったですが、最近ではソーシャルコーディングの流行という後押しもあり（？）、gitのような分散管理型のVCSを使うことが多いように感じます。
筆者がよく実験に利用しているcentOSでは、デフォルトではyumによるインストールができなかったため、ソースコードを取得して自動的にビルドしてgitを利用できる状態にするtipsを投稿いたします。

```ruby:Vagrantfile
Vagrant::Config.run do |config|
  config.vm.box = "centos64_6_5"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box"
 
  config.vm.provision "shell", path: "setup_git.sh"
 
end
```


```bash:setup_git.sh
#!/bin/bash

GIT_TARGET_VERSION="git-2.7.1"
ARCHIVED_GIT_FILE_NAME="${GIT_TARGET_VERSION}.tar.gz"
GIT_URL="https://www.kernel.org/pub/software/scm/git/${ARCHIVED_GIT_FILE_NAME}"

echo "install git dependent libs..."
sudo yum install -y zlib-devel perl-devel gettext gcc curl-devel

echo "get git source..."
wget ${GIT_URL} -O /tmp/${ARCHIVED_GIT_FILE_NAME}

echo "decompress ${ARCHIVED_GIT_FILE_NAME}..."
tar -xvzf /tmp/${ARCHIVED_GIT_FILE_NAME} -C /tmp/

echo "git compile..."
cd /tmp/${GIT_TARGET_VERSION}
./configure
make
sudo make install

# create synbolic link /usr/bin/git to /usr/local/bin/git"
echo "create symbolic link to git..."
sudo ln -s /usr/local/bin/git /usr/bin/git
```

「vagrant ssh」などで、vagrant環境に接続後、
「git version」と入力して、「git version 2.7.1」のように表示されればOKです。

jdkやtomcatなど、実行環境の自動化とgitの組み合わせをうまく利用することで、gitから取得したソースコードをvagrantにデプロイしてそのまま動かしてみるといった事に、応用していきたいと思います。
scalatraでAtmosphereのexampleを動かしたかった...

## 環境構築
 - JDKインストール
 - giter8インストール
 
参考:[PHPerだが、Scalaのフレームワーク「Scalatra」を使ってみる](http://qiita.com/suin/items/d8ec606f18e74044e5e8)

## 新規プロジェクト作成

`$ g8 scalatra/scalatra-sbt`

色々聞かれるがとりあえず全て空Enter

## 起動ポートを3000に変更

```diff:project/build.scala
 project/build.scala | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/project/build.scala b/project/build.scala
index 01af59d..0e8a0c9 100644
--- a/project/build.scala
+++ b/project/build.scala
@@ -4,6 +4,8 @@ import org.scalatra.sbt._
 import org.scalatra.sbt.PluginKeys._
 import com.mojolly.scalate.ScalatePlugin._
 import ScalateKeys._
+import com.earldouglas.xsbtwebplugin.PluginKeys._
+import com.earldouglas.xsbtwebplugin.WebPlugin._
 
 object MyScalatraWebAppBuild extends Build {
   val Organization = "com.example"
@@ -16,6 +18,7 @@ object MyScalatraWebAppBuild extends Build {
     "my-scalatra-web-app",
     file("."),
     settings = ScalatraPlugin.scalatraWithJRebel ++ scalateSettings ++ Seq(
+      port in container.Configuration := 3000,
       organization := Organization,
       name := Name,
       version := Version,
-- 
1.7.11.1
```
参考:[scalatra のポート番号を変更する](http://qiita.com/nabezokodaikon/items/c16cfa1a9bb74d8ad0cc)

## Atmosphere

http://www.scalatra.org/2.2/guides/async/atmosphere.html

ここに載っている通り `project/build.scala` にDependencyを追加。
`MyScalatraServlet.scala`を書き換える。

```
$ ./sbt
> container:start
```

```
[info] Compiling 1 Scala source to /home/masa/my-scalatra-web-app/target/scala-2.11/classes...
[error] /home/masa/my-scalatra-web-app/src/main/scala/com/example/app/MyScalatraServlet.scala:14: class MyScalatraServlet needs to be abstract, since method jsonFormats in trait JValueResult of type => org.json4s.Formats is not defined
[error] class MyScalatraServlet extends MyScalatraWebAppStack 
[error]       ^
[error] one error found
[error] (compile:compile) Compilation failed
[error] Total time: 8 s, completed 2014/07/30 1:00:23
```

なんかエラーが出た！
class内に下記1行を追加すると解決するっぽい。

```scala:MyScalatraServlet.scala
+  implicit protected val jsonFormats: Formats = DefaultFormats
```

ここまでの過程は下記リポジトリに置いてあります。
https://github.com/letsspeak/my-scalatra-web-app/

## よく見たらexampleの正規品があった

[GitHub scalatra-atmosphere-example](https://github.com/scalatra/scalatra-website-examples/tree/master/2.2/async/scalatra-atmosphere-example)

```bash
git clone git@github.com/scalatra/scalatra-website-examples
```

上記と同様に起動ポートを3000に変更して...`container:start`

![スクリーンショット 2014-07-30 1.27.39.png](https://qiita-image-store.s3.amazonaws.com/0/36244/9f8ba1d8-d467-9b1e-5f04-1b2f433815ea.png)

なんか動いた！！
ちなみにApacheを噛ませるとやっぱりWebsocketのエラーが出る。

```
01:30:08.269 [qtp261964679-39] ERROR o.a.cpr.AsynchronousProcessor - Invalid request state. Websocket protocol not supported
```

## おまけ

### Apacheのリバースプロキシの設定

```.conf:/etc/httpd/conf/httpd.conf
<VirtualHost *:80>
    ServerName yourdomain.com
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>
```

### Vim用の設定ファイル

https://github.com/scala/scala-dist/tree/master/tool-support/src/vim
Google Nexus シリーズのシステムフォントを Noto Sans Japanese にする

[NotoSansCJK]:http://www.google.com/get/noto/#/family/noto-sans-jpan
先日、GoogleがAdobeと共同開発でオープンソースなフォント、[Noto Sans CJK][NotoSansCJK]をリリースしました。
Google Nexus シリーズで、このフォントをシステムフォントとして使う方法を記録しておきます。

##前提条件
* Google Nexus シリーズでの設定方法(Nexus 7(2013) と Nexus 4 で確認)。他のAndroid端末で流用できるかは分かりません。
* システム領域を変更するので端末がroot化されている必要があります。
* お約束通り、無保証。端末が文鎮化しても知りません。

##フォントを設置する
[Noto Sans Japanese][NotoSansCJK]からフォントをダウンロードしてきます。ここでは、

* NotoSansJP-Regular.otf(通常用)
* NotoSansJP-Bold.otf(太字用)

を使用するので、これら2つのフォントをGoogle Nexus端末の /system/fonts ディレクトリに設置します（別に7ウェイト全部置いておいても構わない）。
**設置したファイルのパーミッションを644(-rw-r--r--)にします。**

※追記
通常用・太字用という区別は無いのかもしれません。
使用するファイルは1つのみで、太字などはそれを元に作成するみたいです。

##フォント設定ファイルの書き換え
フォント設定ファイル /system/etc/fallback_fonts.xml の、日本語フォント指定部分を書き換えます。

```text:/system/etc/fallback_fonts.xml
    <family>
        <fileset>
            <file lang="ja">MTLmr3m.ttf</file>
        </fileset>
    </family>
```

上記のMTLmr3m.ttf(モトヤフォント)の指定部分を、以下のようにNoto Sans Japaneseを指定するように書き換えます。
ちなみに、この指定部分のすぐ上にあるDroidSansFallback.ttfの設定より上に記述するように解説しているサイトがありますが、特に記述順は変えなくても良いようです。

```text:/system/etc/fallback_fonts.xml
    <family>
        <fileset>
            <file lang="ja">NotoSansJP-Regular.otf</file>
            <file lang="ja">NotoSansJP-Bold.otf</file>
        </fileset>
    </family>
```

**fallback_fonts.xmlのパーミッションを644(-rw-r--r--)にします。**

※追記
前述の追記のとおり太字用の指定などは無いようなので、NotoSansJP-Regular.otfのみの指定でよさそうです。

##パーミッションに注意
太字で注記しましたが、**ファイルのパーミッションが644(-rx-r--r--)でなければならない**事に注意する必要があります。

上の手順を試すときにfallback_fonts.xmlを一旦Dropboxにあげて編集して書き戻す、という事をやっていたのですが、書き戻した時にパーミッションが660(-rw-rw----)になっており、再起動すると日本語のフォントが表示されないという事態に陥りました。なんとかアルファベットで表示される部分だけをたよりに復旧できましたが、最初は上手くいかない原因がわからず悩みました。

##再起動
フォントの設置と、設定ファイルの書き換えが済んだら端末を再起動すれば、システムフォントがNoto Sans Japaneseになります。

##追記 源真ゴシックPを使用する
[Noto Sans Japanese][NotoSansCJK]はプロポーショナルフォントなのですが、幅が変わるのはアルファベットと記号のみで、ひらがなやカタカナは等幅になるため、日本語の文章がやや間延びした表示になります。
[源真ゴシック](http://jikasei.me/font/genshin/)は、[Noto Sans Japanese][NotoSansCJK]を元に色々な調整が施されたフォントファミリーで、ひらがなやカタカナもプロポーショナルフォントに対応させた「源真ゴシックP」が用意されています。幅の狭いひらがなやカタカナの文字が詰めて表示されるので、より自然な表示をすることができます。
上述の NotoSansJP-Regular.otf を GenShinGothic-P-Regular.ttf あたりに置き換えることで、システムフォントに源真ゴシックPを使用することが可能です。
CoffeeFormation 1.0.1 update


地味だけど、結構便利なアップデートが行われたので、ご紹介します。
`npm install -g csfn` で更新されると思います。

## Include機能
`usage: csfn [-I dir] hoge.coffee [ puge.coffee ... ] > hogepuge.template`

テンプレート間で共通で使うような定義を切り出して、参照する機能となります。
インクルードパスを指定すると、その配下のcoffeeスクリプトをテンプレートの前に読みます。

### サンプル
各リージョンのAmazon Linux AMIのマッピングです。

```coffee-script
amznAmiMapping=
  "eu-west-1":
    pv: "ami-2918e35e"
    hvm: "ami-4b18e33c"
  "sa-east-1":
    pv: "ami-215dff3c"
    hvm: "ami-635dff7e"
  "us-east-1":
    pv: "ami-fb8e9292"
    hvm: "ami-978d91fe"
  "ap-northeast-1":
    pv: "ami-c9562fc8"
    hvm: "ami-bb562fba"
  "us-west-2":
    pv: "ami-043a5034"
    hvm: "ami-383a5008"
  "us-west-1":
    pv: "ami-7aba833f"
    hvm: "ami-5aba831f"
  "ap-southeast-1":
    pv: "ami-b40d5ee6"
    hvm: "ami-860d5ed4"
  "ap-southeast-2":
    pv: "ami-3b4bd301"
    hvm: "ami-cf4ad2f5"
```

これをテンプレートで参照するには、先頭行のように代入します。

```coffee-script
Mappings.amis=amznAmiMapping # refer pre-defined object in include/*.coffee 

Resources.small=
  Type: "AWS::EC2::Instance"
  Properties:
    ImageId: "Fn::FindInMap":["amis",{Ref:"AWS::Region"},"pv"]
    InstanceType: "m1.small"

Resources.medium=
  Type: "AWS::EC2::Instance"
  Properties:
    ImageId: "Fn::FindInMap":["amis",{Ref:"AWS::Region"},"hvm"]
    InstanceType: "m3.medium"

```

実際にテンプレート作成、スタック作成を行ってみます。

```bash
~/work/csfn/samples$ tree
.
├── bucket.coffee
├── ec2.coffee
├── include
│   └── amaznAmiMapping.coffee
└── rds.coffee

1 directory, 4 files
~/work/csfn/samples$ csfn -I include ec2.coffee
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Mappings": {
  :
}
~/work/csfn/samples$ aws cloudformation create-stack --stack-name ec2 --template-body "$(csfn -I include ec2.coffee)"
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:111111111111:stack/ec2/e4794e00-1738-11e4-89a4-5088487ec896"
}
```

includeしてもテンプレート内で参照(代入)しなければ、JSONとしては出力されません。

```
~/work/csfn/samples$ csfn bucket.coffee
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "my-special-bucket"
      }
    }
  }
}
~/work/csfn/samples$ csfn -I include bucket.coffee
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "Bucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "my-special-bucket"
      }
    }
  }
}
```

# 謝辞
ナイスな機能実装ありがとうございました＞sumikawa-san
Android 4.4 KitKat で broadcast MEDIA_MOUNTED が Permission Denial になる対策



Android 4.3迄は、SDカードに保存した画像を削除した後、Broadcast を送信して MediaScan を呼ぶことでサムネイルも削除されます。こんな感じです。

```
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, uriToSD));
```

もともと筋が悪い方法な事もあるからか、Android 4.4からはこんなエラーが出て使えません。

```
Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED
```

場当たり的な策として、Intent.ACTION_MEDIA_SCANNER_SCAN_FILE を使う事で取り敢えずは回避できます。

```
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uriToSD));
```

※本来は[MediaScannerConnection](http://developer.android.com/intl/ja/reference/android/media/MediaScannerConnection.html)を使うのが筋の様です。



## 参考URL

[Permission Denial: not allowed to send broadcast in android - Stack Overflow](http://stackoverflow.com/questions/21469431/permission-denial-not-allowed-to-send-broadcast-in-android)

[java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED on KitKat only - Stack Overflow](http://stackoverflow.com/questions/24072489/java-lang-securityexception-permission-denial-not-allowed-to-send-broadcast-an)

[Android KitKat Permission Denial Error | SHAYDES.DSGN Blog](http://blog.shaydesdsgn.com/android-kitkat-permission-denial-error/)

[Android: Refreshing the Gallery after saving new images - Stack Overflow](http://stackoverflow.com/questions/18624235/android-refreshing-the-gallery-after-saving-new-images)
Route53 + S3 を使った任意の URL へのリダイレクト

やりたいこと
==========

* AWSのサービスだけを使って、ある URL http://my.domain/ へのアクセスを、別の URL http://aaa.bbb.ccc/subdir1/subdir.html へ転送したい

問題
====
* Route 53 の CNAME は subdir1/subdir.htmlへの転送ができない。

どうやるか
=========

S3
--
1. S3 に my.domain という名前のバケットを作成
2. Properties から Static Website Hosting
3. Redirect all requests to another host name をクリック
4. Redirect all requests to に　aaa.bbb.ccc/subdir1/subdir2.html
5. Endpoint: my.domain.s3????.amazonaws.com をメモ

Route 53
--------
1. Create Hosted Zone で my.domain を設定 (DNSの設定などは他ページ参照)
2. my.domain への CNAME 設定を上の5に設定

なぜうまくいくのか
================
これで、http://my.domain へのアクセスが Route 53 を経由して
my.domain.s3???.amazonaws.com に転送されて、
S3 の転送サービスで http://aaa.bbb.ccc/subdir1/subdir2.html に
転送される。
Salesforceのヘルプテキストアイコンを再現する

![スクリーンショット 2014-07-29 23.44.58.png](https://qiita-image-store.s3.amazonaws.com/0/8407/d22b63d1-5f86-0819-2272-8dce6d3c94b9.png)

Visualforceでヘルプテキストアイコンを表示するときはpageBlockSectionItemのhelpTextを使って表示できますが、showHeader=falseが指定されたページでは表示されません。

showHeader="false"のページで表示したいときは次の方法でヘルプテキストアイコンを再現できます。

```
<apex:page showHeader="false">
  <style>
  .vfHelpText img {
    margin-right: 2px;
  }
  .vfHelpText a            {
    position:relative;
  }
  .vfHelpText a span       {
    display: none;
  }
  .vfHelpText a:hover span {
    display: block;
    position:absolute;
    top:1.5em;
    left:1.5em;
    padding:5px 5px;
    z-index:100;
    border:1px solid orange;
    background-color:#FEFDB9;
    color:black;
    font-size: 10px;
    font-weight:normal;
  }
  </style>
  <apex:form >
    <apex:pageBlock >
        <apex:pageBlockSection >
          <apex:pageBlockSectionItem >
            <apex:outputPanel >
              <apex:outputLabel value="ラベル" for="inputKokyakuMei" />
              <span class="helpButton" onfocus="this.className='helpButtonOn';" onmouseout="this.className='helpButton';" onmouseover="this.className='helpButtonOn';">
                <span class="vfHelpText">
                  <apex:outputLink value="javascript&colon;return false;">
                    <img src="/s.gif" alt="" class="helpOrb" />
                    <span>
                      <apex:outputText value="ヘルプメッセージです。" />
                    </span>
                  </apex:outputLink>
                </span>
              </span>
            </apex:outputPanel>
            <input type="text" />
          </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
    </apex:pageBlock>
  </apex:form>
</apex:page>
```

ちなみにこの方法はshowHeader="true"のページでは正常に表示されません。
showHeader="true"のページでpanelGridなどと一緒に使いたい場合は次のような書き方で対応できます。

```
<apex:page showHeader="true">
  <apex:form >
    <apex:pageBlock >
      <apex:panelGrid columns="3">
        <apex:outputLabel value="ラベル" styleClass="labelCol" style="padding-right: 0;" />
          <apex:outputPanel >
            <span class="helpButton" id="demo-_help">
              <img src="/s.gif" class="helpOrb"/>
              <script type="text/javascript">
                sfdcPage.setHelp('demo','ヘルプメッセージです。');
              </script>
            </span>
          </apex:outputPanel>
          <input type="text" />
      </apex:panelGrid>
    </apex:pageBlock>
  </apex:form>
</apex:page>
```

##参考
Urgent help - inlineHelp not displaying in Visualforce page, could be silly mistake
https://developer.salesforce.com/forums?id=906F000000096ruIAA
Swiftの関数の引数は、常に一つ

だとしたら、Swiftではカリー化は不要ということになってしまう。

> すなわち、ざっくり言うとカリー化とは*複数の引数を1つに減らす*ことを指します - [Swiftで関数のカリー化(currying)入門]

[Swiftで関数のカリー化(currying)入門]: http://qiita.com/Alex_23drum/items/7a9b0ecd0800483b5ddf

Swiftの関数は、つねに一つの値を受け取り、一つの値を返すのだから。

以下のコードを動かしてみれば、それがわかる。

````swift
func call<A,R>(f:A->R, a:A)->R {
    return f(a)
}
func id(i:Int)->Int { 
    return i
}
func add(x:Int, y:Int)->Int {
   return x + y
}
call(id, 42)       // 42
call(add, (21,21)) // 42
````

上記の`call()`は、「『型Aの値を一つだけ取って型Rの値を返す関数』と『型Aの値』を取って『型Rの値』を返す関数」なはずなのに、「`Int`と`Int`を取って`Int`を返す」関数も受け取っている。

なぜか?

「`Int`と`Int`を取って`Int`を返す」関数なんて、はじめからどこにもなかったからだ。

あったのは、

「`(Int, Int)`を受け取って`Int`を返す関数」

だったのだ。

全てのSwiftの関数は、[tuple]を一つだけ受け取る関数なのである。

[tuple]: https://en.wikipedia.org/wiki/Tuple

Haskellの言葉で言えば、上記の`add()`は

````Haskell
add:: Integer -> Integer -> Integer
````

ではなく

````Haskell
add::  (Integer, Integer) -> Integer
````

ということになる。

`add()`の本当の姿は、

````swift
func add(arg:(Int,Int))->Int {
   let (x, y) = arg
   return x + y
}
````

だったわけだ。

ちなみに`(Int, Int)`は、`Int`とは独立した固有の型である。そして`Int`は`(Int)`でもある。ので要素数ゼロのtupleである`()`を除く全ての値は、必ず`.0`というプロパティが存在する。

````swift
let n = 0
n // 0
n.0 // 0
n.0.0 // 0
n.0.0.0 // 0
// ちなみに0.0.0... は syntax error
// さもないと 0.0がDouble(0.0)なのか(0).0なのか判別不能になる
````

さらに

````swift
func hello(){ println("hi") }
````

は、`()`を受け取って`()`を返す関数であり、

````swift
call(hello, ())
````

は期待通り動く。

[The Swift Programming Language]には

[The Swift Programming Language]: https://itunes.apple.com/jp/book/using-swift-cocoa-objective/id888894773?l=en&mt=11

> Tuples are particularly useful as the return values of functions

なんてのんきに書いてあるが、便利どころかSwiftでは全ての値がtupleなのだ。通常の値は要素数1のtupleで、「値がない値」すら、要素数0のtuple。

このことを知らなくても、普通の関数やclassやstructやenumは書けるのけど、上記のようにジェネリクスを使う場合、このことは必須の知識となる。

大事なことなのにアマツバメ本にきちんと明記していないので、記事にした次第。

(Dan, Swift, Newbie)
シェルの備忘録

## コマンド

#### シンボリックリンクの作成

`ln -s link/to/path symbol/path`

#### wgetでDL先のディレクトリを指定する

`wget -P path/to/target http://url.to/file`

#### curlでPOSTする

`curl -F "name1=value1" -F "name2=value2" http://yourdomain/execute.script`

参考:[curlコマンドから HTTP POST する方法](http://qiita.com/letsspeak/items/8c7266742371699ab45e)

## カーソル移動

|キー入力 | 動作 |
|--------|------|
|Ctrl + a|入力行頭にカーソル移動|
|Ctrl + e|入力行末にカーソル移動|
|Ctrl + u|全消去 (bash:カーソルより行頭を消去)|
|Ctrl + k|カーソルより行末を削除|

## TODO

まだまだあった気がするので随時更新予定。
Unityを複数起動させる

Macではターミナルとかで起動させれば複数起動できます。
% open -n /Applications/Unity/Unity.app

WindowsではタスクバーにでているUnityアイコンの右クリックし、AltをおしながらUnity.exeをクリックする。

但し、既に開いているプロジェクトをもう一個開くことはできないのであしからず。
プロジェクトをコピーして開くしかない模様。

---
蛇足ですが複数のプロジェクトで同時作業したかったのですが
monodevelopで複数ソリューションを開くのがよくわからなかったので、Unityを2つインストールしてそれぞれで別プロジェクトを開いてmonodevelopをそれぞれ開くといけました。
そのかわりUnityが2つ、monodevelopが2つ起動されます。。。
INSTALL_FAILED_UID_CHANGED の対処法

いつもと違うPCでビルドしたAPKを、
adbからAndroid端末にインストールしようとしたところ、

    Waiting for device.
    Target device: htc-htl22-*******
    Uploading file
	local path: *********/app-debug.apk
	remote path: /data/local/tmp/**パッケージ名**
    Installing **パッケージ名**
    DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/**パッケージ名**"
    pkg: /data/local/tmp/**パッケージ名**
    Failure [INSTALL_FAILED_UID_CHANGED]

みたいなエラーが出てインストールに失敗してしまいました。

ぐぐってみると解決方法として

 * Root取ってAPKの残骸を消せ
 * 端末初期化しろ

みたいな普段使いの端末ではあまりやりたくない解決策しか出てきませんでした。

APKをアンインストールしてもデータ領域には残骸が残るらしく、
DebugとかでUIDが異なるAPKを入れようとすると、
この残骸と衝突してINSTALL_FAILED_UID_CHANGEDというエラーが出るそうです。

残骸を消すにはルート取ったり初期化が必要なわけで…。  
かなり手詰まり感がすごいのですが、楽な回避方法を思いつきました。

## 解決方法

その解決方法は「Package name」を変えることです。

データ領域にパッケージ名でファイルが作られるので、
パッケージ名さえ変えてしまえば衝突が回避できます。

AndroidStudioで開発していればGradleをいじるだけで
簡単にパッケージ名を変えられるのでこれを使わない手はありません。  
(本番のパッケージ名はもとの名前に戻す、なんてことも可能です。)

## Gradleでパッケージ名を変える

    apply plugin: 'android'

    android {
        compileSdkVersion 19
        buildToolsVersion "19.1.0"

        defaultConfig {
            minSdkVersion 15
            targetSdkVersion 19
            versionCode 1
            versionName "1.0"
            // これを追記
            applicationId "新しいパッケージ名"
        }
        buildTypes {
　　　　　　　……

これでビルドして端末にインストールしたらうまくいきました。
RailsCasts History

個人的な視聴履歴です

# DONE

http://railscasts.com/episodes/206-action-mailer-in-rails-3
http://railscasts.com/episodes/243-beanstalkd-and-stalker
http://railscasts.com/episodes/267-coffeescript-basics
http://railscasts.com/episodes/270-authentication-in-rails-3-1
http://railscasts.com/episodes/271-resque
http://railscasts.com/episodes/274-remember-me-reset-password
http://railscasts.com/episodes/320-jbuilder
http://railscasts.com/episodes/322-rabl
http://railscasts.com/episodes/354-squeel?view=asciicast
http://railscasts.com/episodes/358-brakeman
http://railscasts.com/episodes/366-sidekiq
http://railscasts.com/episodes/382-tagging
http://railscasts.com/episodes/387-cache-digests
http://railscasts.com/episodes/393-guest-user-record
http://railscasts.com/episodes/402-better-errors-railspanel
http://railscasts.com/episodes/409-active-model-serializers

# TODO
## ASCII

## Video
http://railscasts.com/episodes/37-simple-search-form
http://railscasts.com/episodes/77-destroy-without-javascript
http://railscasts.com/episodes/120-thinking-sphinx

## ASCII(Pro)

http://railscasts.com/episodes/77-destroy-without-javascript-revised
http://railscasts.com/episodes/87-generating-rss-feeds-revised
http://railscasts.com/episodes/301-extracting-a-ruby-gem
http://railscasts.com/episodes/375-monit

## not RailsCasts

http://www.fabricationgem.org/
Jadeifyを使ってみた



https://github.com/domenic/jadeify


個人的にもう生のHTMLを書く事が無くて、諸々条件が許す限りJadeを使用している。
Jadeifyを使用すればjadeファイルを、htmlに変換してテンプレートとしてbrowserifyのビルドで生成するjs内に展開してくれるようなので、テストを読みつつ試してみる。



##インストール

今回はgruntから使用した。
grunt-browserifyとかJade諸々が事前に入ってるとして。

```
npm install jadeify
```

##設定

browserifyのタスクの記述のところで、optionsでtransformのoptionsに'jadeify'を追記する

```Javascript:Grunt.js
//該当部分抜粋
      browserify: {
        app: {
          files: {
            'app/public/js/app.js': ["frontend/*.js", "frontend/*.coffee"]
          },
          options: {
            require: true,
            transform: ['coffeeify', 'jadeify']//<-ココ
          }
        }
      }
```

##使う
underscoreのテンプレートの使い方に似ている。
jadeファイルをrequireするとコンパイル済みのテンプレート関数を返してくるので、
jade内の変数名をキーに、出力したい内容を値にしたオブジェクトをパラメータにして実行する。


```Javascript:main.js
var template = require('./test.jade');
var result = template({foo:"This is a TEST!!!"});
console.log(result);
```

```jade:test.jade
p= foo
```

browserifyのビルドが成功して、ブラウザで見るとコンソールに

```
<p>This is a TEST!!!</p> 
```

と出る。


テストはシンプルな例しかなかったけど、関数を渡したり、通常のJadeと同様for文や#{}の変数展開もできた。

```Javascript:main.js

var template = require('./templates/entries.jade');

var entries = [
  {
    id: 1,
    title: function() {
      return "works";
    },
    link: "http://examples.co.jp/works/"
  }, {
    id: 2,
    title: function() {
      return "people";
    },
    link: "http://examples.co.jp/people/"
  }, {
    id: 3,
    title: function() {
      return "careers";
    },
    link: "http://examples.co.jp/careers/"
  }
];

var result = template({
  entries: entries
});

console.log(result);

```

```Jade:templates/entries.jade
for entry, index in entries
	tr
		td= entry.id
		td= entry.title()
		td
			a(href="#{entry.link}", target="_blank") #{entry.link}
```
を同じくビルドすると

```
<tr>
  <td>1</td>
  <td>works</td>
  <td>
    <a href="http://examples.co.jp/works/" target="_blank">http://examples.co.jp/works/</a>
  </td>
</tr>
<tr>
  <td>2</td>
  <td>people</td>
  <td>
    <a href="http://examples.co.jp/people/" target="_blank">http://examples.co.jp/people/</a>
  </td>
</tr>
<tr>
  <td>3</td>
  <td>careers</td>
  <td>
    <a href="http://examples.co.jp/careers/" target="_blank">http://examples.co.jp/careers/</a>
  </td>
</tr> 
```
という結果が得られた。

##追記
***2014/7/30***
コメントにてご指摘いただきました。
jadeifyはbrowserifyのビルド後に出力するjsにてjavascript1.8.5以降のメソッドを使っているので、そのメソッドに対応していないレガシーなブラウザ(IE8等)ではこのまま実行してもエラーになります。
ご注意ください。
オブジェクト指向でゲームを作るのをやめよう


若干釣り気味です、すいません！！！！！！というかまさかり期待してます、ください。

題の通りです。オブジェクト指向パラダイムはゲームプログラミングと相性が悪いです。

どうもプロのゲームプログラマには常識っぽいんですが、ホビーゲームプログラマにはあまり浸透してないみたいです。（調べてようやく認識しました……）


##ある日曜プログラマの憂鬱
ある日突然モグラたたきが作りたくなりました。なったんです！！
さて、モグラ叩きに登場するオブジェクトを考えます。

モグラが当然いりますね。
というわけでこんな感じに設計しました。

![img1.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/3301e1ce-c442-55fa-cbfb-3b0c4c58e1b8.jpeg "img1.jpg")



詳細な実装をつめていって、とうとうプロトタイプが完成しました！！
やった！！…と言いたいところなんですが、なんだか物足りないのです。

そこでかんがえました、叩いたらダメなウサギを作ろうと。
出たり引っ込んだりするのは同じなので、モグラを継承することにしました（説明のためわざとです、突っ込みたい気持ちは抑えて！！）

![img2.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/abd328a0-ecca-0973-6fe5-2d24c1077d68.jpeg "img2.jpg")


そのあとひたすらコーディングして完成！！しましたが、完成したらしたで、また新たなゲーム要素を思いつきました。おばけです、穴からふわーりと飛んでいく。面白そうですね、面白そうです。

![img3.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/57b4007b-ab4b-36fd-4d16-84a657dfed8a.jpeg "img3.jpg")


さて、これはウサギともモグラとも動きが違います。よって動きは共有できないのです。そこではたと気がつきました（やっとです）、共通コードをベースクラスにすればよいと！！

早速この考えを元に設計し直します……

![img4.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/dc88c83b-d63b-ffd0-d367-2f829ed92e40.jpeg "img4.jpg")

……あれ？これだと出たり引っ込んだりするコードが共有できてませんね？
ならば、と再びペンを走らせます……

![img5.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/f4ca111b-9cc1-25f2-d8c6-35cf212f3495.jpeg "img5.jpg")


……今度はおばけに不要なコードがベースクラスにくっついちゃいました。はたしでどっちがいいのやら！？


##銀の弾丸は無い

データベースとオブジェクト指向の間には溝があります。インピーダンスミスマッチと呼ばれていますが、ゲームを構築する際にも、インピーダンスミスマッチが生じています。

ゲーム世界をプログラムコードに落とす上で、継承という仕組みは貧弱すぎるのです。

これはかなり早い段階で認識されていたようで、いくつか解決策が提示されています。

##Entity Component System
継承がだめならコンポジションです。オブジェクトの粒度を非常に小さくして、それを集めれば良いのです。UnityのMonoBehaviorはまさにこの構造になります。

欠点：
依存関係を粗にしようとすると、オブジェクト間通信のコストが高くつきます。
また依然としてオブジェクト指向なため、ハードウェアと相性が悪いです。
![img6.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/c4e3c324-4a59-9ee2-8d95-469d01f2457b.jpeg "img6.jpg")


##Data Oriented Programming
オブジェクト指向では、データを外から守るオブジェクトという単位でプログラムを構成します。
ですが、DOPではデータを中心に考えます。プログラムを、データを変形するライン工場と見立てるのです。
ECS実装のもう一つのアプローチでもあります。
このプログラミングアプローチは、現代的ハードウェアと相性が良いです。（並列化しやすい、キャッシュに載る）

欠点：
発想の転換が求められます。
![img7.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/687ffa4c-b8c7-fb6d-fabd-3d3fb39de53e.jpeg "img7.jpg")


##Functional Reactive Programming
DOPをもうちょっと眺めてください。

はい、工場、という言葉、Haskellの入門書等で見ますよね。

データを加工する工場、とはすなわち、関数に他なりません。
Functionalというと副作用がどうのこうのが気になりますよね。
ゲームというのは副作用の塊です。相性悪いなんてものじゃなさそうですが……

大丈夫です。
コンピュータは離散で時間を扱います。0msの世界を16ms後の世界に変換する関数、それこそがゲームロジックです。これを連続的に行えば、ゲームは表現できます。

これを関数型の世界で上手く表現する手法、それがFRPになります。
Elmという言語がFRPにフォーカスした言語らしいので、誰かレポートしてください！

欠点：
Haskell……うっ、頭が……

![img8.jpg](https://qiita-image-store.s3.amazonaws.com/0/50291/bb99ceea-735b-2d2c-a99b-3edbae5cf807.jpeg "img8.jpg")


##結論
趣味レベルの規模だとどうでもいい気がします。
コード把握してる限りは何使っても同じですし……

とこの記事の意義をぶちこわして終了です。またどこかで！
GiLab CI | GiLab CI で branch ごとに build 内容を切り替える

# GiLab CI | GiLab CI で branch ごとに build 内容を切り替える

## 概要
GiLab CI で branch ごとに build 内容を切り替える方法について。

GitLab CI は *push* に対して常に *build script* を実行します。
 branch ごとに build 内容を切り替えたい場合は、 *build script* 内で
$CI_BUILD_REF_NAME 環境変数を利用してブランチ名を参照し、処理を分岐をさせます。

## サンプル

~~~bash:build-script
if [ $CI_BUILD_REF_NAME = "master" ] ; then
  echo "build master"
  git submodule update --init
  ls -la
  bundle install
  rspec
  exit 0
elif [[ "$CI_BUILD_REF_NAME" =~ ^tp_.*$ ]] ; then
  echo "build topic branch"
  git submodule update --init
  ls -la
  bundle install
  rspec
  exit 0
else
  echo "not target branch"
  exit 0
fi
~~~

## デプロイ試行
### master ブランチを push

GitLab CI のデプロイ ログを確認

~~~
# :
# 略
# :
echo "build master"
build master
# :
# 略
# :
8 examples, 0 failures
exit 0
~~~

### tp_some_topic ブランチを push

GitLab CI のデプロイ ログを確認

~~~
# :
# 略
# :
echo "build topic branch"
build topic branch
# :
# 略
# :
8 examples, 0 failures
exit 0
~~~

### other ブランチを push

GitLab CI のデプロイ ログを確認

~~~
# :
# 略
# :
echo "not target branch"
not target branch
exit 0
~~~
GitLab CI | GitLab CI のビルドスクリプト内で使用可能な環境変数について

# GitLab CI | GitLab CI のビルドスクリプト内で使用可能な環境変数について

## 概要
GitLab CI のビルドスクリプト内で使用可能な環境変数について。

デフォルトでは、GitLab CIはすべてのPushに対してビルドスクリプトを実行します。
ケースに応じたビルドの実行をするにはビルドスクリプト内でブランチ名などを判別する必要があります。
その際に、GitLab CIが用意している環境変数を利用します。

## 一覧

|変数名|内容|
|:--|:--|
|$CI_SERVER|CIサーバーかどうか？|
|$CI_SERVER_NAME|CIサーバー名|
|$CI_SERVER_VERSION|CIサーバーのバージョン => nil|
|$CI_SERVER_REVISION|CIサーバーのリビジョン => nil|
|$CI_BUILD_REF|pushしたcommitのリビジョン番号（SHA-1）|
|$CI_BUILD_BEFORE_SHA|pushしたcommitの前のリビジョン番号（SHA-1）|
|$CI_BUILD_REF_NAME|pushしたブランチ名|
|$CI_BUILD_ID|ビルド番号|

## サンプル
Build Script に下記を設定。

branch 「hoge」 で git push を実行しました。

~~~bash
echo '@@@@@@@@@@@@@@@'
echo $CI_SERVER
echo $CI_SERVER_NAME
echo $CI_SERVER_VERSION
echo $CI_SERVER_REVISION
echo $CI_BUILD_REF
echo $CI_BUILD_BEFORE_SHA
echo $CI_BUILD_REF_NAME
echo $CI_BUILD_ID
echo '@@@@@@@@@@@@@@@'
~~~

出力メッセージは以下（GitLab CIのビルドログより）

~~~
echo '@@@@@@@@@@@@@@@'
@@@@@@@@@@@@@@@
echo $CI_SERVER
yes
echo $CI_SERVER_NAME
GitLab CI
echo $CI_SERVER_VERSION

echo $CI_SERVER_REVISION

echo $CI_BUILD_REF
ce3c575ec3243382d75c81597eae378ef306e0fc
echo $CI_BUILD_BEFORE_SHA
a59657194759ee67190d06eee2a1e5cf84ee986e
echo $CI_BUILD_REF_NAME
hoge
echo $CI_BUILD_ID
17
echo '@@@@@@@@@@@@@@@'
@@@@@@@@@@@@@@@
~~~

## GitLab CI Runner内のソースコードを確認

https://gitlab.com/gitlab-org/gitlab-ci-runner/blob/master/lib/build.rb

~~~ruby:build.rb
      @process.environment['CI_SERVER'] = 'yes'
      @process.environment['CI_SERVER_NAME'] = 'GitLab CI'
      @process.environment['CI_SERVER_VERSION'] = nil# GitlabCi::Version
      @process.environment['CI_SERVER_REVISION'] = nil# GitlabCi::Revision

      @process.environment['CI_BUILD_REF'] = @ref
      @process.environment['CI_BUILD_BEFORE_SHA'] = @before_sha
      @process.environment['CI_BUILD_REF_NAME'] = @ref_name
      @process.environment['CI_BUILD_ID'] = @id
~~~

CI_SERVER_VERSION, CI_SERVER_REVISIONは今のところ *nil* にしている模様。

## 参照
https://github.com/gitlabhq/gitlab-ci