OmniAICreator/Qiita-1.07M huggingface dataset:
gitで秘密の情報がコミットされないようにpre-commitでチェック

github.comのリポジトリに、秘密の情報をpushしてしまわないようにするため、git pre-commitを使ってコミットメッセージに特定キーワードが含まれる場合はコミットさせないようにした。

なお、以下は社内がGH:Eの環境で一方でgithub.comのpublicなリポジトリも普段使いする人向けに書いているので、GH:E使っておらずgithub.comでprivateなリポジトリを運用している人のケースではそのまま適用できないこと予めご了承ください。

### pre-commit

以下のファイルを`${my_repos}/.git/hooks/pre-commit`に置いて実行権限をつければよい。

```bash:pre-commit
#!/bin/sh

# This prevents pushing prohibited words e.g in-house information to
# github.com by mistake.
#
# Usage:
#
# Add words you do not want to publish to the internet as follow,
#   $ echo "secretword" >> ~/.git_prohibited_words
#
git remote -v | grep -E '^.+\s+(git@github.com:|https?://github.com/).+\(push\)$' >/dev/null
if [ $? -eq 0 ]; then
  if [ -e ~/.git_prohibited_words ]; then
    while read word; do
      # Skip comment or blank lines
      echo $word | grep ^# > /dev/null && continue
      echo $word | grep '^\s*$' > /dev/null && continue

      git diff --cached -U0 | grep -i "$word" > /dev/null
      if [ $? -eq 0 ]; then
        echo "Can't commit because of including the prohibited word '$word'" >&2
        exit 1
      fi
    done < ~/.git_prohibited_words
  fi
fi
```

秘密のキーワードは以下のように追加する。

```bash
$ echo 'secretword' >> ~/.git_prohibited_words
```

### 既存リポジトリ、新規リポジトリ

既存リポジトリ全部に配る必要があるのと、今後git initやgit cloneする場合にも適用したいので、[gitのhooksを管理する(自分用テンプレートを使う)](http://qiita.com/quattro_4/items/59fdf8b9aa9ef48ecbdf)の方法を参考にする。

### この方法のイケてない所

僕の場合、~/.git_prohibited_wordsにとりあえず社内のFQDNを入れてみたが、入れてはいけないワードを全部予め入れることが難しい。今後増えるかもしれないし、それを都度入れるのか?と言われると怪しいところである。。。またパスワード情報がコミットされないようにしたい!といった用途には向かいない。

完璧な対策とならないものの、多少なりともミス軽減にはなるので、ひとまずこれで運用してみる。

もっと良いやり方があれば教えていただきたい。
【脆弱性】Ghost対応

Ghost対応することまとめました

■概要
チェックスクリプトの実行準備（1〜5）
↓
glibcのアップデート（6）
↓
リブートしてチェック（7〜8）

■手順
1)チェックスクリプト中でcurlを使うのでインストールを確認
$ which curl
/usr/bin/curl (表示されることを確認

2)テストプログラムを実行するディレクトリを作り、移動する
$ mkdir ghost
$ cd ghost

3)Githubからテストプログラムをダウンロードする
$ wget https://raw.githubusercontent.com/mholzinger/CVE-2015-0235_GHOST/master/build.sh --no-check-certificate

4)プログラムの取得を確認し、実行権を与える
$ chmod a+x build.sh
$ ll
・・・
-rwxr-xr-x  1 root root  149 Jan 30 14:40 build.sh

5)プログラムを実行し、脆弱性の有無を確認する
$ ./build.sh
vulnerable (脆弱性がある時の実行結果
not vulnerable (脆弱性がない時の実行結果

6)glibcをアップデート
$ sudo yum clean all
$ sudo yum update glibc

7)リブート
$ reboot

8)再チェック
$ ./build.sh
not vulnerable

9)チェックスクリプトを削除
$ cd ~
$ ls -la ghost
drwxr-xr-x   2 root root 4.0K Jan 30 14:40 ghost
$ rm -rf ghost

■ソース元
http://www.agilegroup.co.jp/technote/ghost-update.html
http://blog.goo.ne.jp/takuminews/e/4ccb2b5aeab0cb09c37a9af96ff77c9a
Responsesでrequestsモジュール経由のHTTPリクエストをモックする


