OmniAICreator/Qiita-1.07M huggingface dataset:
【iOS】URLを渡すだけで簡単にOGカードを表示する方法

## はじめに

TwitterやFacebookなどでよく下記のようなURLが埋め込まれたカードを見かけることがあると思います。
<a href="http://qiita.com/szk-atmosphere/items/a723a344d8c371e615ba"><img width="300" alt="スクリーンショット 2016-03-14 1.20.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/60325/d7d77307-7573-97f1-fdce-edbdb4d8a538.png"></a>
上記のカードは[Open Graph Protocol](http://ogp.me/)に準拠しているページのmetaタグから必要な情報を取得して表示されています。

このOGカードをiOSアプリ内でもURLを渡すだけで表示してくれるライブラリが[URLEmbeddedView](https://github.com/szk-atmosphere/URLEmbeddedView)です。
<a href="https://github.com/szk-atmosphere/URLEmbeddedView"><img src="https://raw.githubusercontent.com/szk-atmosphere/URLEmbeddedView/master/SampleImages/sample2.gif" width="200px"></a> <a href="https://github.com/szk-atmosphere/URLEmbeddedView"><img src="https://raw.githubusercontent.com/szk-atmosphere/URLEmbeddedView/master/SampleImages/sample.gif" width="200px"></a>

## 使い方

使い方は非常に簡単で、URLを渡すだけです。

```swift
let embeddedView = URLEmbeddedView()
embeddedView.loadURL("http://qiita.com/szk-atmosphere/items/a723a344d8c371e615ba")
view.addSubView(embeddedView)
```

そして、内部では取得したOG情報と画像を自動でディスクキャッシュしてくれるので、2回目以降の読み込みは自動でキャッシュからの取得になるため非常に読み込みが早くなります。
キャッシュからの読み込みでも、URL上記と同じように渡すだけで表示されます。

ちなみに、ページの最初にあったTwitterのOGカードと同じURLも以下のように表示されます。
<img width="300" alt="スクリーンショット 2016-03-14 1.43.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/60325/caa3fdc3-958c-51c4-ad11-164e8e483176.png">

### OGデータのキャッシュ

キャッシュからOG情報を自前で取得したい場合は、下記のコードを使うことで取得することができます。
ディスクにキャッシュされている場合はディスクからデータが読み込まれ、存在しない場合は自動で取得しにいきます。

```swift
let url = "https://github.com/szk-atmosphere/URLEmbeddedView"
OGDataProvider.sharedInstance.fetchOGData(urlString: urlString) { ogData, error in
   print(ogData)
}
```

一度取得したOGDataが次に更新されるまでの間隔を決めることができます。
デフォルト値は10日間になります。

```swift
OGDataProvider.sharedInstance.updateInterval = 10.days
```

### 画像キャッシュ

OG情報に紐付いた画像を自前で取得したい場合は、下記のコードを使うことで取得することができます。
ディスクにキャッシュされている場合はディスクからデータが読み込まれ、存在しない場合は自動で取得しにいきます。
~~必要なパラメータはURLだけではなく、`OGData`に含まれている`imageUUID`も必要になります。~~

```swift
OGImageProvider.sharedInstance.loadImage(urlString: urlString) { image, error in
    print(image)
}
/*
 * v0.2.0までの記法
 * let url = ogData.imageUrl
 * let uuidString = ogData.imageUUID
 * OGImageProvider.sharedInstance.loadImage(url: url, uuidString: uuidString) { image, uuidString, error in
 *     print(image)
 * }
 */
```

## 最後に

iOSでOGカードを表示してみたいときは、さくっと[URLEmbeddedView](https://github.com/szk-atmosphere/URLEmbeddedView)を試してみましょう!
LinuxコマンドTipsあれこれ（随時更新）

# 大量のファイルを削除する

* たとえばtmpディレクトリのファイルをすべて削除する場合など
* 通常の ```rm``` で削除すると ```引数リストが長すぎます``` と怒られる場合
  * 引数に渡せる総バイトを超えていることが原因

```bash
ls | xargs rm
```

* ```xargs``` を使うと、引数に渡せる限界ギリでコマンド発行、さらに繰り返しをしてくれる

# フォルダの中にあるファイルの数を数える

```bash
ls -l | wc -l
```

# ハードディスクの使用量を確認する

* 全体使用量

```bash
df -h
```

* 特定のフォルダ以下の使用量

```bash
du -sh ./usr
```

# 長いジョブを実行しないといけないが、ターミナルを閉じて帰りたい時

* 通常はコマンド叩いて実行中にターミナルを閉じるとジョブはstopされる
    * 帰りたい時もあるし、wifi切れて切断になっても止まってしまう

## これから実行しようという時

* ```nohup```を使うだけ
    * これだけで実行後はターミナルを閉じても処理は継続する

```bash
nohup hoge.sh
```

## もう実行してしまっている時

* 長いジョブ実行中のターミナルで ```ctrl + z``` を押す
    * これによりジョブが一時中断状態になり、別コマンドを受け付けるようになる
* ```bg 1``` を発行すると一次中断ジョブをバックグラウンドに回して再開させる
    * ```bg 1``` の ```1``` はバックグラウンドの１番目の意味で、複数あればインクリメント
* ```disown %1 ``` で自セッションのジョブでなくする
    * これをすることでターミナルを閉じてもジョブは継続するようになる


# ディレクトリがなかったらディレクトリを作成する（サブディレクトリも）

```bash
! test -d /hoge/fuga && mkdir -p /hoge/fuga
```

# 自分のシェル名を取得する

```bash
echo ${0##*/}
```

# catで出力する結果の最後に改行を付与する

* cat結果をリダイレクトすると改行つかないんだよなぁって時

```bash
function catln() {
  echo "$(cat $@)"
}

catln(hoge.txt) >> fuga.txt
```

# 相手サーバのポートが空いているか確認する

```bash
nmap -p 80 hoge.co.jp
```

# ディレクトリを再帰的に作成する

ネストしたディレクトリを一気に作成してくれる。
すでに存在するフォルダを指定してもエラーとしないでやってくれるのがいいところ。

```bash
mkdir -p ./test/test1/test2
```

braceを使って複数のディレクトリを一気に作成することもできる

```bash
mkdir -p ./test/{hoge,fuga,log}
```


# フォルダの圧縮、解凍

なんどやってもうろ覚えでtarに怒られる

```bash
tar zvcfp xxxxx.tar.gz [directory]
tar zvxfp xxxxx.tar.gz
```

なお、特定のフォルダを除外して圧縮するには ```--exclude``` を使えばＯＫ

```bash
tar zvcfp xxxxx.tar.gz --exclude [exclude directory path] [directory] 
```

# ssh(scp)でファイルをダウンロードする(鍵認証)

サーバからダウンドードするとして、クライアント側のターミナルで実行

> サーバにsshで接続してから実行するのではない

```bash
scp -i ~/.ssh/xxxxxxx.pem -r server_loginid@xxx.xxx.xxx.xxx:target_dir ./download_dir
```

# ディスク使用量を調べる

## 全体

```
df -h
```

```
Filesystem                          Size   Used  Avail Capacity iused      ifree %iused  Mounted on
/dev/disk1                         233Gi  148Gi   84Gi    64% 2901840 4292065439    0%   /
devfs                              184Ki  184Ki    0Bi   100%     637          0  100%   /dev
```

## 特定のディレクトリ配下

```du``` はいくつか使い方があるけど↓が個人的に一番使用頻度が高い

```
du -sh ./*
```

```
 38M	./cache
 16K	./certs
7.7G	./machines
```

# メモリ使用量が多い順にプロセスを表示

```
ps alx | awk '{printf ("%d\t%s\n", $8,$13)}' | sort -nr | head -10
```
> [参考](http://d.hatena.ne.jp/log4jk/20131127/p1)

# ユーザに所属グループを追加する

```
usermod -aG user group 
```

# 定期的に古いファイルを削除する

`cron` と `find` を使う古典的手法で。

```
# 毎日4時に実行
0 4 * * * find /path/to/log -name '*.log' -mtime +30 -delete
```

# ショートカット

## オリジナルファイルのバックアップ

`cp -p ~/hoge ~/hoge.org` とか書くことすらめんどい

```
cp -p ~/hoge{,.org}
```

## オリジナルファイルとのdiff

`diff -u ~/hoge.org ~/hoge` とか書くことすらめんどい

```
diff -u ~/hoge{.org,}
```

## mkdirしてすぐcdする

`$_` の意味はググってくださいませ

```
mkdir hoge && cd $_
```
レジストリ操作

## 新規作成メニューから削除
削除したいアプリケーションの拡張子からたどりShellNewを削除またはリネームする

#### Microsoft Publisherの削除
* HKEY_CLASSES_ROOT\.pub\Publisher.Document.15\ShellNew

#### Microsoft Accessの削除
* HKEY_CLASSES_ROOT\.accdb\Access.Application.15\ShellNew

#### 連絡先の削除
* HKEY_CLASSES_ROOT\.contact\ShellNew

#### Journalドキュメントの削除
* HKEY_CLASSES_ROOT\.jnt\jntfile\ShellNew
【JUnit】Date型の使い方

- Date型の使い方
- Calendarはなるべく使わない、可読性の損なわないJUnitの書き方を探る
- SimpleDateFormatもなるべく使わない

## String("yyyy-MM-dd")をsql.Date型に変換
```java:code
// java.sql.Date.valueOf(String s) を使用
// 時刻は00:00:00.000
java.sql.Date.valueOf("2099-01-01"); // 2099-01-01
```

## String("yyyy-MM-dd")をutil.Date型に変換
```java:code
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.format.DateTimeFormat;
import org.apache.commons.lang3.time.FastDateFormat;
// Thu Jan 01 00:00:00 JST 2099
// ■case1:DateUtils.parseDate(date, pattern) を使用
DateUtils.parseDate("2099-01-01", "yyyy-MM-dd");
/*
■case2:DateTimeFormat.parseDateTime(date).toDate()を使用
Exceptionが出ないのが良い
*/
DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime("2037-12-31").toDate();
// 時刻指定も可 Thu Jan 01 10:10:10 JST 2099
DateUtils.parseDate("2099-01-01 10:10:10", "yyyy-MM-dd HH:mm:ss");
// ■case3:FastDateFormat.parse(date)を使用
FastDateFormat.getInstance("yyyy-MM-dd").parse("2037-12-31");

```

## Date型(util.Date、sql.Date)をStringに変換
```java:code
// ■case1:DateFormatUtils.format(date, pattern) を使用
import org.apache.commons.lang3.time.DateFormatUtils;
DateFormatUtils.format(date, "yyyy/MM/dd hh:mm:ss"); // 2099/01/01 00:00:00
// ■case2:FastDateFormat.format(string)を使用
FastDateFormat.getInstance("yyyy-MM-dd").format(date);
```

## その他、util.Date型に変換
```java:code
// DateTimeコンストラクタからDate生成
// Fri Jan 02 03:04:05 JST 2099
new DateTime(2099, 1, 2, 3, 4, 5).toDate();

```

## JUnitの評価
```java:JUnitcode
// 時間は無視して、同日か比較
assertTrue(DateUtils.isSameDay(actual.getDate(), DateUtils.parseDate("2099-01-01", "yyyy-MM-dd")));
// 完全一致を比較
assertThat(actual.getDate(), is(DateUtils.parseDate("2099-01-01 10:10:10", "yyyy-MM-dd hh:mm:ss")));
```
Expand-html HTMLの拡張という発表を聞いた時のメモ

## 前置き

htmlの属性には元々**role(役割)**というものがあり、それを拡張するものとして**WAI-ARIA**というものが定義されている。

# WAI-ARIA

アクセシブルでリッチなアプリケーション作成に関する仕様を定義する。**ホスト言語に不足している要素を拡張**する*補助輪*のようなもの

#### ホスト言語
    SVGやマークアップ言語のこと

## 不足しているものって？

+ 役割
+ ステート
+ プロパティ

## どうやって拡張してるの？

JS（HTMLの取得）
↓
DOMツリーの生成
↓
アクセシビリティAPI（**WAI-ARIA**など）
↓
支援技術（アクセシビリティAPIを使用できるアプリケーション）
例）Slack,Facebookなど

## 使い方

### 役割(role)

要素の役割を定義する
メニューに**何が**あるのか・**いくつ**あるのかなどを伝える
_静的に使用する_

### ステート・プロパティ(aria)

要素sの状態を定義する
setattributeなどで**開いている・閉じている**などを伝える

## 実装上の注意点

- 無理して使わない
- 元々のやり方（属性など）を変更しない（上書きしない）
- デフォルトのものとの暗黙の衝突を防ぐ

## デバッグツール

- chrome-accesibility developer tool
- firefox-dom inspecter
- vin-viewer
- cssでセレクタを用いてスタイルを変更する
- dipslay-wai-aria

# Micromedia

**itemscope**でアイテムを作り、**itemtype**で定義する
目的や環境に応じて仕様を参照し、拡張する

## ここまでして、HTMLを拡張する意味は？

- **リッチスニペット**

#### リッチスニペット
    Google検索を例にとって説明すると、
    検索結果の中に存在する「食べ物のサイトにおける食べ物の画像」や
    「サイト内検索ができる検索窓」、「商品の場合に存在するレビュー」などを表示する技術のこと

- **AMP**にも対応

#### AMP
    Accelerated Mobile Pageのこと。
    表示に時間がかかるページを（モバイルからに限るが、）高速に表示するために定義されたフォーマット。

- WebサイトをAPI化できる

## どういうものなの？何が違うの？

- **Microdata**　→HTMLの記法
- **schema.org**　→語彙
- **Google rich snipet** 　→Googleのオリジナル仕様
HTML5のAPIをひたすら叩いてみた記録という発表のメモ


# ストレージ系API
Cookieの代わりに**クライアントサイドにデータを保持**する。
Twitter,Amazon,Facebookなどの**ハイブリットアプリ**に使える。

## Web Strage
**手軽**・キーバリュー型
##  Index DB
**DB寄り**・高機能なDB
## WebSQL
Web上でSQLを使うことができる
SQLiteの仕様に依存していたため、**廃止されてしまった**。

# WebRTC (Web Real-Time Communication)
**ブラウザ同士**での**リアルタイム通信**を行うためのAPI
_※IE、Safariでは使えない_
通信時は完全に**クライアント間**のみだが、**シグナリング**というクライアント間を接続する処理にサーバーが必要となる。
必要なスキルの幅が広く、ビジネス向けに実装するにはハードルが高い。

## ラップ技術
WebRTCをある程度容易に実装できるようにラップ技術が登場している
 + NTT :  Skyway
 + Pear.js

#### 実装例
+ appear.in : ブラウザでビデオ音声チャットができるアプリケーション

# Web Notifications
クライアントにブラウザなどから**通知を送信する**API。

# APIを使う上での注意点
APIや拡張機能に対応している率が高いのは基本的に
**PC(Chrome,FireFox)>PC(その他)>Android(Chrome)>iOS**
となっている。
このため、すべてのOS、環境に対応したものを作りたければ、iOSに基準を置き、iOS上で使える機能やAPIを基準にシステムを作るべきである。
また、ローカルでは無視されるが、**SSL上でしか使えない機能**もあるため、**HTTPS環境**での開発をおすすめする。
スタートアップにおけるソフトウェア品質をいい感じに担保する方法

※本文は個人の見解であり、所属する組織の公式見解ではありません。

# 対象
* サービスを立ち上げ時で本当に猫の手も借りたいぐらいクソ忙しい状態の中でエンジニアリングしている人
* もはや業務範囲がエンジニアリング以外のものも担当しながら開発をしている人
* test(unit test,E2Eテスト)が重要な事は知ってるが、本当に時間がなくやむなく置き去りにしている人
* 期間限定のサービスではなく、ヒットすれば長期間運用するサービス開発をする場合


# 過去を振り返ると
いろいろとご意見はあると思うが、主に下記の２パターンが多かったのではないかと思っている

## 過去のパターン1（スピード重視）
はじめはとにかく、テストはあまり考えずにサービスの立ち上げに集中して、ある程度シェアを獲得した段階で一度立ち止まり、リファクタ/リプレイス/テストを書いていくパターン

* メリット
 * とにかく機能のリリースを優先して、先行者メリットで市場のシェアを獲得できる
 * ビジネスとしてある程度成り立たせることが優先でき、その後のロードマップがひきやすい

* デメリット
 * 技術的負債はたまり続ける。時には技術的負債で新規機能開発の妨げになる場合もある 
 * 途中でjoinしたエンジニアは初め苦しむ。。。

## 過去のパターン2（品質[意図した動作を保証するという意味の品質]重視）
テスト駆動開発的にやはりテストはありきで開発を進めるパターン

* メリット
 * バグの件数や技術的な負債は少なくて済ませられる
 * 安定的に新規機能開発が進み、スケールしやすい
 
* デメリット
 * 立ち上げスピードがどうしても遅くなるので先行者メリットが薄れる 
 * ビジネス判断としてサービス終了となる可能性が少々高くなる


# 過去を踏まえつつ、最近っぽく、良い感じ（スイードも重視しつつ、品質も...）にするには
## オススメパターン
はじめにエラーログを収集・集計する仕組みだけを導入し、testコードは一度忘れ、サービス立ち上げの開発に集中する
エラーが発生しているパターンが集計され、集計値の多いものから随時バグフィックスしていくことで改善効果が高くなり、品質と新規機能開発がうまく回り始める。

### 具体的にはこんな感じ
![error_log管理.png](https://qiita-image-store.s3.amazonaws.com/0/106937/07ce2831-649f-c91a-c06b-c72122812947.png)

* APサーバにFluentのエージェントをインストールして、フレームワークのログ、Nginxのログ、アプリサーバのログをtailして集約サーバへ送る
* Fluentの集約サーバはそのまま、Elasticsearchに投げてインデックスさせる
* Kibanaからエラーログをいい感じに集計して、グラフ等で見える化する
* DBサーバのスロークエリとかもFluentエージェントでtailしても良い
* fluentやelasticsearch,kibanaというプロダクトが無料で出てきて、且つ低コスト（手間のコスト）で導入することが可能になった今だから出来ることであり
開発者の皆さんには感謝感謝です。

### 他にも細かい部分を言うと
* 静的型付言語を選択することで無駄なシンタックスエラーが回避できたり
* IDEを大いに活用してケアレスミスを事前に防げたり


# まぁでも一番大切な事
## サービスの市場におけるなんとなくの**立ち位置を客観的に把握**する事
リリース優先をしてスタートダッシュしてある程度成功をおさめた後、少し立ち止まりリファクタorリプレイスを繰り返し再度スタートダッシュをする事で成功するすパターンもあれば、逆に少し立ち止まってる間に他者に追い越される場合もある。

また立ち上げスピードが遅く、そもそもビジネスとして成り立たなかったパターンもある。

いずれにしてもビジネスとして成り立たないと全ては無くなるので客観的な立ち位置を常に考えてその時に必要な手立てを行う。

## 完璧を求めない
test code やE2Eテストを書き始めるとカバレッジを取得しながらやると思います。
数値で定量化されるのでどうしても100％を求めがちなるが、100%でないゴールを設定して保つ目標にすべし。
WEBアプリケーションであれば、サービスの内容にもよるが80%程度が丁度良いと思っている。
css3のプロパティ、filterとmix-blend-modeを使ってみたらすごかった。

# `filter`と`mix−blend−mode`
instagram風の画像編集ができる、[CSSgram](http://una.im/CSSgram/)というcssフレームワークが話題になっています。
css3の`filter`と`mix-blend-mode`というプロパティを使うとCSSのみで画像を編集することができ、雰囲気や仕上がりをガラリと変えることができます。
結構細かい機能が実装されていて、簡単な加工のみならphotoshopなど使わずに簡単に出来てしまいます。

自分の勉強も兼ねて画像ジェネレーターサイトを作成しました。

[CSS filter and mix-blend-mode Generator](http://www.sottar.net/filter-generator/)
![ScreenShot.png](https://qiita-image-store.s3.amazonaws.com/0/63056/6a3c032e-2406-6c76-1aed-9a6a1659932b.png)

[コード(github)](https://github.com/sottar/filter-generator)

## こんな加工がCSSのみで出来てしまいます。
元画像
<img width="249" alt="london_default.png" src="https://qiita-image-store.s3.amazonaws.com/0/63056/b70ed402-cfba-6403-51e7-1132dd2d051c.png">

加工1
<img width="250" alt="london_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/63056/fdd9c30d-725b-7ca2-73f3-9cab9a0d73e9.png">

```css
#image_after {
  filter: grayscale(100%) sepia(30%) brightness(110%) contrast(110%) ;
  -webkit-filter: grayscale(100%) sepia(30%) brightness(110%) contrast(110%) ;
  -moz-filter: grayscale(100%) sepia(30%) brightness(110%) contrast(110%) ;
  -o-filter: grayscale(100%) sepia(30%) brightness(110%) contrast(110%) ;
  -ms-filter: grayscale(100%) sepia(30%) brightness(110%) contrast(110%) ;
}
```

加工2
<img width="250" alt="london_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/63056/d0fd33e5-8dcf-61f2-f13a-3a1dab617bd5.png">

```css
#image_after {
  filter: brightness(90%) contrast(150%) ;
  -webkit-filter: brightness(90%) contrast(150%) ;
  -moz-filter: brightness(90%) contrast(150%) ;
  -o-filter: brightness(90%) contrast(150%) ;
  -ms-filter: brightness(90%) contrast(150%) ;
}
#image_after::before {
  background: rgba(112,58,22,1);
  mix-blend-mode: screen;
}
```

これらの画像加工がCSS数行で出来てしまいます。

## filterの機能一覧

それぞれ設定できるオプションがあり、それらについて簡単に説明します。

|名称(en)|効果|初期値|
|-------|-------|-------|
|blur|ぼかし|0px|
|grayscale|モノクロ|0%|
|sepia|セピア|0%|
|saturate|彩度|100%|
|hue-rotate|色相回転|0deg|
|invert|階調反転|0%|
|opacity|透明度|100%|
|brightness|明るさ|100%|
|contrast|コントラスト|100%|

## mix-blend-modeの機能一覧

|名称(en)|名称(ja)|効果|
|-------|-------|-------|
|darken|比較(暗)|上下の画像を比較して暗いピクセルが表示される|
|lighten|比較(明)|上下の画像を比較して明るいピクセルが表示される|
|multiply|乗算|暗い表現を作るときに使う描画モード|
|color-burn|焼きこみ|乗算よりもより暗くなる描画モード|
|screen|スクリーン|明るい表現を作るときに使う。かなり使える|
|color-dodge|覆い焼き|スクリーンよりもより明るくなる。インパクトが得られるのでエフェクト作成時などこれもかなりよく使う|
|overlay|オーバーレイ|乗算とスクリーンの両方に近い効果が得られる。コントラストがあがるため見栄えの印象が上がる|
|soft-light|ソフトライト|明るい部分はさらに明るく、暗い部分はされに暗くする|
|hard-light|ハードライト|ソフトライトよりも強い効果が得られる|
|difference|差の絶対値|二枚の画像の違いを可視化するのに役立つ|
|exclusion|除外|差の絶対値よりも弱い効果が得られる|
|hueHSL|色相|色空間で合成。下位レイヤーの輝度(L)と彩度(S)、上位レイヤーの色相(H)を持つカラーが得られる|
|saturationHSL|彩度|色空間で合成。下位レイヤーの輝度(L)と色相(H)、上位レイヤーの彩度(S)を持つカラーが得られる|
|colorHSL|カラー|色空間で合成。下位レイヤーの輝度(L)、上位レイヤーの彩度(S)と色相(H)を持つカラーが得られる|
luminosityHSL|輝度|色空間で合成。下位レイヤーの彩度(S)と色相(H)、上位レイヤーの輝度(L)を持つカラーが得られる|

filterについてはこのサイトに詳しく説明がありました。
http://blog.asial.co.jp/979
Java-Python文字列操作対比

Java8とPython3の基本的な文字操作の対比です。

###文字列の一致
|Java|Python|結果|
|----|------|----|
|"abc".equals("abc")|'abc' == 'abc'|True|


###文字列の長さ
|Java|Python|結果|
|----|------|----|
|"abcde".length() |len('abcde')|5|

###文字列の一部
|Java|Python|結果|
|----|------|----|
|"abcde".substring(1)  |'abcde'[1:]|'bcde'|
|"abcde".substring(0,2)|"abcde"[:2]|'ab'|
|"abcde".substring(1,4)|'abcde'[1:4]|'bcd'|
|"abcde".substring(0,"abcde".length()-2)|'abcde'[:-2]|'abc'|

###指定された文字の最初の位置
|Java|Python|結果|
|----|------|----|
|"abcde".indexOf('d')|'abcde'.find('d')|3|
|"abcde".indexOf('X')|'abcde'.find('X')|-1|

###文字列が指定されたprefixで始まるか
|Java|Python|結果|
|----|------|----|
|"abcde".startsWith("abc")|'abcde'.startswith('abc')|True|
|"abcde".startsWith("bcd")|'abcde'.startswith('bcd')|False|

###文字列が指定されたsuffixで終わるか
|Java|Python|結果|
|----|------|----|
|"abcde".endsWith("de")|'abcde'.endswith('de')|True|
|"abcde".endsWith("cd")|'abcde'.endswith('cd')|False|

###文字列が指定された文字列を含むか
|Java|Python|結果|
|----|------|----|
|"abcde".contains("bcd")|"bcd" in "abcde"|True|
|"abcde".contains("ae")|"ae" in "abcde"|False|

###文字列 to 数値
|Java|Python|結果|
|----|------|----|
|Integer.parseInt("1")+2|int('1')+2|3|

###数値 to 文字列
|Java|Python|結果|
|----|------|----|
|String.valueOf(1)+"2"|str(1)+'2'|'12'|
|String.valueOf(1)+2|str(1)+2|Pythonではエラー|

###文字列の分割
|Java|Python|結果|
|----|------|----|
|"a,b,c".split(",")|'a,b,c'.split(',')|['a', 'b', 'c']|

###文字列の結合
|Java|Python|結果|
|----|------|----|
|String.join(",", new String[]{"a","b","c"})|",".join(['a', 'b', 'c'])|'a,b,c'|

*Java7までなら*

```
import org.apache.commons.lang3.StringUtils;

StringUtils.join(new String[]{"a","b","c"},",")
```

##ドキュメントリンク

あとはここで調べる

Java8 [クラスString](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html)
Python2系 [「3.6.1 文字列メソッド」](http://docs.python.jp/2.5/lib/string-methods.html)
Python3系 [「4.7. テキストシーケンス型」](http://docs.python.jp/3/library/stdtypes.html#text-sequence-type-str)

## 改定履歴
2016/3/14 初版 
2016/3/15 equals,startsWith,endsWith,containsを追加
BYOP > Application > Letters to you 10 years later v0.1


This article is for my hackaday.io project (BYOP).
https://hackaday.io/project/9526-bring-your-own-pizero-byop

## Message holding duration

The message station store the messages in the Flash.

According to the datasheet of some Flash product, the Flash may have the ability to hold the message for 20 years (or less).

[Datasheets of some Flash product @ spansion](http://www.spansion.com/Support/Datasheets/S25FL128S_256S_00.pdf)

> Data Retention
> - 20 Year Data Retention typical


## Letters to you 10 years later

You can store letters to you 10 years later into the message station.

The procedure is same as in [Application > Message to your friends / family v0.1](http://qiita.com/7of9/items/c301422dfbd096b07302). 

After the post of the message, you may keep the message station in your tool box or somewhere for the long journey.
結合(SQL)


##デカルト結合(Cartesian join)

デカルト積(Cartesian)
直積(cross product)
クロス結合(cross join)
無結合(no join)
とも呼ばれることがある

```sql:SQL
SELECT テーブル名1.列名1,テーブル名2.列名2
FROM テーブル名1
CROSS JOIN
テーブル名2 
```

テーブル１のすべての行とテーブル2のすべての行を交差させたものを返す
(テーブル1の行数*テーブル2の行数の行が返る)

##内部結合

```sql:SQL
SELECT テーブル名1.列名1,テーブル名2.列名2
FROM テーブル名1
	INNER JOIN
	テーブル名2
ON 条件; 
```
条件の中の比較演算子を用いて、2つのテーブルのレコードを結合する

###自然結合

```sql:SQL
SELECT テーブル名1.列名1,テーブル名2.列名2
FROM テーブル名1
	NATURAL JOIN
	テーブル名2;
```

列名1と列名2の名前が同じ時
テーブル名1.列名1=テーブル名2.列名2
の条件で内部結合される

##サブクエリ

クエリの中にクエリを埋め込むこと
基本的にサブクエリが返せるのは１つの列の１つの値だけ
(例外としてWHERE句のIN演算子のような複数の値を要求する場合のみ１つの列の複数の値を返す)

###分類

非相関サブクエリ
(外部クエリの何も参照にしていない場合)
相関サブクエリ
(内部クエリが外部クエリに依存している場合)

###利用できる箇所

SELECT句
SELECT文の列リスト
FROM句
HAVING句

###例１(SELECT文の列リスト・非相関サブクエリ)

```sql:SQL
SELECT テーブル名1.列名1,テーブル名2.列名2,...
FROM テーブル名1
	NATURAL JOIN
	テーブル名2
WHERE テーブル名1.列名1 IN (SELECT 列名3 FROM テーブル名3);
```

テーブル名3の列名3に含まれるものからテーブル名1の列名1に一致するものを条件とし、抽出する
この場合、1つの列の複数の行を返す

###例２(SELECT文の列リスト・相関サブクエリ)

```sql:SQL
SELECT テーブル名1.列名1,...,
(SELECT 列名2 FROM テーブル名2 WHERE テーブル名1.列名3 = テーブル名2.列名2)
FROM テーブル名1;
```

SELECT文の１つの列として使える
この場合、１つの列の１つの行を返す
テーブル名１の列名3の値を参照としている

###EXISTS

相関クエリとともに使われる

```sql:SQL
SELECT テーブル名1.列名1,テーブル名1.列名2,...
FROM テーブル名1
WHERE EXISTS
(SELECT * FROM テーブル名2 WHERE テーブル名1.列名1 = テーブル名2.列名2);
```

(テーブル名１・列名１)が(テーブル名2・列名2)に少なくとも１回は現れるテーブル1のデータを返す

```sql:例
SELECT mc.first_name firstname, mc.last_name lastname, mc.email email
FROM my_contact mc
WHERE EXIST
(SELECT * FROM contact_interest ci WHERE mc.contact_id = ci.contact_id);
```

my_contactテーブルのcontact_idがcontact_interestテーブルのcontact_idに存在するデータを返す

##外部結合

###LEFT OUTER JOIN(左側外部結合)

```sql:SQL
SELECT テーブル名１.列名１, テーブル名２.列名２, ...
FROM テーブル名１
LEFT OUTER JOIN テーブル名２
ON 条件;
```

左側のテーブル(テーブル１)のすべての行を右側のテーブル(テーブル２)の行と合致させる
INNERJOINとの違いは合致するものがあるかないかに関わらず全ての行を返す為
合致しない場合右側のテーブル(テーブル２)の列はすべてNULLを返す

###RIGHT OUTER JOIN(右側外部結合)

```sql:SQL
SELECT テーブル名１.列名１, テーブル名２.列名２, ...
FROM テーブル名１
RIGIT OUTER JOIN テーブル名２
ON 条件;
```
LEFTOUTERJOINと逆
右側のテーブル(テーブル２)のすべての行を左側のテーブル(テーブル１)の行と合致させる
合致しない場合左側のテーブル(テーブル１)の列はすべてNULLを返す

##自己結合

```sql:SQL
SELECT as１.列名１, as２.列名２
FROM テーブル名1 AS as1
INNER JOIN テーブル名1 AS as2
```

同じテーブルで結合をする

###自己参照外部キー(self-reference foreign key)
同じテーブル内の別の目的で使われるテーブルの主キー

##UNION

複数のクエリの結果を同じ列に結合する
(縦に結合する)

規則
各SELECT文の列数が、一致しなければならない
各SELECT文に対して、式や集約関数も同じでなくてはならない

###UNION

```sql:SQL
SELECT 列名１ FROM テーブル１
UNION
SELECT 列名2 FROM テーブル2
UNION
SELECT 列名3 FROM テーブル3
[ORDER BY 列名];
```

重複値は取り除かれる

###UNION ALL

```sql:SQL
SELECT 列名１ FROM テーブル１
UNION ALL
SELECT 列名2 FROM テーブル2
UNION ALL
SELECT 列名3 FROM テーブル3
[ORDER BY 列名];
```
重複値は取り除かれない

###INTERSECT

```sql:SQL
SELECT 列名１ FROM テーブル名１
INTERSECT
SELECT 列名２ FROM テーブル名２
```

テーブル名１の列名１とテーブル名２の列名２の重複値のみを返す

###EXCEPT

```sql:SQL
SELECT 列名１ FROM テーブル名１
EXCEPT
SELECT 列名２ FROM テーブル名２
```
テーブル名１の列名１に含まれテーブル名２の列名２に含まれない値を返す

##参考

Head First SQL 8章 9章
技術英語 > I'll tell you what @ Voyager / Tell you what @ Fullhouse

@ Star Trek Voyager > MANEUVERS

トレスと Janeway が議論しているなか Janeway が

> I'll tell you what...

字幕はきちんと訳がついていなくて

> でも今は...

http://ejje.weblio.jp/content/tell+you+what
>あのね(いい話がある).

<hr>
フルハウスでミシェルがジェシーおいたんに対して

> Tell you what...

この時は以下の字幕がついていた。

> あのね

<hr>

Voyagerでの使われ方（I'llをつけた場合）は少し丁寧になるのかもしれない。

襟を正す時、あるいは、間を置く時、などに使えるのかもしれないが未消化。

「いい話がある」という意味を使うのかもしれない。
ペーストしたらインデントがずれてしまった時の対処法


vimでペーストしようとしたら、インデントがずれてしまうことってよくありますよね。
対応方法をよく忘れるので自分のためにも書いておきます。

ペースト前

```
# -*- coding: utf-8 -*-

class testclass:

    def __init__(self):
        print("create testclass", end="")

    def testmethod(self,str):
        print(r"call \testmethod")
        print(str)
```

ペースト後

```
# -*- coding: utf-8 -*-

class testclass:

        def __init__(self):
                    print("create testclass", end="")

                        def testmethod(self,str):
                                    print(r"call \testmethod")
                                            print(str)
```

## 解決策1 - set paste

ペースト前にこれを入力すれば、そのままペーストできます。

```
:set paste

# こんな表示になる
-- INSERT (paste) --
```

モードを元に戻したい時はこれ。

```
:set nopaste
```

以下、 @D4prog さんのコメントより。

```
:set paste!
```
を使えば、履歴で再度 ```:set paste!``` を打てば  元のモードに戻れる。簡単！

## 解決策2 - gg=G
@okamos さんにコメントしてもらった内容。
貼り付け後に以下を実行すればいい感じに整形されます。
こっちのほうが手間が少なくて良さそう。

```
gg=G
```

以下、簡単な説明。  

| figure | description |
| ----- | ----- |
| gg | 1行目へ移動 |
| =X | 現在の行からX行までを整形する |
| G | 末尾 |

しかし残念ながら私が普段よく使うpythonだとうまく反映されない模様。
pythonは括弧がないから難しいんでしょうね。。
modern.IEでVimeoが動かなくて焦ってる方へ

#modern.IE（Win7 / IE9）環境にて焦ってた
modern.IEでVimeoが「あなたのブラウザはサポートしていません」的なメッセージが表示され焦っていた。
もしやと思って、Flashゲームの「寿司打」のページへ行き、確認すると、エラーメッセージさえも出てこない。

念の為にFlash Playerをインストールしてみると、問題なくmodern.IE環境でVimeoの再生ができますた。

これだけの投稿です。笑
Windows7 Enterprise(64bit)からWindows10への無償アップグレード


regedit.exe で下記の4箇所を編集
EnterpriseをProfessionalに

```
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
  ProductName: Windows 7 Professional
  EditionID: Professional

HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion
  ProductName: Windows 7 Professional
  EditionID: Professional
```

その後、再起動せずにWindows7 Professionalへアップグレード。

その後、Windows10アップグレードプログラムを起動する。
Electronでのクローラ開発

ElectronってChromiumベースなので、クローラ開発にも使えるのではないかと試行錯誤してみる。
都度加筆する予定。

```main.js
  mainWindow = new BrowserWindow({
    preload: path.resolve(path.join(__dirname, 'preload.js'))
  });
```

こんなふうに書くと、ページ遷移する度に[preload.js]が実行されるようになる。

##画面制御

###URLベースでやってみる
```preload.js
window.onload = function(){
  if(location.href=="https://search-engine.co.jp"){
    //検索画面での処理
    $('#search-box').val('ことり')
    $('#search-form').submit()
  }else if(~location.href.indexOf('https://www.search-engine.co.jp/search?')){
    //検索結果での処理

    //中略

    ipcRenderer.send('writeCSV',result);
  }
}
```

他にもDBとかファイルとかlocalStorageとかに状態をもたせたりして制御もできそう。


##プロキシ
```main.js
app.commandLine.appendSwitch('proxy-server','xxx.xxx.xxx.xxx:80');
```

こんな感じで設定はできる。BrowserWindow毎にプロキシサーバを指定したい場合はどうするんだろう...
LPC810の割り込みハンドラをアセンブリで書いてハマった

# はじめに
## Disclaimer
この挙動がどの仕様で規定された物なのか確認してません。中の作りを想像するにCortex-M0+共通の仕様な気がしていますが、もしかしたらNXP社製のCortex-M0+系に特有の挙動かもしれませんし、LPC810のみの仕様かもしれません。

## tl;dr
割り込み復帰に```mov pc, lr```使うとhardware faultで死ぬので注意しましょう。

## とか書くと
割り込みからの復帰が普通のリターン命令じゃ駄目とか当たり前じゃね？というのが普通のおじさんの反応です。でもCortexは違うんだよ、というのがARMおじさん達の言い分。ちなみに正しい書き方は

```
bx lr
```

または

```
push {lr}
pop {pc}
```

後者はスタックをちょっと汚すだけで意味はまったく同じ。中で別の関数呼んでる時は（lrが壊れるので）後者のペアをprologとepilogに書くのが普通。

# 何が起きているのか
## Cortex-M0+の割り込み
[ChaN大先生](http://elm-chan.org/index_j.html)が[32ビットへの誘い](http://elm-chan.org/junk/32bit/report.html)で詳しく説明している事の繰り返しですが、Cortex-M0+は割り込みが発生すると、caller saveレジスタと一部のシステムレジスタをユーザプログラム走行時のスタックに自動退避し、lrレジスタに特殊なアドレスを積んで割り込みベクタに書かれたアドレスに飛んできます。

この特殊なアドレスと言うのは、自分が見た値は```0xfffffff9```だったので、だいたいそんな感じの値だと思って下さい。Cortex-M0+のメモリモデルではコードやデータに使ってはいけないとされている領域なので、このアドレスへのジャンプは通常発生しません。

戻る時はこの特殊なアドレスにジャンプすれば、CPUがスタックに積んだはずのデータを使って割り込みからの復帰処理を自動的に行います。

ようするに割り込み発生時には、C言語の関数呼び出しの規約をハードウェアで処理してくれます。その結果普通に書いたCの関数が割り込みベクタに直接登録できるという、変なところで気の利いた仕様なのです。

## 落とし穴
で、この特殊なアドレスへのジャンプによる復帰ですが、どうも単に復帰すれば良いわけではないようで、popを使ってpcに書き戻して上げる必要があるようです。コンパイラは通常prologでcallee saveレジスタやら特殊レジスタをpushして、epilogでpopするというコード書くので、まずこの制限でひっかかる事はありません。

アセンブリで書く場合にもbl命令による関数呼び出しがlrレジスタを破壊するため、普通は最初にlrもpushして、最後にまとめてpcにpopで流し込んでリターンするのが普通です。

が、本当に簡単な処理だけして戻る場合には、そのまま```mov pc, lr```とか書きたくなるのが人情というもの。うっかりこちらで書くと特殊アドレスに本気でジャンプしてhardware faultを起こすようです。

movとpop両方に手を入れたくなかった、という気持ちはわからなくもないけど。緩い条件で公開されてる資料には割り込み周りの事情はほとんど書かれていないので、ちょっとこれは辛かった。

# おまけ
## 調査方法
Serial Wire Debug使いました。SWD用の機器を持ってないので困ったなー、とか思ってたら部屋にトラ技2014年3月号が転がってました。部屋の在庫部品で付属基板を組み立てて2月号のCD-ROMからCMSIS-DAPのファームを書き込み。これでLPCXpressoからSWDを使った書き込みとデバッグができるようになります。CMSIS-DAP自体はHIDとして見えるので特別なドライバは不要。Linux版でも問題なく動いてます。

もともとLPCXpressoでC言語使って開発してた人はこれだけでばっちり。自分はarm-none-eabi-gcc使ってアセンブラだけで開発してたので、ちょっと特殊な設定が必要でした。

- New ProjectからC ProjectとしてProjectを作成
- 自動生成されたソースファイルは即削除して、元々のソース一式をsrc以下にコピー
- makeは元々自分で用意してたものは使わずにIDEの自動生成にお任せ
- Propertiesから```C/C++ Build>Settings>Tool Settings>MCU Assembler>General>Include paths (-I)```を選んでアセンブリ用のインクルードパスを（srcに）設定
- 同```C/C++ Build>Settings>Tool Settings>MCU Linker>Managed Linker Script```を開いて```Managed linker script```からチェックを外して```Linker script```に自分のLinker scriptを設定

これでLPCXpressoからBuild/Debugメニューを使ってアセンブリのコンパイル＆リンクとCMSIS-DAP経由のデバッグができました。ソースファイル上でブレイクポイント設定したり、実行止めた時に自動でソース開いたりと、期待した以上に「普通に」動いてます。

ここで普通にCのソースとか追加すれば、crtに依存しない限りは普通(?)に混ぜて使えます。今回は問題の例外ハンドラを試しにCで書いてみたら、他の部分は変えずに動くようになったので、コンパイル版と手書き版の差を詰めていって問題に気づいた感じです。やっぱりキモいですよね、基本アセンブリで例外ハンドラだけCのコードとか。

割り込みベクタで使ってないとこにはダミー関数のアドレス入れてブレイクポイント張っておくと予期しない例外が起きている時に気づけて良いかと思います。今回も最初から張ってたんですが、それでhardware faultに気づきました。

## ```mov pc, lr```の制約
どうやらmovの場合にはARM/Thumbモードの切り替えも発生しないようで。海外のフォーラムで[ARMのドキュメント](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0040d/ch07s02s02.html)が紹介されてました。

>Note
You must use a BX lr instruction at the end of the ARM subroutine to return to the caller. You cannot use the MOV pc,lr instruction to return in this situation because it does not cause the required change of state.

これはThumbから呼ばれたARMコードのリターンについて言ってますが、割り込みについても似たような制限があるのでしょう。
Solutions of install RMagick on Mac OSX

# Problem

* System: Mac OSX

Installing ```RMagick``` gems for ruby, get error:

```shell-session
yukis$ gem install rmagick
/Users/yukis/.rvm/rubies/ruby-1.9.3-p362/lib/ruby/1.9.1/yaml.rb:56:in `<top (required)>':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
	ERROR: Failed to build gem native extension.

        /Users/yukis/.rvm/rubies/ruby-1.9.3-p362/bin/ruby extconf.rb
checking for /usr/local/Cellar/apple-gcc42/4.2.1-5666.3/bin/gcc-4.2... yes
checking for Magick-config... no
checking for pkg-config... yes
Package MagickCore was not found in the pkg-config search path.
Perhaps you should add the directory containing `MagickCore.pc'
to the PKG_CONFIG_PATH environment variable
No package 'MagickCore' found
checking for outdated ImageMagick version (<= 6.4.9)... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
	--with-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/yukis/.rvm/rubies/ruby-1.9.3-p362/bin/ruby


Gem files will remain installed in /Users/yukis/.rvm/gems/ruby-1.9.3-p362/gems/rmagick-2.15.4 for inspection.
Results logged to /Users/yukis/.rvm/gems/ruby-1.9.3-p362/gems/rmagick-2.15.4/ext/RMagick/gem_make.out
```

# Solution

1. check ```pkg-config``` (or reinstalling it)
2. run

```shell-session
C_INCLUDE_PATH=/usr/local/Cellar/imagemagick/6.9.2-6/include/ImageMagick-6 PKG_CONFIG_PATH=/usr/local/Cellar/imagemagick/6.9.2-6/lib/pkgconfig gem install rmagick
```

# Reference

http://stackoverflow.com/questions/9050419/cant-install-rmagick-2-13-1-cant-find-magickwand-h

http://stackoverflow.com/questions/23684133/cant-install-rmagick-pkg-config-command-not-found/23957018#23957018
かつて DWT 使いだったおじさんたちへ

Dreamweaver テンプレート (以下 DWT)、使わなくなりましたね。

HTML コンテンツの共通部分を管理したり、変数や式を使った条件分岐で出力するパーツを出し分けできたりと便利で、大規模な静的サイトの構築では威力を発揮しました。

でも Dreamweaver って有料だし、バグったりするし、Node.js 製のテンプレートエンジン使えば同じ問題を解決できるし、などの要因によって [Grunt](http://gruntjs.com/) が出てきた辺りからでしょうか、使わなくなったと記憶しています。

そんな DWT ですが先日ふと思い出して、こんな使い方あったなぁ、なんてものが出てきたのでここに記しておこうと思います。

## テンプレートコードは Javascript の式が使える

下記のようなテンプレートコードですが、

```html
@@(!templateParam)@@
<!-- TemplateExpr expr="!templateParam" -->
```

[公式のヘルプ](https://helpx.adobe.com/jp/dreamweaver/using/dreamweaver-templates.html)にも記載があるとおり、Javascript が使えます。
簡単な演算だけに限らず大体使えます。

## テンプレートコード内で Javascript を使ってみる

式として成立すれば割りと何でも良くて、例えば下記のようなコードを書くとわーっと何かが出てきます。

```html:window.dwt
<script>
@@(
(function() {

  /* window 配下をちら見してみる */
  var obj = window;
  var key;
  var value;
  var data = ['var data = {'];

  for (key in obj) {
    value = obj[key];
    if (/^string|object$/.test(typeof value)) {
      data.push('"'+ key +'": "'+ value +'",');
    }
    else {
      data.push('"'+ key +'": '+ value +',');
    }
  }

  data.push('};');
  return data.join('\n');

}());
)@@
</script>
```

```html:output.html
<script>
var data = {
"navigator": "[object Navigator]",
"dreamweaver": "[object Dreamweaver]",
// 省略 ...
"dwscripts": function dwscripts() {
},
"dwscripts_getNewline": function dwscripts_getNewline() {
// 省略 ...
</script>
```

`window` 配下にいろいろといらっしゃるのが確認できました。
Dreamweaver が内部で使っている風なコードが出てきましたね。
テンプレートコード内ではこんな感じで Javascript を使えます。

~~上記の結果を見るとファイル操作関数とかもあるんですが、大丈夫でしょうか。
野良 DWT とかよく見ないで無邪気に使ったりすると大変なことになりそうです☆~~

## まとめ

Dreamweaver のテンプレートコード内では Javascript が使えます。
使い方次第では僕が考えた最強の DWT とかできそうです。

ちなみに僕はあまり活用していなくて、下記のような残念な使い方だけしていました。

```html
@@(''/*

ここにテンプレートパラメータなどの説明を Markdown 形式で書いて
ドキュメント代わりにしていました。

*/)@@
```

## おまけ

`navigator` オブジェクトにも幾つか値が入っていました。
OSX の Dreamweaver CC 2015 を使った時の出力です。

```javascript
navigator.appName;  // "Netscape"
navigator.appVersion; // "4"
navigator.winOSname;  // "NA"
navigator.platform; // "MacPPC"
navigator.userAgent;  // "Dreamweaver/16.1(Macintosh; U; Mac OS X)Adobe Dreamweaver CC 2015/16.1.0.7851"
```

~~興味深いのは `Netscape` と `4` というバージョンです。
もしかして Dreamweaver が使っている Javascript エンジンは Netscape 4 がオープンソース化された時のものなのかも知れませんね。
それならばテンプレートコード内で JSON オブジェクトが使えないのも納得です。~~
(2016/03/14) `navigator.appName` には大体のブラウザで `Netscape` が入っている[仕様](https://www.w3.org/TR/html5/webappapis.html#dom-navigator-appname)なので宛にはなりませんでした。thx @jkr_2255
git for windows利用時のgithub接続にPermission denied (publickey)が出た時の対応

windowsにgitの設定しようとしたときにはまったのでメモ

git for windowsを入れて鍵をつくってgithubに登録したのに

```
ssh -T git@github.com
```

を実行したら

```
Permission denied (publickey)
```

が起きた
.sshにconfigを設定しても同様のエラー

git for windowsの場合
C:\Program Files\Git\etc\ssh\ssh_config

```
Host github.com
  User git
  HostName github.com
  IdentityFile (鍵の場所)
  IdentitiesOnly yes

```

に設定されていたのでこちらを修正し解決


#参考にしたページ

http://qiita.com/ques0942/items/1a6c198c6d16ac297f2c
本番環境でheroku run bundle exec rake RAILS_ENV=production db:migrateしたらエラー(relation テーブル名 does not exit)　[ 自分用メモ ]

参考サイト
http://qiita.com/zaqisuke/items/865fc0eed3ad24dbf3f3<br>

本番環境で<br>heroku run bundle exec rake RAILS_ENV=production db:migrate<br>
としたらActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation テーブル名 does not existとエラーが発生。<br>
heroku run bundle exec rake db:schema:load RAILS_ENV=production<br>
とした後<br><br>heroku run bundle exec rake RAILS_ENV=production db:migrateで成功。<br>
参考
Rake - Railsドキュメント
Alcatraz 初期設定と、とりあえず入れとくと良いプラグインの紹介

Alcatraz 初めて使うぞ！的な人への記事なので導入済みの人は読む価値ないです。

# [Alcatraz](http://alcatraz.io/) とは

XCode のプラグインマネージャ。
XCode で Vim 使いたいとか、カラースキーマとか導入したい時に使う。

# install

2016/03/12 現在のインストール方法は以下のコマンド。
ただ古くなっている可能性があるため [Alcatraz](http://alcatraz.io/#Install) に書いてあるの参照してほしい。


```
curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/deploy/Scripts/install.sh | sh
```

インストール後、 Xcode を再起動してね と言われるので再起動する。
再起動すると `Unexpected code bundles` と出るので、ここで間違えないよう `Load Bundles` を選ぶ。

`Skip Bundles` を選んじゃったら [Xcode をアップデートした後にプラグインが動作しないときは ｜ Developers.IO](http://dev.classmethod.jp/tool/xcode-load-bundle/) らへんの情報を見てなんとかする。

# Plugin install

1. Xcode メニュー > Window > Package Manager をクリック。
    * もしくは `cmd + shift + 9` でもいける。
2. 小さい画面でてくるので、そこでとりあえず Vim と入れてみる。
3. ２個目に XVim というのが出てくるので、 INSTALL をクリック
    * INSTALL 完了すると REMOVE というボタンに変わる
4. Xcode を再起動する。
5. 起動するとまた `Unexpected code bundles` が出るので `Load Bundles` を選ぶ。
6. エディタ起動すると Vim キーバインドが使えるようになる。

ちなみに [Alcatraz Search](http://starhoshi.github.io/AlcatrazSearch/) を使うと GitHub Star 順や更新順でプラグイン探せる。

# とりあえず入れとくべきプラグイン

* [ThilinaHewagama/AutoIndentWithSave](https://github.com/ThilinaHewagama/AutoIndentWithSave)
    * 保存すると自動で indent する。
* [FuzzyAutocomplete/FuzzyAutocompletePlugin](https://github.com/FuzzyAutocomplete/FuzzyAutocompletePlugin)
    * メソッド名などの補完をより便利にしてくれる。
* [onevcat/VVDocumenter-Xcode](https://github.com/onevcat/VVDocumenter-Xcode)
    * ドキュメントはこれで書こう。
* [XVimProject/XVim](https://github.com/XVimProject/XVim)
    * Vim 好きな人はこれ。
AnsibleのVariables優先順位で死んだ話

どうも情弱氏の俺です。

vars/main.ymlをrole default variablesと勘違いしていた話です。

`Ansible 2.0.0.2` での話です。

http://docs.ansible.com/ansible/playbooks_roles.html#role-default-variables
と
http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
をよく読みましょうという話です。

使い回しの効くいい感じのプレイブック目指すなら`role_name/defaults/main.yml`に書こうという話です。

# overrideできなくて死ぬ

- tree

```
orenomac$ tree  roles/mysql
roles/mysql
├── binaries
├── vars
│   └── main.yml
├── files
├── handlers
├── tasks
│   ├── main.yml
│   └── mysql_client.yml
└── templates
    └── my.cnf.j2
```

- vars/main.yml

```
mysql_client:
  install: true
  version: "5.6"
mysql_server:
  install: false
  version: "5.6"
```

- hosts
 
こーするじゃないですか。
overrideだと思ってて

```
- hosts: orenomassiiiiiiiinnnnnnn
  user: ec2-user
  vars:
    mysql_server:
      install: true
      version: "5.6"
  sudo: true
  roles:
    - mysql
```

- ansible-playbook

ファー`mysql_server.install`がoverrideされてない

```
TASK [mysql : debug] ***********************************************************
ok: [orenomassiiiiiiiinnnnnnn] => {
    "mysql_server": {
        "install": false,
        "version": "5.6"
    }
}
```

# overrideできて生き延びた

- tree

```
orenomac$ tree  roles/mysql
roles/mysql
├── binaries
├── defaults
│   └── main.yml
├── files
├── handlers
├── tasks
│   ├── main.yml
│   └── mysql_client.yml
└── templates
    └── my.cnf.j2
```

- defaults/main.yml

```
mysql_client:
  install: true
  version: "5.6"
mysql_server:
  install: false
  version: "5.6"
```

- hosts
 
今度こそoverride

```
- hosts: orenomassiiiiiiiinnnnnnn
  user: ec2-user
  vars:
    mysql_server:
      install: unko
      version: "5.6"
  sudo: true
  roles:
    - mysql
```

- ansible-playbook

ファーできた

```
TASK [mysql : debug] ***********************************************************
ok: [orenomassiiiiiiiinnnnnnn] => {
    "mysql_server": {
        "install": unko,
        "version": "5.6"
    }
}
```

完
iOSアプリにTwitter FabricのAnswer(Crashlytics)入れてみた

[Fabric](https://get.fabric.io) を実際に入れてアプリをリリースしてみたので、ダッシュボードの内容・使用感のレポートとか

## 導入方法

チュートリアルがかなり丁寧なので、ここに書くほど難しくないです
流れは以下のような感じだったかと思います

1. アカウント作成
2. Macアプリをインストール
3. アプリを起動し、手順に沿ってライブラリを入れビルド (自分はCocoaPodsで入れました)
4. Macアプリから提示されたコードを挿入

### 個人的にハマったところ
- dSYM Error とか言われちゃった時
- Debugでログが落ちてこない時
 - プロジェクト設定にて、以下のようにDebugでもdSYMを生成するよう切り替えると解決しました
<img width="546" alt="スクリーンショット 2016-03-14 0.38.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/deaf0692-a4a0-d699-9db8-533ef6d24934.png">

## Answerでわかること

<img width="489" alt="スクリーンショット 2016-03-14 0.00.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/1655d7a9-bcc8-3f1a-1f69-5a92d047b74c.png">


- リアルタイム/日別/月別のアクティブなユーザー数
- クラッシュ率
- iPhone/iPad/iPod touch 使用率
- iOSバージョン使用率
- 新規ユーザー数/比率

><img width="491" alt="スクリーンショット 2016-03-13 23.25.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/779bc137-f4ad-e0ae-eea1-e6c66c98dfeb.png">
>バージョン毎にこんな感じで見られるようでした

- 性別比率
- ユーザーの関心？

><img width="191" alt="スクリーンショット 2016-03-13 23.45.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/d70a49be-3a64-e2e9-9902-dae7db579893.png">
>この画面の下に"Top Differences"というのがあったのですが、これはよくわからず…

- アプリが使われている主な場所

><img width="222" alt="スクリーンショット 2016-03-13 23.45.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/caad8767-9025-92ca-e762-6d4aa1d55305.png">
>日本だけではなく海外も表示されそうな雰囲気でした

- DAU/MAU
- 利用継続率 (1,7,30日)
- クラッシュ率
- 接続数
- ユーザー毎利用時間
- 利用時間の平均/中央値

### イマイチよくわからんかった & 残念なところ

- Extensionには非対応…？
 - 自分が探した限りでは方法見当たらず

- イベント (ContentView)
 - 実際の数値やユーザー属性とか、もうちょっと細かく見れたらいいのですが…

>以下の画像のように比率しか見られず & 上位4つしか見られずで謎でした
><img width="485" alt="スクリーンショット 2016-03-13 23.54.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/72271/39e01daa-b71a-bf8d-a481-4bf9c47715af.png">

自分の場合"Content name"や"Content type"の使い分けがよくわからず、適当に入れちゃいましたが、カスタムイベントを以下の記事を参考に作ってみると、結構有効に活用できるかもしれません
[Twitter Fabric(Crashlytics)のAnswersの新機能イベントトラッキング結果例を紹介](http://qiita.com/mono0926/items/885ebeba4db5d7b834ac)

***

痒いところに手が届かない感じなのですが、テストで入れてみると本当にリアルタイムで反映されたり、本リリースに入れてみても結構数値がリアルなので、精度は高いように思えました

とにかく手軽なので、個人開発ぐらいならさくっと仕込んでユーザーの利用動向を把握するのに便利そうです
$ pod install より$ pod install --no-repo-updateがいいよね？

$ pod install の動作について 
--

`$ pod install `すると
cocoapodsのmasterにあるversion別ライブラリから今のディレクトリのPodfileに書かれてるversionのライブラリをコピーする

```
$ pod install　--verbose
```
このオプションをつけると実際行ってることがわかるんだけど、こんなかんじになって、

```
/usr/bin/git clone https://github.com/CocoaPods/Specs.git master --depth=1
Cloning into 'master'...
```

installするたびにmasterを書き換えるためにSpecs.gitをcloneしてるんです。
どうやらSpecs.gitをもってくるのが長くて２０分とかくらい時間かかる時があるとのこと。
だからとても重い。
そんな最新のやつじゃなきゃダメでもなければわざわざ持ってこないくていいよって感じ。
てかまず今のversionで試して、ダメならcloneという流れがいい。
なのでこのコマンドを日頃から使うことにします

```
$ pod install --no-repo-update
```
PL/SQL で ズンドコキヨシ

 > ズンドコキヨシまとめ
 > http://qiita.com/shunsugai@github/items/971a15461de29563bf90

と云う訳(?)で PL/SQL で ズンドコキヨシ を作って見た。

(力技で)すまんな。彡(-)(-)
ワンライナーでやっている猛者も何人か居るけど、
ワイにはこれ位が限界や……彡(-)(-)

```sql
SET SERVEROUTPUT ON SIZE UNLIMITED;
DECLARE
  -- Define
  vStr VARCHAR2(50);
BEGIN
  -- Initialize
  DBMS_RANDOM.SEED(TO_CHAR(SYSTIMESTAMP, 'YYYY/MM/DD HH24:MI:SS.FF'));
  -- ZunDoko Loop
  LOOP
    -- Zun or Doko
    vStr := vStr || CASE MOD(TRUNC(DBMS_RANDOM.VALUE*10), 2) WHEN 0 THEN 'ズン！' ELSE 'ドコ！' END;
    -- Cut and Format
    IF LENGTH(vStr) > 15 THEN
      vStr := SUBSTR(vStr, -15);
    END IF;
    -- Output
    DBMS_OUTPUT.PUT_LINE(vStr);
    -- Complete
    EXIT WHEN vStr = 'ズン！ズン！ズン！ズン！ドコ！';
  END LOOP;
  -- Kiyoshi!
  DBMS_OUTPUT.PUT_LINE('キ・ヨ・シ！');
END;
/
```

実行結果のサンプルは以下の通りやで彡(ﾟ)(ﾟ)

```sql
SQL> SET SERVEROUTPUT ON SIZE UNLIMITED;
SQL> DECLARE
  2    -- Define
  3    vStr VARCHAR2(50);
  4  BEGIN
  5    -- Initialize
  6    DBMS_RANDOM.SEED(TO_CHAR(SYSTIMESTAMP, 'YYYY/MM/DD HH24:MI:SS.FF'));
  7    -- ZunDoko Loop
  8    LOOP
  9      -- Zun or Doko
 10      vStr := vStr || CASE MOD(TRUNC(DBMS_RANDOM.VALUE*10), 2) WHEN 0 THEN 'ズン！' ELSE 'ドコ！' END;
 11      -- Cut and Format
 12      IF LENGTH(vStr) > 15 THEN
 13        vStr := SUBSTR(vStr, -15);
 14      END IF;
 15      -- Output
 16      DBMS_OUTPUT.PUT_LINE(vStr);
 17      -- Complete
 18      EXIT WHEN vStr = 'ズン！ズン！ズン！ズン！ドコ！';
 19    END LOOP;
 20    -- Kiyoshi!
 21    DBMS_OUTPUT.PUT_LINE('キ・ヨ・シ！');
 22  END;
 23  /
ズン！
ズン！ズン！
ズン！ズン！ドコ！
ズン！ズン！ドコ！ズン！
ズン！ズン！ドコ！ズン！ドコ！
ズン！ドコ！ズン！ドコ！ドコ！
ドコ！ズン！ドコ！ドコ！ズン！
ズン！ドコ！ドコ！ズン！ドコ！
ドコ！ドコ！ズン！ドコ！ドコ！
ドコ！ズン！ドコ！ドコ！ズン！
ズン！ドコ！ドコ！ズン！ドコ！
ドコ！ドコ！ズン！ドコ！ズン！
ドコ！ズン！ドコ！ズン！ズン！
ズン！ドコ！ズン！ズン！ドコ！
ドコ！ズン！ズン！ドコ！ドコ！
ズン！ズン！ドコ！ドコ！ズン！
ズン！ドコ！ドコ！ズン！ズン！
ドコ！ドコ！ズン！ズン！ズン！
ドコ！ズン！ズン！ズン！ズン！
ズン！ズン！ズン！ズン！ズン！
ズン！ズン！ズン！ズン！ズン！
ズン！ズン！ズン！ズン！ズン！
ズン！ズン！ズン！ズン！ズン！
ズン！ズン！ズン！ズン！ドコ！
キ・ヨ・シ！

PL/SQL procedure successfully completed.

SQL>
```

でももうちょっとスマートにやりたいやね彡(ﾟ)(ﾟ)
Windows7からラズベリーパイと有線接続

windows 7
raspberry pi 2
Lanケーブルで繋いで、windowsからラズベリーパイへssh接続する。

（１）ケーブル接続
（２）ブリッジ接続
コントロールパネル＞ネットワークと共有センター＞アダプターの設定の変更
raspberrypiとのローカルエリア接続とwifiとのワイヤレスネットワーク接続を両方選択した状態で右クリックし、ブリッジ接続する。
するとこんな感じ
![image](https://qiita-image-store.s3.amazonaws.com/0/99215/f67738d9-469c-2390-4d01-0232d73f9f37.png)

（３）raspberrypiへ割り当てられたIPアドレスを調べる。
windowsのコマンドプロンプトを開いてipconfig
![image](https://qiita-image-store.s3.amazonaws.com/0/99215/a5791382-f376-714f-3f8d-7810c7fb6bfa.png)

IPv4アドレスのところが、このwindowsマシンに割り当てられたIPアドレス。
pingで隣の番号のIPアドレスに接続を試みる（だいたい隣り合う番号に割り振られるらしい）。
192.168.10.199へ接続してみると成功。

（４）端末からssh


#参考
http://independence-sys.net/main/?p=975
redis概要

# ■ redis

個人が開発したキーバリューストア型のデータベース。

# ■ 特徴

## ● オンメモリ

メモリ上に書き込むので、HDDに書くより高速。

サーバの電源が落ちると。DB上のデータも消える


## ● データストラクチャ・ストア

文字列だけでなく、リスト、セット、ハッシュ、画像などのデータ構造をキーとして指定できる。

## ● 排他的制御

更新処理を原子的に行う

## ● マスタースレーブ

## ● 永続化

メモリデータが一定以上更新されると、ディスクに書き出す

# ■ 参考

* [入門 : Redis のデータ構造と概念](http://redis-documentasion-japanese.readthedocs.org/ja/latest/topics/data-types-intro.html)
AngularJS入門リンク集

# はじめに
こんにちはnagameです。
筆者がAngularJSを理解するためにお世話になったリンク集です。


##チュートリアル
[すぐできる AngularJS](http://8th713.github.io/LearnAngularJS/#/)
> ToDoアプリと帳票アプリがあります。チュートリアルだけではなくガイドも見やすくてオススメです。

[AngularJS's tutorial](http://lab.hisasann.com/AngularJSTutorial/)
> 機能単位で説明があり分かりやすいです。

##動画
[ドットインストール](http://dotinstall.com/lessons/basic_angularjs)
> もはや説明不要の動画学習サイト

[code school](http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro)
> ドットインストールでは紹介のないカスタムディレクティブの説明もあります。英語です。

[ng-mtg#4](https://www.youtube.com/watch?v=ZehPqvoUEYk)
> 2013/12/03に開催されたAngularJS勉強会。[AngularJS 20min](https://speakerdeck.com/naoya/angularjs-20min-number-ng-jp)のスライドの動画です。


##スライド
[AngularJS 20min](https://speakerdeck.com/naoya/angularjs-20min-number-ng-jp)
> 伊藤直也さんのスライドです。分かりやすい。[動画](https://www.youtube.com/watch?v=ZehPqvoUEYk)あります。

[Directiveで実現できたこと](http://www.slideshare.net/KonYuichi/0725-directive-innote)
> ng-mtg#6 @konpyuさんの資料。案件をもとにDirectiveについて分かりやすく説明されています。


[モダンAngularJS](http://www.slideshare.net/armorik83/angularjs-141206)
> @armorik83 さんのスライドです。下記でご紹介する[Qiitaの記事](http://qiita.com/armorik83/items/5542daed0c408cb9f605)とあわせて読むと理解が深まると思います。

##Qiitaの記事
[AngularJSモダンプラクティス](http://qiita.com/armorik83/items/5542daed0c408cb9f605)
> 個人的には神。丁寧に書かれていてAngular2へマイグレーションを考慮されて書かれています。

[その使い方はもう古いかも？AngularJS老化チェック（ディレクティブ篇）](http://qiita.com/laco0416/items/edfa917583af4593ad6c)
> 1.2から1.3、1.4、1.5と各バージョンの書き方が紹介されています。

[AngularJSのDirectiveを理解する](http://qiita.com/Quramy/items/dd4e7d2693c32d92048c)
> 初心者がつまづきやすいDirectiveの構成要素を説明してあります。

##参考書
[AngularJSリファレンス](http://www.amazon.co.jp/AngularJS%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-%E6%B1%A0%E6%B7%BB-%E6%98%8E%E5%AE%8F/dp/4844336681)
> 個人的には一番わかりやすい参考書でした。ビルトインディレクティブの機能など一つ一つ丁寧に説明してあります。

## まとめ
エントリーの古い記事もそのまま紹介しています。Angular2を捉えながら学習するには多少ノイズがあると思います。。
（Angular2では$scope,ng-controller, restrictが廃止されるなど）
その辺りはうまく読み替えていってください。急がば回れ。Angularの課題を知ることでより詳しく理解出来ると思います！
ズンドコキヨシ with Elixir Stream

# はじめに

流行りに乗ってみました。すでにn番煎じでした。すいません
しかも仕様を間違えて永遠に続けられるようにしてしまいました。
でもStreamモジュールの勉強になりました。

#Streamとは

Elixirにはリスト用のモジュールとして即時評価なEnumモジュールと遅延評価なStreamモジュールがあります。
今回Streamモジュールをつかった遅延評価な感じで実装してみました。

常に5word分バッファしながら動きバッファの内容が条件にマッチングしたら
キ・ヨ・シ！をリストに追加します。

実装結果は以下のとおりです。

```ex
defmodule Zundoko do
  @zun "ズン "
  @doko "ドコ "
  @kiyoshi "キ・ヨ・シ！"
  def try(n) do
    zundoko |> kiyoshi |> Enum.take(n) |> IO.puts
  end
  def zundoko do
    Stream.repeatedly(fn -> Enum.random([@zun, @doko]) end)
  end
  
  def kiyoshi(zundoko) do
    zundoko |> Stream.transform([], fn e, acc ->
      if Enum.count(acc) < 5 do
        {[e], [e|acc]}
      else 
        [_ | tail] = Enum.reverse(acc)
        next_acc = Enum.reverse(tail)
        case Enum.reverse(acc) do
          [@zun,@zun,@zun,@zun,@doko] -> {[@kiyoshi,e],[e | next_acc]}
          _ -> {[e],[e | next_acc]}
        end
      end        
    end)
  end
end
```

順に説明します

## zundoko

無限長のリストを作成します。
randomに`ズン`,`ドコ`を吐き出し続けることが可能です。

```ex
  def zundoko do
    Stream.repeatedly(fn -> Enum.random([@zun, @doko]) end)
  end
```
個別に実行すると次のようになります。

```
iex(67)> Zundoko.zundoko |> Enum.take(5)
["ドコ ", "ズン ", "ズン ", "ズン ", "ズン "]
iex(68)> Zundoko.zundoko |> Enum.take(5)
["ドコ ", "ドコ ", "ドコ ", "ズン ", "ドコ "]
```

Enum.takeの地点で実行されます。

##  kiyoshi

無限長のリストを引数に取り内部的にwordを最大5wordバッファします。
バッファ内容に対して ``[@zun,@zun,@zun,@zun,@doko]``とマッチングしマッチしたら``キ・ヨ・シ！``をリストに挿入します。

```ex
 def kiyoshi(zundoko) do
    zundoko |> Stream.transform([], fn e, acc ->
      if Enum.count(acc) < 5 do
        {[e], [e|acc]}
      else 
        [_ | tail] = Enum.reverse(acc)
        next_acc = Enum.reverse(tail)
        case Enum.reverse(acc) do
          [@zun,@zun,@zun,@zun,@doko] -> {[@kiyoshi,e],[e | next_acc]}
          _ -> {[e],[e | next_acc]}
        end
      end        
    end)
  end
```

``Stream.transform(enum, acc, fun)``は以下のように引数を取ります。

* enum Stream(遅延評価リスト)
* acc(アキュームレータ)　処理全体を通して使用する一時保存変数です。今回はバッファとしてリストをもたせています
* fun (element,acc) 第一引数は上述enumの各要素、第二引数に上述のアキュームレータが来ます。  
返却値としては返却するエレメントと次のアキュームレータの２要素のタプルとなります。
メモ：Rの関数の環境

『R言語徹底解説』8章を読んだので、Rの関数に関連する 4 つの環境について理解できたか確認したい。

|名前|英語|調べる方法|
|:--|:--|:--|
|エンクロージング環境|enclosing|`environment(f)`|
|束縛環境|binding|`pryr::where("f")`|
|実行環境|execution|`environment()`|
|呼び出し環境|calling|`parent.frame()`|

次のような関数を用意する。

```r:R
f <- function() {
  cat("x: ", x, "\n")
  eclosing_env  <- environment(f)
  binding_env   <- pryr::where("f")
  executoin_env <- environment() ; attr(executoin_env, "name") <- "execution_env"
  calling_env   <- parent.frame()
  cat("エンクロージング環境:\t", environmentName(eclosing_env),  "\n")
  cat("束縛環境:\t\t",           environmentName(binding_env),   "\n")
  cat("実行環境:\t\t",           environmentName(executoin_env), "\n")
  cat("呼び出し環境:\t",         environmentName(calling_env),   "\n")
}
```

これをそのまま呼び出すと、次のような結果になる。

```r:R
x <- 1
f()
```

```:結果
x:  1 
エンクロージング環境:	 R_GlobalEnv 
束縛環境:		 R_GlobalEnv 
実行環境:		 execution_env 
呼び出し環境:	 R_GlobalEnv 
```

実行環境以外はグローバル環境である。

エンクロージング環境を変えてみる。

```r:R
enclosing_env <- new.env()
attr(enclosing_env, "name") <- "my_enclosing_env"
assign("x", 999, envir = enclosing_env)
environment(f) <- enclosing_env

f()
```

```:結果
x:  999 
エンクロージング環境:	 my_enclosing_env 
束縛環境:		 R_GlobalEnv 
実行環境:		 execution_env 
呼び出し環境:	 R_GlobalEnv 
```

エンクロージング環境を変更できた。
`x` の値もグローバル環境の値からエンクロージング環境のものに変わっている。

次に、束縛環境を変えてみる。

```r:R
binding_env <- new.env()
attr(binding_env, "name") <- "my_binding_env"
assign("f", f, envir = binding_env)
parent.env(enclosing_env) <- binding_env

f()
```

```:結果
x:  999 
エンクロージング環境:	 my_enclosing_env 
束縛環境:		 my_binding_env 
実行環境:		 execution_env 
呼び出し環境:	 R_GlobalEnv 
```

エンクロージング環境とグローバル環境の間に新しい環境を追加し、そこに `f` を置いた。
これは、関数 `f()` 内で `f()` という関数を呼び出そうとすると、呼び出されている関数とは別の、新しく作成した環境にあるものが呼び出されることになる。

さらに、呼び出し環境を変えてみる。

```r:R
f2 <- function() {
  calling_env <- environment()
  attr(calling_env, "name") <- "my_calling_env"
  f()
}

f2()
```

```:結果
x:  999 
エンクロージング環境:	 my_enclosing_env 
束縛環境:		 my_binding_env 
実行環境:		 execution_env 
呼び出し環境:	 my_calling_env 
```

関数を呼び出す場所を新しい関数 `f2()` の中に変更した。
関数の呼び出し場所を変えれば呼び出し環境は変わる。

R　の環境について理解が進んだように思える。