[Reponses](https://github.com/dropbox/responses)はHTTP通信を実施する[requestsモジュール](https://pypi.python.org/pypi/requests/)をモックするライブラリ。信頼できそうなDropbox製。ライセンスはAPL 2.0。

```python
class APITestCase(TestCase):
    @responses.activate
    def test_api(self):
        import api

        # setup
        responses.add(
            responses.GET,
            'https://example.com/api/v3/users',
            status=200,
            body="[{'user': {'id': 1, 'username': 'test'}}]",
            content_type="application/json",
        )

        # test
        api.get_users()
        assert responses.calls[0].request.method == 'GET'
        assert responses.calls[0].request.url == 'https://example.com/api/v3/users'
```

似たようなので[httpretty](https://github.com/gabrielfalcao/HTTPretty)というのもあるんですが、Responsesの方が自分の好みにあってました。しばらく試してみようと思います。

※Responsesのインターフェースは`httpretty`の影響を受けていると思います。
subversionレポジトリをgitレポジトリに変換

[前提] : git-svn パッケージがインストールされているマシン

<dl>
  <dt>svnレポジトリ</dt>
  <dd>svn://host/path/repository</dd>
  <dt>作成したいgitレポジトリのpath</dt>
  <dd>/path/to/new/git/</dd>
</dl>

1 . subversionのログを確認

```
$ svn log svn://host/path/repository/ | head 20
------------------------------------------------------------------------
r135 | gigatune | 2013-02-11 21:02:46 +0900 (火, 11  2月 2013) | 1 line

コミットログ
(略)
------------------------------------------------------------------------
```

2 . 変換

最新のリビジョン番号を指定して変換する(上の例では135なので、その番号を指定している)

```
git svn clone -r 1:135 svn://host/path/repository/ /path/to/new/git
```
ugui EventSystemsでイベント取得　メモ

PointerClickイベントが欲しければ、
IPointerClickHandlerインタフェースをMonoBehaviourの横に追加

public class クラス名 : MonoBehaviour, IPointerClickHandler
{

}

IPointerClickHandlerの定義を見ると
public interface IPointerClickHandler : IEventSystemHandler
{
　　void OnPointerClick(PointerEventData eventData);
}

となっているので

自分のソースに以下を追加するとイベントが取れる
public void OnPointerClick(PointerEventData eventData)
{
}
ブラウザ環境でcommonjs/requireを可能にするrequire1k


Echo.jsで話題になってたので試してみた。

```
$ wget https://raw.githubusercontent.com/Stuk/require1k/master/require1k.min.js
```

index.htmlで読み込む

```html
<html>
  <head>
    <title>try require1k</title>
    <script src="require1k.min.js" data-main="./main"></script>
  </head>
  <body>
  </body>
</html>
```

data-mainで指定したパスがエントリポイントになる。


main.jsではlodashは読み込んでみた。
どうやら、外部モジュールを呼び出す際にpackage.jsonのmainを見てないっぽくて、直接指定しなければならなかった。

```javascript
var _ = require('lodash/index');
var marked = require('marked/index');
console.log(marked('# hello'));
```

パッケージがさらに入れ子になってるようなライブラリ(react)は呼び出せない模様。

サブセットなので `browserify main.js` で連結してもちゃんと動く。


どうせ環境作るなら非力だけど、mainまでサポートしたら開発環境用に使えなくもない気がした。

サンプルプロジェクト
https://github.com/mizchi-sandbox/try-require1k

以上です。
GitHubのpjaxによる画面遷移をユーザースクリプトなどから検知する

pjaxによる画面遷移ではユーザースクリプトが新しく呼び出されない。ここでは、GitHubでpjaxによる画面遷移が発生したことをユーザースクリプト側で検知する方法をいくつか紹介する。Chrome Extensionなどのブラウザ拡張を書くときにも参考になるかもしれない。

## URLをポーリングする

`setInterval`などで定期的にURLを確認することでpjaxによる画面遷移が検知できる。

URLが変更されたときに発生するイベントはないようだ[^urlevents]。

[^urlevents]: `history.popState()`が実行されたときに発生するPopStateEvent、hash fragmentが変更されたときに発生するHashChangeEventなどはある。

## MutationObserverでDOMの変更を検知する

おそらく一番まっとうな方法。かつてはDOMの変更検知にはDOMNodeInsertedをはじめとするmutation eventsが使われていたが、現在は非推奨になっていて、代わりにMutationObserverが提供されている。

### 使用例など

- [github-linker/injection](https://github.com/github-linker/injection): [GitHub Linker](https://chrome.google.com/webstore/detail/github-linker/jlmafbaeoofdegohdhinkhilhclaklkp)のコンポーネントの一つ。npmとbowerのパッケージとして提供されている。
- [app.js · kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github](https://github.com/kyanny/chrome-ext-wip-pull-request-unhighlighter-for-github/blob/134fea5c17ba261c5354ec86c50108261a77ca7c/app.js#L29-L47)（Chrome Extension）
  - [pjax を利用したサイト向けの Chrome Extension の書き方 - @kyanny's blog](http://blog.kyanny.me/entry/2014/06/09/233708)
- [inject.js · NARKOZ/crank-for-rubygems](https://github.com/NARKOZ/crank-for-rubygems/blob/d52f6a99504b9bb46e45b4e06b88c3741856dc3a/inject.js#L28-L43)（Chrome Extension）
- [github-userscripts/refer-issue-when-creating.user.js](https://github.com/motemen/github-userscripts/blob/8832fd765d5f8267313fbfa332c038237876ee89/refer-issue-when-creating/refer-issue-when-creating.user.js#L9-L12)（ユーザースクリプト）

## 独自イベントを取得する

どこでも使える方法ではないが、サイト側のJavaScriptで独自にイベントが発行されていることがある。

GitHubではpjaxの実装に[defunkt/jquery-pjax](https://github.com/defunkt/jquery-pjax)を使っているので[^ghpjax]、pjax処理の過程で`pjax:success`などのイベントがjQueryを使って発火される。

[^ghpjax]: 将来的には[github/pjax](https://github.com/github/pjax)に置き換えられそう。

[jQueryから発行されるイベントの名前に`:`が含まれる場合、vanilla JSから取得することはできない](http://qiita.com/vzvu3k6k/items/8ce7f48bc81c20d6e38e)ので、何らかの方法でコンテンツと同じコンテキストでJavaScriptを実行する必要がある。

GitHubでは<abbr title="Content Security Policy">CSP</abbr>で`'unsafe-inline'`が設定されているため、[Location hack](http://wiki.greasespot.net/Location_hack)や[Content Script Injection](http://wiki.greasespot.net/Content_Script_Injection)は使えない。`unsafeWindow`からjQueryを呼び出してイベントハンドラを設定する以外の方法はないのではないかと思う。

### 使用例など

- [github-linkify_gems_in_gemspec_gemfile.user.js](https://github.com/vzvu3k6k/github-linkify_gems_in_gemspec_gemfile.user.js/blob/067bf775db4c6272b6543808d835e73e6aea3e0c/github-linkify_gems_in_gemspec_gemfile.user.js#L56-L58)（ユーザースクリプト）

<a rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="http://i.creativecommons.org/p/zero/1.0/80x15.png" style="border-style: none;" alt="CC0" /></a>
dateコマンドでLinuxサーバの時刻変更

はじめに
===

Linuxサーバ(CentOS 6.6)の時刻をdateコマンドで一時的に変更する例です。

たまにアプリケーション等の検証目的で、サンドボックス用途のLinuxサーバを対象として、一時的にLinuxサーバの時刻を変更する事があります。備忘を兼ねて、時刻変更コマンドをメモしました。

注意事項
===

**サービスに影響を与えない かつ 自分しか利用していないサンドボックス用途のLinuxサーバでなら、自由にサーバ時刻変更しても大丈夫だと思いますが、本番環境や開発環境のサーバでは時刻変更しないようご注意下さい。**

**もし、本番環境や開発環境のサーバについて、どうしてもサーバの時刻変更が必要となる場合は、サーバ管理者の方々とご相談しましょう。**

また、サンドボックスのLinuxサーバで時刻変更が必要なテストが終わったら、ntpdateコマンドを使うなりして、変更した時刻を元に戻しておくと良いでしょう。

Linuxサーバの時刻変更コマンド
===

・Linuxサーバの時刻を10分前に変更するコマンド。

```
# date
Fri Jan 30 14:19:50 JST 2015
#

# date -s "`date +'%m'`/`date +'%d'` `date -d '10 minutes ago' +'%H:%M'` `date +'%Y'`"
Fri Jan 30 14:09:00 JST 2015
#

# date
Fri Jan 30 14:09:01 JST 2015
#
```

・変更したい時刻を直接指定して変更するコマンド。

以下はLinuxサーバの時刻を2015/01/30 13:00:00に変更する例です。

```
# date -s "01/30 13:00 2015"
Fri Jan 30 13:00:00 JST 2015
#

# date
Fri Jan 30 13:00:02 JST 2015
#
```

・一時的に変更したLinuxサーバの時刻を元に戻すコマンド例。

```
# date
Fri Jan 30 13:00:01 JST 2015
#

# ntpdate -s -b ntp.jst.mfeed.ad.jp
#

# date
Fri Jan 30 14:27:14 JST 2015
#
```

以上になります。
Springboot Reactjs でHerokuで動くSampleを試作しました

下記のUrlで試して下さい。

[https://spring-react.herokuapp.com](https://spring-react.herokuapp.com)
![heroku1.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/2a9059e9-74c7-9703-d88b-cc1884cce30b.jpeg)


LOGINボタンを押し、Login ID = test, Password = testで入れます。
![heroku2.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/ce1f1ab6-0a45-14ad-861e-f65c2aff5a78.jpeg)


左側のボタンを押すと各画面が新たなタブで開きます。
![heroku3.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/f2b4cec0-c49d-1fd5-4677-b9456294157b.jpeg)


LOGOFFを押すと、開いたTABを閉じて LOGOFFします。

USER管理は、LOGIN Userの管理画面です。（本来はAdministrator権限ですね）

表のアイテムをクリックすると、下側のフォームに表示されます。

変更後　更新ボタンを押すと更新されます。

新規追加の場合は、新規ボタンを押し、データ　を入れた後、更新ボタンを押します。

USER INLINEは機能はUSER管理と同様ですが、Excelの様に INLINE EDIT出来ます。

また行をDrug and Dropで入れ替える機能も入れてあります。

![heroku4.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/dd8beb6f-7e80-a3c2-4c51-4b5aea11c7ae.jpeg)


USERタブは機能はUSER管理と同様ですが、タブで分かれています。
![heroku5.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/f64b06da-f792-8b76-bcd7-2996ef1fd11d.jpeg)


ユーザーテーブルとシステムテーブルは機能は同じですが、権限が違っていて、
testでLOGINすればすべての画面が開きますが、aabbcc(パスワードは同じtest)だと
システムテーブルは権限がなく開けません。
![heroku6.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/c0a1fa41-0df5-0cad-c38a-09556e7e92a2.jpeg)

なお権限の管理はシステムテーブルで行っています。
![heroku7.jpg](https://qiita-image-store.s3.amazonaws.com/0/20387/020ed270-f815-e915-a8c4-c2c6359524ee.jpeg)


ソースは[GitHub](https://github.com/mikeshimura/spring-react)に置いてあります。

下記 HEROKUボタンを押すと、HEROKUのアカウントがあれば無料で同じものが出来ます。
[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/mikeshimura/spring-react)

データベースは下記コマンドでLoad出来ます。

heroku pgbackups:restore HEROKU_POSTGRESQL_XXXX https://s3.amazonaws.com/springreact/springreact.dump --app your-app-name

###環境

* springboot
* dbflute
* reactjs
* Fluxxor
* CoffeeScript
* react-bootstrap

参考　[React.js, Flux, CofeeScriptで試作したメモ](http://qiita.com/mikeshimura/items/ccc225f2fc64f20fe656)
jQueryでtriggerされたイベントをjQueryを使わずに取得するための条件

`jQuery(elem).trigger(eventType)`が実行されたとする。このとき発生したイベントをjQueryを利用せずに取得できるだろうか。

## `jQuery.fn.trigger()`の実装の概要

`jQuery.fn.trigger()`は`jQuery.event.trigger()`の薄いラッパーになっていて、処理の大半は`jQuery.event.trigger()`の中で行われる（どちらも[src/event.js](https://github.com/jquery/jquery/blob/master/src/event.js)で定義されている）。

現在のDOMではイベントを生成するAPI（`new Event`, `document.createEvent`）と、生成したイベントを発行するAPI（`EventTarget.dispatchEvent(event)`）が提供されているが、jQueryはそれらのAPIを使わず、独自にイベントオブジェクトを作り、イベントのバブリング[^jquery-capture-phase]なども自前で実装している。

[^jquery-capture-phase]: `trigger()`メソッド内のイベント伝播のシミュレートでは、capture phaseには対応せず、bubbling phaseのみ実装している。`jQuery.fn.bind`などは、IE8以下ではcapture phaseがサポートされていないという理由でcapture phaseに対応していない（参考: [Jquery .bind events triggered when event capture or event bubble(Stack Overflow)に対するT.J. Crowderの回答](http://stackoverflow.com/a/15472362)）のと関係があるのかもしれない。

`jQuery.fn.trigger()`によってイベントが発行される処理を大まかにまとめると次のようになる。

1. イベントがバブリングするノードをリストアップして、それぞれに「jQueryから設定されたイベントハンドラを実行して、`node['on' + type]`が呼び出せそうならそれも実行する」という処理を行う。
  - ここでの`type`は`trigger()`の引数として渡されたイベント名からネームスペースを取り除いたもの（`jQuery(node).trigger("click.foo.bar")`なら`click`になる）。
  - `type`に`:`が含まれている場合は`node['on' + type]`は実行されない。
2. イベントの`preventDefault()`が呼ばれていなければ、`elem[type]`を見て、これが関数であれば実行する[^trigger-method-propagation]。
  - ここでの`elem`はイベントの起点になるノード（`jQuery(elem).trigger(event)`）。
  - `type`に`:`が含まれている場合はこの処理は実行されない。

[^trigger-method-propagation]: 余談だが、一部のブラウザでは`HTMLElement.click()`などで発火したイベントも伝播するので、ここで`node['on' + type]`がもう一度実行される。

## 例

- `click`:
  1. バブリングの対象になるノードの`onclick`プロパティに関数を設定しておくと、1の処理の中で実行される。
  2. ほとんどのノードにはネイティブの`click`メソッドがあるはずなので、イベント伝播の対象になるノードに標準のイベントリスナーを設定しておけば（伝播中に他のリスナーが伝播を抑止しない限り）イベントを取得できる。
- `click.foo.bar`: `click`と同じ。
- `reset`: 
  1. `click`の1と同じ。
  2. イベントの起点になるノードにネイティブの`reset`メソッドがあるときには`click`の2と同じ。そうでない場合には`foobar`の2と同じ。
- `foobar`（非標準のイベント）
  1. バブリングの対象になるノードの`onfoobar`プロパティに関数を設定しておくと、1の処理の中で実行される。
  2. イベントの起点になるノードの`foobar`プロパティに関数を設定しておくと、2の処理の中で実行される。
- `ajax:success`: 取得できない。

テスト: [Catching jQuery events by vanilla JS - JSFiddle](http://jsfiddle.net/vzvu3k6k/t4j5esvk/1/)

## 参考・関連

- [.trigger() | jQuery API Documentation](http://api.jquery.com/trigger/)
- [自作オブジェクトのイベントのやりとりにはjQuery.triggerではなくjQuery.triggerHandlerを使うほうがよいと思った - hitode909の日記](http://hitode909.hatenablog.com/entry/2013/11/24/174809)

<a rel="license" href="http://creativecommons.org/publicdomain/zero/1.0/"><img src="http://i.creativecommons.org/p/zero/1.0/80x15.png" style="border-style: none;" alt="CC0" /></a>
Chromeアプリ：アイコンをクリックしてアイコンの色を変える。

勉強＆メモとして書きます。
今回はchrome extensions samples の
>[A browser action which changes its icon when clicked](https://developer.chrome.com/extensions/samples#search:browseraction)

からファイルをダウンロードしたものを勉強します。これはブログタイトル通りの拡張機能です。

manifest.json
----------
```manifest.json
{
  "name": "A browser action which changes its icon when clicked",
  "description": "Change browser action color when its icon is clicked",
  "version": "1.2",
  "background": { "scripts": ["background.js"] },
  "browser_action": {
      "name": "Click to change the icon's color"
  },
  "manifest_version": 2
}
```

必要最低限といった感じですね。***アイコンを使うのでbrowser_action***。***クリック時の動作をbackground.jsで記述している***感じです。

background.js
-----

```background.js
var min = 1;
var max = 5;
var current = min;

function updateIcon() {
  chrome.browserAction.setIcon({path:"icon" + current + ".png"});
  current++;

  if (current > max)
    current = min;
}

chrome.browserAction.onClicked.addListener(updateIcon);
updateIcon();
```

きになるコードは

```js
chrome.browserAction.setIcon({path:"icon" + current + ".png"});
chrome.browserAction.onClicked.addListener(updateIcon);
```

の二つですね。一つ目は名前からして***アイコンの画像を指定できるコード***だと思います。
二つ目は***アイコンがクリックされたら発動するコード***だと思います。
最後のupdateIcon();を消したら，ファイル読み込み時に画像がない時のアイコンになっていたので，最後のupdateIcon();は読み込み時にアイコンをセットする意味があるんですね。
<br>
この機能を使ったアレンジが思いつかないので課題としておいておきます。
Node.js開発入門_02


 - nodeのインストール
 - HelloWorld
 - ノンブロッキングな処理を書く

## nodeのインストール

インストールは[Node.js公式](http://nodejs.org/)から行ってください。
正しくインストールできると、コマンドラインからnodeコマンドが利用できるようになります。
```node -v```と入力してバージョン情報が返ってくればインストールはOKです。
※当方Macbookで作業してますのでwinのことはよくわかりません

## HelloWorld

早速nodeを書きます。

```hello.js
console.log("Hello,World!!");
```

これだけ。
あとはコマンドラインから
```>node hello.js```
という形で実行してやると、ターミナルにHello,World!!が表示されますヽ(´@ω@｀)ﾉ

## ノンブロッキングな処理を書く

node.jsはスレッドモデル（一つの処理に一つのスレッドを使う）ではなく、イベントループ（一つのスレッドで処理を全て捌く）を用いています。
スレッドモデルとイベントループについての説明は、長くなりそうかつ本旨から外れるので割愛。代表的なところだと、Apacheがスレッドモデルでnginxがイベントループを採用しています。


このイベントループを途中で止めない(forループなどを使うとその処理のために次の動作に移れない(＝ブロックされてしまう))ために、node.jsではコールバック関数を用います。

### ブロッキングな処理
※日本語がどうとかいう話は取り敢えず今はなしで

```blocking_hello.js
for(var i=0;i<10;i++){
  console.log("Hello");
}
console.log("World");
```

上記の通りだと、forループが終わるまでWorldが表示されません。これがブロッキングな処理、forループが処理を止めてしまう状態になります。

結果
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
World

### ノンブロッキングな処理

``` nonblocking_hello.js
setTimeout(function(){
   for(var i=0;i<10;i++){
     console.log("Hello");
  }
},0);
console.log("World");
```

コールバック関数を使って上記の書き方をすると、forループが次の処理を止めずに済みます。

結果
World
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello
Hello

…なぜ10回Helloを出したかって、Helloの間にWorldが入ってきたら処理順序が見えやすくなるかなと思ったからだったんですが、目論見が外れました。THE無意味。というか認識が間違っているんでしょうか。

今回はここまでヽ(´@ω@｀)ﾉ
作成ファイルはgithubにアップロードしていますので、もしよければ見てみてください。
[node_sample - github (架空会社ぱあぷう)](https://github.com/perpouh/node_sample)


しかしドットインストール、一回一回短いのはいいけど早口なのはちょっと聞き取りにくいですね……
Serializeした属性の要素をバリデーションする

serializeを使うと柔軟にデータを保存できるようになって便利だが、バリデーションを書きづらいという問題がある。こういう場合は `ActiveModel::Validations#read_attribute_for_validation` を使うとRailsのバリデーション機構を使いまわすことができる。

例えば `File` モデルに `data` 属性があってそれがserializeされていて、 `data` には `"name"` `"link"` というキーがあり、 `"name"` は必須かつ長さ255以下、 `"link"` は必須にしたいとする。そういう場合はこんな感じで書ける

```rb:app/models/file.rb
class File < ActiveRecord::Base
  DATA_KEYS = %i(name link).freeze

  serialize :data, Hash

  validates :name, presence: true, length: { maximum: 255 }

  validates :link, presence: true

  def read_attribute_for_validation(key)
    DATA_KEYS.include?(key) ? data[key] : super
  end
end
```
〘JAVA〙配列の重複項目を削除する(HashSet不使用)

```
	public static void main(String[] args) {

		int arrayA[] = new int[5];
		arrayA[0] = 10;
		arrayA[1] = 11;
		arrayA[2] = 12;
		arrayA[3] = 13;
		arrayA[4] = 14;

		int arrayB[] = new int[5];
		arrayB[0] = 11;
		arrayB[1] = 11;
		arrayB[2] = 11;
		arrayB[3] = 11;
		arrayB[4] = 12;

		ArrayList arrayC = new ArrayList();

		for (int i = 0; i < arrayA.length; i++) {
			for (int j = 0; j < arrayB.length; j++) {
				if (arrayA[i] == arrayB[j]) {
					arrayC.add(arrayA[i]);
					break;
				}
			}
		}
		
		System.out.println(arrayC);
		
	}
```
EBSのNameタグにEC2のNameの値を自動で付ける。

# 目的
EC2と一緒に作成されるEBSにはタグ付けが自動で行えないので基本何もタグがつかないEBSが大量にできることになる。するとボリュームの一覧を見た時に何処にアタッチされてるボリュームなのかわからないくて不便。

何より個人的に嫌なのは、[Cost Allocation Tag](http://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/configurecostallocreport.html)による請求レポート分析から漏れて案件毎の請求額の把握が面倒なことになるのが嫌（プロジェクト単位でアカウント分けるてのもありだけどConsolidatedBillingて増やせるとはいえ20アカウント上限があるしAWSクレジットが適用されると請求書がゼロとかにされて実態把握が面倒だし結局BillingReportの詳細CSVから自分の好みに応じて集計するのが痒いところに手が届いて気持ち良いのよねー）なので。

だから、タグは可能な限り漏れ無く付けておきたい→自動化したい。

# 要件
以下の理由により各EC2インスタンス自身で付けさせるのはやりたくない。

- 絶対設定漏れがでる。（userdataで必ずこれ実行すること！とかルール決めてもどうせ忘れる）
- インスタンス起動後に別途EBSをアタッチした場合にそいつに付けるタイミングがないのでやっぱ漏れる。
- EC2には第三者（発注元や外注先など）もログインorコードデプロイ可能なので、与えるIAM権限は最小にしたい。（特定インスタンス(リソースIDじゃなく自身のインスタンスに対してとかファジーな感じ)や特定タグに対してのみに絞って権限を与えるということが出来ればいいが、そこまで細かい制御をIAMでは出来ないので）

# 実装
要件を踏まえて、管理用のインスタンスのcron実行により、タグ無し(or EC2と不一致)EBSを見つけて勝手にタグを付け直す形で実装してみました。

## IAM設定
まず管理用インスタンスのIAMRole(or IAMUser)に最低限以下の様なポリシーを追加しておます。

```json:ManageVolumeTags-20150130T131540
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags",
        "ec2:DescribeInstances",
        "ec2:DescribeRegions",
        "ec2:DescribeVolumes"
      ],
      "Resource": "*"
    }
  ]
}
```

## スクリプト

で、管理用インスタンス上で以下のスクリプトをcronで実行しとけば大体よい。

```bash:tag-to-ebs.sh
#!/bin/bash
volumeNamesByInstances() {
  region="$1"
  aws ec2 describe-instances --region "$region" --no-paginate --filters Name=tag-key,Values=Name |
  jq -r '.Reservations[].Instances[]|"\(.BlockDeviceMappings[].Ebs.VolumeId) \(.Tags[]|select(.Key=="Name").Value)"' |
  sort
}

volumeNamesByVolumes() {
  region="$1"
  aws ec2 describe-volumes --region "$region" --no-paginate |
  jq -r '.Volumes[]|"\(.VolumeId) \(.Tags[]?|select(.Key=="Name").Value)"' |
  sort
}

regions() {
  az=$(curl -sL http://169.254.169.254/latest/meta-data/placement/availability-zone)
  region="${az%[a-z]}"
  aws ec2 describe-regions --region "$region" | jq -r '.Regions[].RegionName'
}

for region in $(regions); do
  # EC2とEBSでタグの値に差異のある部分だけを更新する
  diff <(volumeNamesByVolumes "$region") <(volumeNamesByInstances "$region") | grep '^> ' |
  while read _ volumeId name; do
    [[ $name =~ ^- ]] && continue # skip dangerous
    aws ec2 create-tags --region "$region" --resources "$volumeId" --tags "Key=Name,Value=$name"
  done
done
```

## 実行間隔について
cronの実行間隔は、AWSの課金が1時間単位なのでその前にはタグを付けておきたいがそんなに急がなくてもよい、逆に短すぎてもAWSのAPIサーバに負荷かけると悪いかなーって気持ちと、そもそも現実問題としてdescribe系のAPIの結果が実は数分くらいキャッシュされてるらしくそれが原因でEC2側のタグを変えてもdescribeのレスポンスは暫く変わらないこともよくあるので頻繁にチェックする意味が無いので、僕は15分間間隔くらいで実行させている。


# おまけ
僕の要件には合わないけど、EC2自身にタグ付けさせたい人にはクラスメソッドさんのこの記事が参考になると思う。＞[EC2インスタンスのEBSルートボリュームに自動でNameタグを付与する ｜ Developers.IO](http://dev.classmethod.jp/cloud/add-name-tag-to-root-volume/)
Mac覚書　非表示のユーザーライブラリーを表示させる方法

非表示のユーザーライブラリーを表示させる方法をメモ

参考サイト：http://helpx.adobe.com/jp/x-productkb/global/cpsid_91195.html#main_C_____________________

***

参考サイトでは、３つの方法が紹介されいましたが、常に表示をしたかったので
下記の方法で表示させることにしました。

**常にライブラリフォルダーを表示する方法**
　以下の操作を行います。
　　①Finder で、移動／ユーティリティを選択します。
　　②ターミナルをダブルクリックして起動します。
　　③以下の文字列を入力し、Return キーを押します。
　　　chflags nohidden ~/Library
　　④パスワードの入力を促されたら、システム管理者のパスワードを入力し、
　　　Return キーを押します。
Xcode覚書　バージョンによるSegue名の違いについて


Segueのバージョンによる名称の違いについて、まとめてあるサイトがあったのでメモ。
名称の違いに混乱させられていたので助かりました。

参考サイト：http://selection9.blogspot.jp/2014/10/xcode6storyboadsegue.html

| Xcode5 | Xcode6 |
|:------:|:------:|
|Push|Show|
|Model|Present Modally|
|Popover|Present As Popover|
|Replace|Show Detail|
Thymeleafのif文で使う比較演算子の使い方

```html
<div data-th-if="${a > b}">
  true!
</div>
```
とかやると怒られます。

正しくは、

```html
<div data-th-if="${a gt b}">
  true!
</div>
```

ようは、ThymeleafはHTMLなので『>』とか『<』とかそのまま書いちゃダメでしょってことです。
ちなみに『==』とかはHTMLでエスケープする必要がないので使うことができます。

#よく分かる対応表
| Javaの演算子 | Thymeleafの演算子 |
|:-:|:-:|
| > | gt |
| < | lt |
| >= | ge |
| <= | le |
| ! | not |
| == | eq |
| != | neq |

| && | and |
|:-:|:-:|
| &#124;&#124; | or |
fork元のリポジトリへの変更をforkしたリポジトリに反映する

**20190429追記**
わかりにくい表現を修正しました。
内容の変更はしていません。
**追記ここまで**

forkしたリポジトリのブランチを、fork元のリポジトリのブランチに追従させる、ということをGitコマンドで実行します。
このコマンドをJenkins等で実行することもできます。

※ここでは[Git初心者に役立つ「よく使うコマンド集」②](http://qiita.com/chihiro/items/b69f1051b7bca6361e01)で紹介したコマンドを使用しています。

### 0.今回の環境
fork元のリポジトリ名：fork_master
追従したいブランチ：develop
forkしたリポジトリのリモートリポジトリ名：origin


### 1.fork元のリポジトリがリモートリポジトリとして存在しなければ、リモートリポジトリとして追加する
1.リモートリポジトリの一覧を表示して確認します。

```bash
$ git remote

origin    # forkしたリポジトリのみリモートリポジトリとして登録済み
```


2.fork元のリポジトリを「fork_master」という名前で追加します。

```bash
$ git remote add fork_master <url> 
```

3.追加されていることを確認します。

```bash
$ git remote

origin
fork_master　　
```

### 2.fetch
1.fork元のリポジトリをfetchします。

```bash
$ git fetch fork_master　　
```


### 3.fork元のリポジトリの追従したいブランチのローカルブランチを作成する
1.「fork_master_develop」という名前でローカルブランチを作成します。

```bash
$ git checkout -b fork_master_develop fork_master/develop
```

2.ブランチの一覧を表示して確かめてみます。

```bash
$ git branch -a

* fork_master_develop
...
...
...
```

### 4.追従するブランチを最新化
1.forkしたリポジトリのブランチ(fork元の変更を取り込みたいブランチ)を最新化しておきます。

```bash
$ git checkout develop
$ git pull origin develop
```

### 5.マージ
1.forkしたリポジトリのブランチにfork元のリポジトリのブランチをマージします。

```bash
$ git branch
* develop
...
...

$ git merge --no-ff fork_master_develop
```


### 6.push
1.forkしたリポジトリのブランチをpushします。

```bash
$ git push origin develop
```

以上です。
ちなみに3の手順はなくてもできます。
ローカルにリポジトリを作成せずに、リモートブランチを追従したいブランチに直接マージすればよいです。
Xcode 6.1導入後にJenkins Xcode Pluginでエラーが発生した際の対処

# 経緯
Xcode6.1.1にアップグレード後にJenkinsのXcode Pluginを使用してビルドする際に「ResourceRules.plist: cannot read resources」というエラーが発生するようになりました。

# 対策
プロジェクトの設定にて、「Xcode」-「Advanced Xcode build options」-「Custom xcodebuild arguments」欄に
`CODE_SIGN_RESOURCE_RULES_PATH="$(SDKROOT)/ResourceRules.plist"`
を記載する。
NetBeansでのxdebug設定方法

# NetBeansでのxdebug設定方法

開発環境：Windows7 php5.5.19

### 自分の環境にあったxdebug.dllを探す方法  
- 下記ソースでphpinfoを表示する。  
　`<?php phpinfo()  php?>`  
- <http://xdebug.org/wizard.php>へ出力されたphpinfoをコピーして貼り付け、実行すると下記画面のようになる。  
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/67654/81263421-a209-4bbc-9d1f-71325e9fddcc.jpeg)
  
- 出力画面のdllダウンロードリンクからダウンロードして、記載の場所へdllを格納する。  
- php.iniファイルを変更する。
- php.iniファイルの変更箇所(下記項目を追加した)
 `[XDebug]
  zend_extension="C:\php55\ext\php_xdebug-2.2.7-5.5-vc11-x86_64.dll"  
  xdebug.remote_enable=1
  xdebug.remote_host="127.0.0.1"
  xdebug.remote_port=9000
  xdebug.remote_handler="dbgp"
  xdebug.idekey="netbeans-xdebug"
  xdebug.profiler_output_dir="C:\php55\tmp"`

### NetBeansでの変更箇所
- [ツール]-[オプション]-[php]を選択し、デバッグタブを選択する。(下記画面参照)
- デバッグポート、セッションIDをphp.iniへ記載したものへ変更する。  
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/67654/8fa6e62b-8d0a-3f5f-e028-ce705b6d5105.jpeg)
 
NetBeansプロジェクトを「PHP組込みWebサーバー」で実行する場合はアパッチの再起動は不要でNetBeansの再起動でOK。ローカルにインストールしたアパッチで動かす場合はアパッチ再起動が必要。

![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/67654/088d9f26-0cd1-b123-00f9-8c523b390128.jpeg)
(小ネタ) tmuxのセッション状態を保存・復元できるtmux-resurectを使おう！

tmuxはターミナル使いとしては必須のツールなんですが、PC毎再起動した時に元に戻すのが面倒だと思っていた。
tmuxinator使えよ、という話もあるのだが、あれ設定が若干面倒なのと設定した状態に戻す事しか出来ないんで、再起動の時に元の状態に戻る訳じゃない。
もうちょっと良い方法は無いのかと探していたらこんなのがあった。

[tmux-plugins/tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect "tmux-plugins/tmux-resurrect")

prefix + CTRL-Sでセッション状態を保存。
prefix + CTRL-Rでセッション状態を復元できる。

設定を組み合わせれば起動しているプロセスの保存も出来るし、vimのセッションも戻せるらしい。
これで再起動後も快適に過ごせる。

他にもいくつかtmuxのプラグインを調べてみたが、[tmux-plugins/tmux-sessionist](https://github.com/tmux-plugins/tmux-sessionist "tmux-plugins/tmux-sessionist")も便利そうだった。
データベース内のテーブル定義をcsv出力するコマンド書いた

テーブル定義を把握したい時に便利そうだったので書いてみた

```
#!/bin/bash

usage()
{
    echo "usage: `basename $0` -u USER -h HOST -p PASSWORD -d DATABASE
    -u      user
    -h      host
    -p      password
    -d      database
    --help  show this message
    "
    exit
}

OPT=`getopt -o u:h:p:d: --long help -- "$@"`
if [ $? -ne 0 -o "$1" = "" ]; then
    usage
fi
eval set -- "$OPT"

while true
do
    case "$1" in
        -u )
            MYSQL_USER=$2
            shift 2
            ;;
        -h )
            MYSQL_HOST=$2
            shift 2
            ;;
        -p )
            MYSQL_PASS=$2
            shift 2
            ;;
        -d )
            MYSQL_DATABASE=$2
            shift 2
            ;;
        --help )
            usage
            ;;
        -- )
            break
            ;;
        * )
            echo "Unknown parameter $1"
            usage
            ;;
    esac
done

if [ "$MYSQL_USER" = "" -o \
     "$MYSQL_HOST" = "" -o \
     "$MYSQL_PASS" = "" -o \
     "$MYSQL_DATABASE" = "" ]; then
    usage
fi

mysql -u$MYSQL_USER -h$MYSQL_HOST -p$MYSQL_PASS $MYSQL_DATABASE -N -e "show tables" \
    | xargs -I{} bash -c "
        echo {};
        mysql -u$MYSQL_USER -h$MYSQL_HOST -p$MYSQL_PASS $MYSQL_DATABASE -e 'desc {}';
        echo" \
    | sed 's/\t/,/g'
```

localhostのmysqlデータベースのテーブル定義を見る場合、以下のように使う

```
$ ./show_create_tables -u root -h localhost -p 1234 -d mysql
columns_priv
Field,Type,Null,Key,Default,Extra
Host,char(60),NO,PRI,,
Db,char(64),NO,PRI,,
User,char(16),NO,PRI,,
Table_name,char(64),NO,PRI,,
Column_name,char(64),NO,PRI,,
Timestamp,timestamp,NO,,CURRENT_TIMESTAMP,on update CURRENT_TIMESTAMP
Column_priv,set('Select','Insert','Update','References'),NO,,,

db
Field,Type,Null,Key,Default,Extra
Host,char(60),NO,PRI,,
Db,char(64),NO,PRI,,
User,char(16),NO,PRI,,
Select_priv,enum('N','Y'),NO,,N,
Insert_priv,enum('N','Y'),NO,,N,
Update_priv,enum('N','Y'),NO,,N,
Delete_priv,enum('N','Y'),NO,,N,
Create_priv,enum('N','Y'),NO,,N,
Drop_priv,enum('N','Y'),NO,,N,
Grant_priv,enum('N','Y'),NO,,N,
References_priv,enum('N','Y'),NO,,N,
Index_priv,enum('N','Y'),NO,,N,
Alter_priv,enum('N','Y'),NO,,N,
Create_tmp_table_priv,enum('N','Y'),NO,,N,
Lock_tables_priv,enum('N','Y'),NO,,N,
Create_view_priv,enum('N','Y'),NO,,N,
Show_view_priv,enum('N','Y'),NO,,N,
Create_routine_priv,enum('N','Y'),NO,,N,
Alter_routine_priv,enum('N','Y'),NO,,N,
Execute_priv,enum('N','Y'),NO,,N,
Event_priv,enum('N','Y'),NO,,N,
Trigger_priv,enum('N','Y'),NO,,N,
...
```
スマホで背景fixedしたい時のCSSメモ


Mobile Safari等 ```background-attachment:fixed;``` が効かない環境でもそれらしいことをやりたい場合の方法として、```position:fixed;``` の全面div要素を背面に敷いておく方法がよく紹介されていました。
少し改良?しつつメモ。

---------------------------------------------------

#### サンプル

http://jsrun.it/volkuwabara/w5KY
(スマホからどうぞ)

#### ソース

```css:css
body::before {
  background:url('bg.png') no-repeat left top;
  background-size: 100% auto;
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  padding-bottom: 108px;
  content: "";
  z-index: -1;
}   
```

#### 説明

* 空の```div```は嫌なので背景を敷きたい親要素の```::before```擬似要素でやった。(上記例では```body```)
* iOS7以降のMobile Safariで、スクロールダウン中に上下のUIが引っ込む時に、その分の背景が埋まらない(touchendしないとheight:100%が更新されない) ので、```height:100%;```としつつ、この引っ込む差分(デバイス横向きだとこのUIが完全に隠れる) 108px (iOS7は上:64px, 下:44pxだった)を padding にあらかじて足してはみ出させておく。とはいえiOSのことばかりではないので、```height:150%;```とかにしておくのがてっとり早いかも。
* ```background-size```は```cover```や```contain```にしたかったがブラウザのUIが出たり引っ込んだりするときに背景サイズがガクガク変わって煩わしいので```100% auto```が素直そう。


#### その他

あるいは ~~iOS7.1以降~~  iOS7 ではViewportに```minima-ui```指定を入れると、デフォルトでUIが隠れた状態でロードされるそうです。

```html:html
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimal-ui">
```

> 追記(2016/4/22)：
iOS8以降では `minimal-ui` は廃止されたため、iOS7でしか意味をなしません。

いずれもやりかたがちょっと強引なので、```background-attachment:fixed;``` に対応してくれればいいのになと思いました。
　

---------------------------------------------------

参考：
・ http://d.hatena.ne.jp/tt_clown/20130819/fixed_background
・ https://w3g.jp/blog/ios7_1_minimal-ui_warning
Wordpress plugin ぽちぽち



WordPress の add_action と add_filter などのフックが分からないから調べた！ : actyway
http://actyway.com/3750

関数リファレンス
http://wpdocs.sourceforge.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_filter


get_the_title
http://wpdocs.sourceforge.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_the_title

get_permalink
http://wpdocs.sourceforge.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/get_permalink


WordPressのプラグインを開発しよう（初級編）
http://www.webopixel.net/wordpress/631.html


■ 読んどいたほうがいい良記事
・投稿タイプについて
http://webdesignrecipes.com/wireframe-with-wordpress-post-type/
（具体例：http://webdesignrecipes.com/wordpress-corporate-website/ ）

・テンプレート階層
→ どのテンプレートPHPが表示されるか？？
http://wpdocs.sourceforge.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E9%9A%8E%E5%B1%A4

■ リファレンス
・WordPress Codex（公式ドキュメント）
http://wpdocs.sourceforge.jp/

※ ぐぐって調べた情報は、あまり信用しないほうが吉。


セキュリティの基本
http://wpdocs.sourceforge.jp/WordPress_%E3%81%AE%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B

エスケープ
http://morilog.com/wordpress/tips/wp_escape/


テスト環境から本番環境へ、URLが異なる環境にWordPressを移行する方法
http://www.slideshare.net/ryujiroyamamoto/wordbenchchiba20130518?related=1
Bowerのインストールで「Error: EACCES〜」が発生した場合の対処


Bowerをインストールしてみようとしたところ、早速エラーが出たので、対処した作業ログを。
~/.npmにある幾つかのファイルの所有者がrootになってたのが原因だった模様。


```bash
# yuto-ogi [11:53:22]
$ npm install bower -g
npm ERR! Darwin 14.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "bower" "-g"
npm ERR! node v0.10.36
npm ERR! npm  v2.3.0
npm ERR! path /Users/yuto-ogi/.npm/graceful-fs/3.0.5
npm ERR! code EACCES
npm ERR! errno 3

npm ERR! Error: EACCES, mkdir '/Users/yuto-ogi/.npm/graceful-fs/3.0.5'
npm ERR!  { [Error: EACCES, mkdir '/Users/yuto-ogi/.npm/graceful-fs/3.0.5']
npm ERR!   errno: 3,
npm ERR!   code: 'EACCES',
npm ERR!   path: '/Users/yuto-ogi/.npm/graceful-fs/3.0.5',
npm ERR!   parent: 'bower' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/yuto-ogi/Dropbox/Public/source/npm-debug.log
```

確認してみると、そこにはrootパーミッションに設定されたgraceful-fsが。

```bash
# yuto-ogi [11:53:34]
$ ll ~/.npm
~
drwxr-xr-x   4 root      staff   136 11  3 15:50 graceful-fs
~
```

ということで、所有者をログインユーザーに変更します。

```bash
# yuto-ogi [11:54:38]
$ sudo chown -R yuto-ogi ~/.npm/
```

リトライ。

```bash
# yuto-ogi [11:54:44]
$ npm install bower -g
/usr/local/bin/bower -> /usr/local/lib/node_modules/bower/bin/bower
bower@1.3.12 /usr/local/lib/node_modules/bower
├── is-root@1.0.0
├── junk@1.0.0
├── stringify-object@1.0.0
├── abbrev@1.0.5
├── chmodr@0.1.0
├── which@1.0.8
├── osenv@0.1.0
├── archy@0.0.2
├── opn@1.0.1
├── rimraf@2.2.8
├── bower-logger@0.2.2
├── bower-endpoint-parser@0.2.2
├── lru-cache@2.5.0
├── graceful-fs@3.0.5
~
```

無事インストールできました！

```bash
# yuto-ogi [11:54:44]
$ bower -v
1.3.12
```

今回は~/.npmの所有者をゴソっと直しちゃったけど、自分のユーザーディレクトリ直下なのに、~/.npm/に所有者がrootのディレクトリが幾つかあったのが解せん。。。
node/npmはあんまり触ったことないので、もっとスマートなやり方があれば知りたいですね。
シェルにおける eth0 や en0 の IP アドレスの取得のしかたと、GNU sed と BSD sed の挙動違い


Linux の場合。以下は Boot2docker の /etc/init.d/docker より。ip(8) と sed(1) を使っている。

~~~~console:
$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether d8:50:e6:4c:be:de brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.64/24 brd 10.0.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::da50:e6ff:fe4c:bede/64 scope link
       valid_lft forever preferred_lft forever
$ ip addr show eth0 | sed -nEe 's/^[ \t]*inet[ \t]*([0-9.]+)\/.*$/\1/p'
10.0.0.64
~~~~

OS X には ip(8) が無いので ifconfig(8) を使う。そもそもで `eth0` も無いが。そして驚いたことに、BSD sed は GNU sed と違い、タブを展開しない。

エスケープではなく、直接にタブ文字を入れろ、ということのようだ。 ∥ [regex - How can I insert a tab character with sed on OS X? - Stack Overflow](http://stackoverflow.com/questions/5398395/how-can-i-insert-a-tab-character-with-sed-on-os-x)

以下は、Bash にタブを展開してもらった例。しかし、今度は `\1` をエスケープする必要が生じた。

~~~~console:
$ ifconfig en0 | sed -nEe $'s/^[ \t]+inet[ \t]+([0-9.]+).*$/\\1/p'
192.168.34.65
~~~~

タブ文字を使いたくなければ、やはり sed(1) の方で、ブラケット展開の文字クラスを使って書かざるを得まい。ところがさらに、re_format(7) (BSD) に書かれていることと違って、`[[:space:]]` と `\s` が等価でない問題が。

~~~~console:
$ ifconfig en0 | sed -nEe 's/^[[:space:]]+inet[[:space:]]+([0-9.]+).*$/\1/p'
192.168.34.65
$ ifconfig en0 | sed -nEe 's/^\s+inet\s+([0-9.]+).*$/\1/p'
$ 
~~~~

細かいところ、BSD は緩いのかね？ Linux, OS X 両対応するなら以下で。 ∥ [shell - Check if a program exists from a bash script - Stack Overflow](http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script)

~~~~bash:
command -v ip &> /dev/null && \
 ip addr show eth0 | sed -nEe 's/^\s+inet\W+([0-9.]+).*$/\1/p' || \
 ifconfig en0 | sed -nEe 's/^[[:space:]]+inet[[:space:]]+([0-9.]+).*$/\1/p'
~~~~

あるいは、こんなか。

~~~~bash:
(command -v ip &> /dev/null && ip addr show eth0 || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+inet[^[:alnum:]]+([0-9.]+).*$/\1/p'
~~~~

追記（Feb 24 2015）: eth0 や en0 の MAC アドレスが欲しい場合には、以下のような感じか。

~~~~bash:
(command -v ip &> /dev/null && ip addr show eth0 || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+(link\/)?ether[[:space:]]+([0-9a-f:]+).*$/\2/p'
~~~~

追記（Apr 26 2016）: Ubuntu のバージョンを上げて systemd になったせいか、NIC の命名ルールが [PredictableNetworkInterfaceNames](https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/) に変更になった。うちの子たちは 1 Ethernet しか積んでいないので、とりあえず一つ目に見つかった Ethernet デバイスの IP アドレスを取ってくるようにするよ。なお、DELL のハードウェアは Linux 的には特別扱いで、“biosdevname” なる、これまた別のルールで命名されるらしい。 ∥ [RHEL7のNICのネーミングルール - めもめも](http://enakai00.hatenablog.com/entry/20140728/1406504163)

~~~~bash:
(command -v ip &> /dev/null && ip addr show \
 $(basename $(ls -d /sys/class/net/{en*,eth*,em*} 2> /dev/null | \
 head -n 1)) || ifconfig en0) | \
 sed -nEe 's/^[[:space:]]+inet[^[:alnum:]]+([0-9.]+).*$/\1/p'
~~~~
ラピッドVPSで Class 'RuntimeException' not found 出た(CakePHP)

# PHP5.2 でCakePHP2が動かない?!
ラピッドサーバの古いVPS環境でCakePHP2を動かそうとしたら、

`Fatal error: Class 'RuntimeException' not found`

でまったく動かない。とりあえず、PHPのバージョンを確認
`# php -v`
>PHP 5.2.17 with Suhosin-Patch 0.9.7 (cli) (built: Jan 12 2011 20:44:22)
>Copyright (c) 1997-2009 The PHP Group
>Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies

PHPのバージョンは5.2。CakePHP2の動作には問題ないはず。
そもそも、RuntimeExceptionクラスはどこが提供しているのか調てみると。。

[PHP公式](http://php.net/manual/ja/book.spl.php)だった。
マニュアルを見ると、RuntimeExceptionは SPLという機能の一部で、PHP5.1以上なら標準で付属してますとの事。サンプルにあるコードでSPLが使えるか検証。

```php:spltest.php
<?php
print_r(spl_classes());
?>
```
Fatal error: Call to undefined function spl_classes()
何も使えません。

という事は、このサーバ固有のPHP設定がされているようなので、変更可能かラピッドVPSのマニュアルを検索してみた。

# ラピッドVPSでのPHP環境方法
マニュアルを見ると、vinstall コマンドで各種環境変更を行う仕組みになっていた。まずは実行する

`# vinstall`
>Select an option:
>?               view list of programs
>install         enter install mode
>module_name     view information about program name
>quit            exit vinstall program
>--\>

メニューが起動する。?で変更できるプログラム一覧を確認できる。今回は、php5.2の変更を行うので、
`-->install`
`Enter module name to install -->php5.2`

![スクリーンショット 2015-01-30 11.45.24 のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/65326/5f1ce0dd-f8ff-2e6c-ac7b-21081eaf501d.png)

make configとかでよく見る画面がでてきた。ここでモジュールの有効/無効を設定できる。(カーソルで移動、スペースでON/OFF)
よく見るとSPLだけでなく、足りないモジュールがあったので以下を有効な状態にした
* bz2
* CTYPE
* CURL
* DBA
* DOM
* GD
* GETTEXT
* HASH
* ICONV
* JSON
* MBSTRING
* MCRYPT
* MHASH
* MYSQL
* MYSQLI
* OPENSSL
* PDO
* PDO_MYSQL
* SESSION
* SIMLEXML
* SOCKETS
* SPL

モジュールの追加をしたので
`# service httpd restart`
でWebサーバの再起動を行なっておく。

# 再トライ
CakePHPを再度導入してみる。動いた! もう問題なさそう
Data::DumperでJSONの出力メモ

PerlでJSONを作る時に、ハッシュから作っても良いのだけども、Data::Dumperを使ってさくっと作る方法をメモ。

```pl:sample
use Data::Dumper;

my $data;
for my $hoge ( keys %{$hoge} ) {
    $data->{ $hoge{'uniq_no'} }->{'created_at'}  = $hoge{'created_at'} || '';
    $data->{ $hoge{'uniq_no'} }->{'username'}    = $hoge{'username'} || '';
}

my $dump = Data::Dumper->new( [$data] )->Indent(1)->Terse(1)->Useqq(0)->Sortkeys(sub { [sort {$data->{$b}->{'created_at'} cmp $data->{$a}->{'created_at'}} keys %{$_[0]}] })->Pair(':')->Dump;
$dump =~s/'/"/mg;

```
Sortkeysの中で無名サブルーチンを使ってソートしているのが、みそです。
あと、「|| ''」とすることで、undefの表示を潰しています。

Useqqを有効にすると２バイト文字がエスケープするため、ここでは無効にし、後から置換で「'」から「"」に変換しています。
ここもData::Dumperのオプションでさくっとできれば良いのだけど、Data::Dumperモジュールの改修以外の方法で、良い案ないかなー。
俺は32ビットなのか、64ビットなのか。

#.NET Framework4.0未満
* IntPtr.Size = 8 の場合は 64 ビットモードでプロセスが動作している。 
* IntPtr.Size = 4 の場合は 32 ビットモードでプロセスが動作している。 

IntPtrはIntのポインタサイズなのでバイトからビットへ変換すればいいと思うよ。

```basic:sampleFX2.vb
if IntPtr.Size = 8 then
    'ロクヨン
else
    'ハチロク
end if
```
#.NET Framework4.0以上
Environment.Is64BitProcess を参照する
https://msdn.microsoft.com/ja-jp/library/system.environment.is64bitprocess(v=vs.110).aspx

```basic:sampleFX4.vb
if Environment.Is64BitProcess then
    'ロクヨン
else
    'ハチロク
end if
```
〘JAVA〙HashSetを使って配列の重複項目を削除する

```
public static void main(String[] args) {

		int arrayA[] = new int[5];
		arrayA[0] = 1;
		arrayA[1] = 1;
		arrayA[2] = 1;
		arrayA[3] = 3;
		arrayA[4] = 0;
		
		int arrayB[] = new int[5];
		arrayB[0] = 1;
		arrayB[1] = 0;
		arrayB[2] = 0;
		arrayB[3] = 3;
		arrayB[4] = 3;	
		
		Set<Integer> arrayC = new HashSet();

		for ( int i = 0; i < arrayA.length; ++i) {
			for ( int j = 0; j < arrayB.length; ++j ) {		
				if(arrayA[i]==arrayB[j]){							
					arrayC.add( new Integer( arrayA[i] ) );				
				}
			}		
		}
	
	   Iterator outPutArray = arrayC.iterator();
	    while (outPutArray.hasNext()) {
	        System.out.println(outPutArray.next());
	    }
	}
```
AWS EC2 で既存の EBS AMI から Instance Store Image 作成

# はじめに
最近はシステムデータ用途にInstance Store Image を利用することは少ないと思うが、
終了時にディスクが消去されてもよい状況で、追加費用無しで利用できる
ディスクとして利用する状況はまだそれなりにあると思う。

今回は既存の EBS で稼働しているシステムから Instance Store Image を使用したAMIを作成する。

# 必要なもの
* AWS Access Key ID (S3にアクセス権限のある IAM ユーザー)
* AWS Secret Key (S3にアクセス権限のある IAM ユーザー)
* S3 Bucket (AMIデータのアップロード先)
* AWS Account Number ([ここ](https://console.aws.amazon.com/billing/home?#/account)で確認できる)
* X.509 証明書 (~/certificate/iam_cert.crt)
* X.509 秘密鍵 (~/certificate/iam_cert.key)

また Amazon Linux 以外のディストリの場合は、
事前に Amazon EC2 CLI や AMI Tools の導入が必要になる。

[Setting Up the Amazon EC2 CLI and AMI Tools](http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ec2-cli-get-set-up.html#install-ami-tools)
[Setting Up the Amazon EC2 Command Line Interface Tools on Linux/Unix and Mac OS X](http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/set-up-ec2-cli-linux.html)

# IAM ユーザーの作成
AWS ダッシュボードから

* Identity & Access Management
  * Users

を選択し、S3にアクセス権限のある IAM User を作成する。

# S3 Bucket の準備
AWS ダッシュボードから、

* S3
  * Create Bucket

を選択し、作成するAMIを保存する Bucket Name を記述、Region を選択し Createをクリック。

# X. 509 証明書
## 証明書と秘密鍵の作成
X. 509 証明書が必要になるが、今回は作業用に自作する。
作業用マシンにディレクトリを作成し、下記のコマンドを実行し、
必要事項を入力する。

```
$ mkdir -p ~/certificate
$ cd  ~/certificate
$ openssl genrsa -rand rand.dat -des3 2048 > iam_cert.key    # 秘密鍵作成
$ openssl req -new -x509 -out iam_cert.crt -key iam_cert.key # 証明書作成
```
## 証明書と秘密鍵のアップロード
イメージ作成元となるインスタンスに以下のコマンドで秘密鍵と証明書をコピーする。

```
$ scp -i ~/.ssh/[AWS にアクセスするための秘密鍵] iam_cert.key ec2-user@[Instance Public IP]:/tmp/iam_cert.key
$ scp -i ~/.ssh/[AWS にアクセスするための秘密鍵] iam_cert.crt ec2-user@[Instance Public IP]:/tmp/iam_cert.crt
```

# Image の作成 
下記コマンドをイメージ作成元となるインスタンスで実行する。
最小構成のインスタンスで処理終了までに10分程度はかかった。

`-e /tmp` の部分は証明書を置いたディレクトリを指定する。

```
$ sudo su -
# ec2-bundle-vol --no-filter -k /tmp/iam_cert.key \
   -c /tmp/iam_cert.crt -u [AWS Account Number] -r x86_64 -e /tmp/
# exit # root から抜ける
```

# S3へイメージをアップロード
```
$ ec2-upload-bundle --location ap-northeast-1 -b [bucket_name/bundle_name] \
   -m /tmp/image.manifest.xml -a [access_key_id] -s [secret_access_key]
```

# AMIの登録
```
$ ec2-register [bucket_name/bundle_name]/image.manifest.xml \
   --region ap-northeast-1 -n [AMI name] \
   -O [your_access_key_id] -W [your_secret_access_key]

IMAGE ami-cXXXXXXXX
```
AWS ダッシュボードの

* EC2
  * IMAGES
    * AMIs

に作成した AMI が登録されているのを確認できればOK。

# おわりに
あとは作成した AMI を利用してインスタンスを作成すればよい。
ただし、t2.micro 等の EBS しか使えないマシンでは利用できないので、
その点には注意が必要。


# 参考文献
[Creating an Instance Store-Backend Linux AMI](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-instance-store.html)
[Instance Store-BackedのAMIをつくる](http://blog.kenjiskywalker.org/blog/2014/03/18/instance-store-backed-ami/)
Heroku へ HTTPS でデプロイする

昨年末に [Heroku](https://www.heroku.com/) が [HTTPS 経由での Git に対応](https://blog.heroku.com/archives/2014/11/6/announcing_http_git_beta) しました :clap:
これで SSH が通らない環境でもデプロイできますね :exclamation: 

最新の Heroku Toolbelt がインストールしている前提で話を進めていきます。


## 新しいアプリケーションを作る場合

#### 1. Heroku に新しいアプリケーションを作る。この際に `--http-git` を指定する。

```
$ heroku apps:create --http-git
Creating アプリケーション名... done, stack is cedar-14
```

#### 2. 新しい git レポジトリを作る

```
$ git init
```

#### 3. Heroku を git のリモートとして登録する。

```
$ heroku git:remote -a アプリケーション名
Git remote heroku added
```

#### 4. 確認する。

```
$ git remote show heroku
* remote heroku
  Fetch URL: https://git.heroku.com/アプリケーション名.git
  Push  URL: https://git.heroku.com/アプリケーション名.git
```

Fetch URL と Push URL が https で始まっていれば OK です :exclamation: 


## 既存のアプリケーションを SSH から HTTPS に変更する場合

#### 1. まずはこんな感じで SSH 経由になっているはず（git@heroku.com）

```
$ git remote show heroku
Fetching repository, done.
* remote heroku
  Fetch URL: git@heroku.com:アプリケーション名.git
  Push  URL: git@heroku.com:アプリケーション名.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (local out of date)
```

#### 2. `heroku git:remote --http-git` で変更しましょう。

```
$ heroku git:remote --http-git
Git remote heroku updated
```

#### 3. もう一度1のコマンドで確認すると…

```
$ git remote show heroku
* remote heroku
  Fetch URL: https://git.heroku.com/アプリケーション名.git
  Push  URL: https://git.heroku.com/アプリケーション名.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local ref configured for 'git push':
    master pushes to master (local out of date)
```

ちゃんと HTTPS になってますね:exclamation:
github.comへのSSH通信を爆速化する

`~/.ssh/config`に追記：

```
Host github.com github.*
  User git
  Port 22
  Hostname github.com
  Compression yes
  ServerAliveInterval 60
  TCPKeepAlive yes
  IdentitiesOnly yes
  ControlMaster auto
  ControlPath /tmp/%r@%n:%p
  ControlPersist yes
```

`github.hoge`みたいにして秘密鍵を使い分けていても混ざらずに使えました。

---

MavericksのHomebrewで入れた`openssh 6.7p1`でのみ確認していましたが
CentOS6上ではyumの最新`openssh 5.3p1`で`ControlPersist`は対応できますが`ControlPath`の`%n`表記に対応していないようでした。

```
Host github.com
  Identityfile ~/.ssh/id_rsa
  ControlPath /tmp/%r@github.com:%p
Host github.hoge
  IdentityFile ~/.ssh/id_rsa_hoge
  ControlPath /tmp/%r@github.hoge:%p
```

`ControlPath`項を個別にハードコーディングして対応。
リアルタイム為替レートをとってみた

最近、インベスターZというマンガに影響され投資に興味を持った。
証券口座作ってみたりして遊んでいると、FXの口座は開設するといくらかキャッシュバックがもらえるところが多いことに気づき、DMM.com証券とか開いてみた。

お仕事はプログラマをやっているということで、やっぱシステムトレードとかそういうの興味を持ってしまう。世の中には為替取引をREST APIで提供している企業があるらしい。APIがあるなら繋ぎたい。そう思うのがWebエンジニアである。(ﾀﾌﾞﾝ)

## OANDAというところがREST APIを提供している
最近サイトのリニューアルをしたらしい。
http://markezine.jp/release/detail/468817

口座開設しないとAPIたたけないんだろうなーと思っていたが、sandboxでは必要ないらしい。（※なお、ガチ環境でやるときは25万円入金している状態でアクセストークンの発行を行わないといけない。）

FXはキャッシュバックの半分が吹っ飛んでいる程度に負けているのであんまやる気しないんですが、為替レート、jsonで取れるならとってみたい。

## JavaのサンプルをScalaに書き換えてみた
javaのサンプルがここに。mavenとjavaがあれば動かせられる。
https://github.com/oanda/java-api-streaming

そんまま真似してscalaで書いてみた。
sbtがあれば動くはず。
https://github.com/oshiro-kazuma/oanda-scala-stream-api

## おっおっおっ
取れとる・・・
USD_JPYとEUR_JPYを取得してみた。

```json
sbt "run-main PriceStream"
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:30:09.099175Z","bid":142.564,"ask":142.584}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:30:38.746838Z","bid":114.86,"ask":114.874}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:30:41.068148Z","bid":114.859,"ask":114.875}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:30:42.749457Z","bid":142.564,"ask":142.585}}
{"tick":{"instrument":"USD_JPY","time":"2015-01-29T15:31:06.279973Z","bid":114.861,"ask":114.875}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.333618Z","bid":142.565,"ask":142.588}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.334019Z","bid":142.566,"ask":142.587}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.437200Z","bid":142.565,"ask":142.588}}
{"tick":{"instrument":"EUR_JPY","time":"2015-01-29T15:31:06.814322Z","bid":142.566,"ask":142.587}}
```

## そ、、それで・・・？
そ、、そそれだけです。

scalaでBufferedReaderをうまいこと回す方法を学べたのは良かったかと。

```scala
// print realtime prices
Stream.continually(br.readLine())
  .takeWhile(_ ne null)
  .filterNot(_.contains("heartbeat"))
  .foreach(println)
```

と思ったが、こっちのほうが断然良かった。

```scala
val bs: BufferedSource = Source.fromInputStream(entity.getContent)
bs.getLines()
  .filter(!_.contains("heartbeat"))
  .foreach(println)
```

初めは以下っぽく書いていたんですがscalaでコレは辛いかな、と思い。

```scala
var line: String = ""
while ({line = br.readLine()); line != null}) { // do something } 
```

# Dispatch使ったほうが3倍簡単でした

```scala
object Hoge extends App {

  import dispatch._, Defaults._
  import scala.concurrent.duration._

  val endpoint = "http://stream-sandbox.oanda.com/v1/prices?instruments=USD_JPY"
  val request = Http(url(endpoint) > as.stream.Lines(printer))

  def printer(line: String) = line match {
    case l if l.contains("heartbeat") => // nothing to do.
    case l => println(l)
  }

  Await.result(request, Duration.Inf)

}
```
lftpメモ


ftpしかつかえないサーバのファイルの転送に自動化にlftpを使った。
CUIのftpクライアントはどれがよいのかわからないけど、良いクライアントでした。

特にsyncコマンドが便利でした。

標準入力からコマンドを食わせてもうまくうごかせなかったのでファイルを生成して`lftp -f`で渡した。

host から dataディレクトリにのhost名のディレクトリに一旦保存して new_host へ転送する場合をerbでかいておく。

```
open -u <%= user %>,<%= pass %> <%= host %>
mirror . data/<%= host %>
open -u <%= new_user %>,<%= new_pass %> <%= new_host %>
mirror -R data/<%= host %> .
```

mirror だとダウンロードで mirror -R だとアップロードになるそうな。

`!vi`でローカルのファイルを操作してputするのも便利でした。

# lsがキャッシュされる

lftpのlsはキャッシュされるので複数人で同じ場所をみている場合は変更に気づかない場合があるので注意すること。

# 関連

* [man lftp](http://lftp.yar.ru/lftp-man.html)
Mac の Sublime Text 3 で SKK を快適に使う

*ここでは AquaSKK で発生した問題と解決方法を記載します。他の SKK ライクな IM などについては検証していません。*

# 問題

SKK の利用において、最も頻繁に使う機能の1つに「キャンセル」がある。デフォルトでは「キャンセル」は `ESC` あるいは `Ctrl+G` に割り当てられている。

一方、Sublime Text 3 では `Ctrl+G` は行番号指定ジャンプに割り当てられている。 Sublime Text は自身のアプリケーション内でのキーバインド設定を優先するため、 **SKK 側の `Ctrl+G` (キャンセル)が効かない。**

# 解決方法

まず、 default キーマップ用のファイルを作成する。

```sh
$ touch ~/Library/Application` Support/Sublime\ Text\ 3/Packages/Default/Default\ \(OSX\).sublime-keymap
```

次に、 default のキーマップを開く。
`Preferences -> Key Bindings - Default`
このキーマップの内容を先程作成した `Default (OSX).sublime-keymap` というファイルにコピーする。

最後に、 `Default (OSX).sublime-keymap` をエディタで開き、以下の行を削除(もしくは他のキーに変更)する。

```
	{ "keys": ["ctrl+g"], "command": "show_overlay", "args": {"overlay": "goto", "text": ":"} },
```

変更する場合は `"ctrl+g"` の部分を変更すれば良いが、複数キー入力の1つ目を `"ctrl+g"` にしてはならない。  
ダメな例）`["ctrl+g", "ctrl+l"]`

# 解説

問題を解決したいだけの人はここまでで十分である。以下に上記解決方法の詳細を解説する。

この手の問題に対して検索して出てくる方法として、 Sublime Text 3 の user のキーマップ上で `Ctrl+G` を無効にする、というものがある。

```
[
    { "keys": ["ctrl+g"], "command": "unbound" }
]
```

この設定を行うことで、 `Ctrl+G` を押しても行番号指定ジャンプのためのオーバーレイは表示されなくなる。しかし、 SKK 側には `Ctrl+G` は伝達されない。依然、キーマップ上でその入力は Sublime Text のものとして登録されているためだ。

そこで、 user のキーマップに追加するのではなく、 default のキーマップ上から `Ctrl+G` を削除することにする。これによって、 `Gtrl+G` は Sublime Text 上で握り潰されず、 SKK まで到達されるようになる。

ただ、 Sublime Text 3 では default のキーマップを表示することはできるが、そのまま編集することはできない(そもそも所定のディレクトリに対象のファイルが存在しない)。

そのため、所定のディレクトリに自らファイルを作り、 default のキーマップの内容をそのままコピーする必要がある。そうすれば、作成したファイルを参照するようになるので、編集も可能だ。やり方は既に書いた。