OmniAICreator/Qiita-1.07M huggingface dataset:
Facebookの投稿埋め込みができるようになるらしい


facebookの投稿を、Webサイトに埋め込む仕組みが使えるようになったみたいです。

- [Facebook、「埋め込み投稿」機能を全ユーザーが利用可能に -INTERNET Watch](http://internet.watch.impress.co.jp/docs/news/20130822_612161.html?ref=rss)
- [Embedded Posts Now Available to Everyone- Facebook Developers](https://developers.facebook.com/blog/post/2013/08/21/embedded-posts-now-available-to-everyone/)

動画の再生もlikeも、この埋め込み投稿からできるよ! とのことです。

いちおう仕組みとか使い道とか、いろいろ調べてみました。

## 埋め込みタグの取得方法

方法は2つあります。

まず、facebook上で、投稿の右上に付いている矢印から「埋め込み投稿」を選ぶ方法。
例えばザッカーバーグの投稿とか。

- https://www.facebook.com/zuck

![右上の矢印](http://gyazo.com/7da5ea76e2347234650c3b85e9e158e4.png)

クリックするとこんな画面。ここで出てくるタグをhtmlに貼ると、投稿が埋め込みできるわけです。

![埋め込みタグが出た](http://gyazo.com/7851176fd689a7fef4a8ba4aa0efe10b.png)


ふたつめ。ここのページでポストのURLを入力すると、埋め込みタグつくれます。

- https://developers.facebook.com/docs/plugins/embedded-posts/

こちらはこんな画面。

![URLを入力して埋め込み](http://gyazo.com/5805d531419195de09257694c121fe87.png)

なお、facebookの投稿のURLは、投稿の時刻の部分に貼られてるリンクからとれますよ。

![「リンクアドレスをコピー」つかうと吉](http://gyazo.com/a738789c25ff121dd071d1779771ae0b.png)

## 埋め込みタグ

埋め込むときの実際のタグはこんな感じ。

```
<div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/all.js#xfbml=1"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script>

<div class="fb-post" data-href="https://www.facebook.com/fnobi/posts/523780947693730"><div class="fb-xfbml-parse-ignore"><a href="https://www.facebook.com/photo.php?v=10200120650771638">Post</a> by <a href="https://www.facebook.com/mumfordandsons">Mumford and Sons</a>.</div></div>
```

おなじみのfb-rootに、fb-postっていうものがくっついている形ですね。
タグの形式は非常にシンプルで、 **data-hrefに埋め込みたい投稿のURLを入れるだけ**みたいです。

中のfb-xfbml-parse-ignoreは、代替コンテンツみたいなかんじですね。
公式が生成するタグはこういう感じのテキストリンクが入ってますが、たぶん別のものいれても動くと思います。

## 何に使えそうだろうか
たとえばキャンペーンサイト上で、投稿に対するlikeを可視化したり、ねだったりしやすくなるので、できることは増えそう。

投稿のURLがあれば埋め込みタグはこっちでも生成できそうなので、
APIであるウォールの投稿ぜんぶ引っ張ってきて、すべて埋め込みとして表示、とかもできますね。

投稿自由なfacebookページを作っておいて、ユーザーにあるテーマで投稿してもらって、そのいいね数を競う…みたいな?
Ruby 1.8のハッシュロケットを使ってしまって斧を投げられないように、一発で1.9形式に変換するvimの設定

現実逃避のための小ネタ。
Inspired by [Ruby - Hash Rocketを1.9記法に置換するelisp - Qiita [キータ]](http://qiita.com/kwappa/items/367ce6fe65fed922ae02 "Ruby - Hash Rocketを1.9記法に置換するelisp - Qiita [キータ]")

elispがあるんだからvimも書いておこう。

```vim
" to 1.9 hash
vnoremap <silent> <C-h> :s/:\([a-zA-Z0-9_]\+\)\s*=>/\1:/g<CR>
```

Shift-Vとかで複数行選択してやれば、特定範囲でサクっと。
自分は手頃なキーマップが空いてなかったのでビジュアルモードにだけ割り当ててるけど、その他でも使いたかったらvnoremapをnnoremapに変えれば、ノーマルモードでもそのまま利用できる。
その時はカーソルのある行だけ。

逆方向の変換? 不要ですよね。
範囲外の enum

**以下の内容は [enum 利用時の注意事項について](http://qiita.com/kazuhisam3/items/093fbc734d37aae5db8c) により詳しく書かれています。**

----

enum は範囲外の値もとれるってことが意外と知られていない気がする。

```csharp:enum.cs
public enum Hoge
{
    Foo = 0,
    Bar = 1
}
```
```csharp:use.cs
// 普通に動く
Hoge hoge = (Hoge) 2;
```
Web情報クリッピングTips

#はてなブックマーク
## iPhoneのSafari用
- 公式ブックマークレットがある 
- [はてなブックマークに追加](http://b.hatena.ne.jp/help/touch/bookmarklet?javascript:(function(){if(window.BTouch){BTouch.Let.loadBookmarklet();}else{var%20d=new%20Date;var%20s=document.createElement(%27script%27);s.type=%27text/javascript%27;s.charset=%27utf-8%27;s.onload=function(){BTouch.Let.loadBookmarklet();};s.src=%27http://b.hatena.ne.jp/js/BTouch.js?d=%27+d.getFullYear()+d.getMonth()+d.getDate();document.body.appendChild(s);}})())

## iPhoneのChromeブラウザからはてなブックマークする
- [iOS版 Google Chrome と はてなブックマーク for iPhone を連携する - 大西ブログ](http://onishi.hatenablog.com/entry/2012/07/18/133506)

## Twitter連携
- はてなブックマーク設定からTwitterアカウントを登録して、Twitter連携設定をオンにすることで、Twitter投稿記事のURLを自動でブックマーク登録できる

#Flipboard
- Facebookにシェアできるが『全公開』にはされてしまう
JavaScriptの楽しい(?)ところ

個人的に「面白い動作だなぁ」と思ったものの詰め合わせ。


```js:

(alert(1), "Hello"); 
//-> "Hello"

(alert(1), alert(2), alert(3)); 
//->左から順に実行

a = ["zero","one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"]

a[1+1]
//-> "two"
a["1"+"1"]
//->"eleven"

a = {}
a.valueOf = 5
a + 3
//->"[object Object]3"

a.valueOf = function(){ return 5}
a + 3
//-> 8

a = ["hello", "world", "hoge", "xxx", "test", "boo"];
b.valueOf = function(){ return  Math.floor(Math.random() * 5) }
a[+b]
//->"world"
a[+b]
//->"test"
a[+b]
//->"xxx"
a[+b]
//->"test"

a = ["hello", "world" , 1, 3];
b = 'join'
a[b]();
//->"hello,world,1,3"
b = 'sort';
a[b]();
//->[1, 3, "hello", "world"]


a = ["aaa", "bbb" , "ccc", "ddd"];
flag = true;
a[flag ? 'shift' : 'pop']();
//->"aaa"

flag = false;
a[flag ? 'shift' : 'pop']();
//->"ddd"

```

やっぱり、JavaScriptって楽しい。
gnuplotで目盛りの数字は表示しつつ目盛り自体は表示させない


![kobito.1377237683.680544.png](https://qiita-image-store.s3.amazonaws.com/0/523/7f906034-a759-d5f1-69b7-d58e4f21e53f.png "kobito.1377237683.680544.png")

gnuplotでグラフを描くときに、目盛り(tics)の数字自体は表示させたいけど、目盛りのヒゲみたいなやつは消したいことがまれによくある。

そういうときは

~~~
set xtics scale 0 0
~~~

を指定すると、ヒゲを消せる。ちなみに `scale` オプションはmajor ticsとminor ticsのヒゲのサイズをそれぞれ指定するもの。
ファイルの先頭から n 行捨てて残りを表示するコマンド

```bash
$ sed 1,${line}d
```

```bash
$ seq 1 10
1
2
3
4
5
6
7
8
9
10
```

```bash
$ seq 1 10 | sed 1,3d
4
5
6
7
8
9
10
```
ファイルの先頭から n 行捨てて残りを表示するコマンド

`~/bin/tailm` とかに置く

```bash
$ cat /tmp/hoge
1
2
3

$ tailm -n 1 /tmp/hoge
2
3
```

```rb:
#!/usr/bin/env ruby
require 'optparse'
o = OptionParser.new
o.on('-n=VAL') { |n| @n = n }
o.parse!

@n.to_i.times do
  ARGF.gets
end

puts ARGF.read
```
Chromeコンソール右下に謎の黄色い三角

バージョンアップか、自分が入れた改修によるものか不明ですが、
いつの間にか Chrome コンソールの右下に黄色い三角が出ていました。

![](http://gyazo.com/434acca5568457ff1986617c9d8642d7.png)

出力には何も出ないので何かなと思ってたら CSS のバグで ..

![](http://gyazo.com/82c4efd3d4841a6e35258be45d16e223.png)

のチェックを付けると、

![](http://gyazo.com/11cca84c39c7959a9dbd081ee86491ef.png)

と、警告が出力されるようになりました。
VMで後から接続したNICを調べる。

メモ

```bash:
/sbin/ifconfig -a
```

```
eth0      Link encap:Ethernet  HWaddr 08:00:27:17:6A:86
          inet addr:192.168.200.153  Bcast:192.168.200.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe17:6a86/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4135 errors:0 dropped:0 overruns:0 frame:0
          TX packets:49 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:333798 (325.9 KiB)  TX bytes:4160 (4.0 KiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:FA:A0:57
          inet addr:192.168.56.2  Bcast:192.168.56.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fefa:a057/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:667 errors:0 dropped:0 overruns:0 frame:0
          TX packets:492 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:58652 (57.2 KiB)  TX bytes:91881 (89.7 KiB)

eth2      Link encap:Ethernet  HWaddr 08:00:27:0A:F8:27
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

eth3      Link encap:Ethernet  HWaddr 08:00:27:DE:0E:A2
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

```
csvをLOAD DATA INFILEするときよく発行するクエリ

たまに依頼があるLOAD DATA INFILEでの作業

```sql:event_history
CREATE TABLE event_hisotry(
  `id` bigint unsigned not null auto_increment,
  `member_id`, bigint unsigned not null,
  `event_id` tinyint unsigned not null,
  `created_at` datetime not null,
  PRIMARY KEY(`id`),
  KEY `key_1` (`member_id`, `timestamp1)
)Engine=InnoDB
```

みたいなテーブルに

```
"member_id","event_id","created_at"
"100","23","20130823100000"
"100","24","20130823101510"
"101","23","20130823095959"
...
```

みたいなcsvをいれてくれという依頼。

* 1行目に取り込む必要がないものが入っている
* 各fieldがダブルクォーテーションで囲まれている
* auto_incrementのfieldが省略されている。

発行するクエリは

```sql:
LOAD DATA INFILE '/data/mysql_backup/filename.csv' INTO TABLE event_hisotry 
  FIELDS TERMINATED BY ',' ENCLOSED BY '"' (member_id, event_id, `created_at`);
```

これでOK。
【Ruby】対象のIPアドレスがプライベートIPアドレスかどうか確認する

IPAddr クラスにそういうメソッドが見当たらなかった。

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

require "ipaddr"

def private_ip?(target)
  IPAddr.new("10.0.0.0/8").include?(target) ||
  IPAddr.new("172.16.0.0/12").include?(target) ||
  IPAddr.new("192.168.0.0/16").include?(target)
end

p private_ip?("8.8.8.8")
p private_ip?("10.10.10.10")
```

```rb:
#=> false
#=> true
```
Git で feature ブランチにいる時に master に移動して pull してから元の feature ブランチに戻って rebase master する

#### 修正バージョン

最初は @{-1} を使っていましたが、うまくいかないケースがあるようなので、ブランチ名を直接 checkout するようにしました。

```:~/.gitconfig
rebase-master = "!sh -c 'branch=`git rev-parse --abbrev-ref HEAD` && git checkout master && git pull origin master && git checkout $branch && git rebase master'"
```

```zsh
☁  git rebase-master
Switched to branch 'master'
From github.com:foo/bar
 * branch            master     -> FETCH_HEAD
Current branch master is up to date.
Switched to branch 'foo'
Current branch foo is up to date.
```

---

#### 最初に書いたうまくいかなかったバージョン

```:~/.gitconfig
rebase-master = "!sh -c 'git checkout master && git pull origin master && git checkout @{-1} && git rebase master'"
```

### 参考

http://keijinsonyaban.blogspot.jp/2010/11/git-tips.html

>"@{-n}" という特別な構文は「現在から数えてn個前にチェックアウトされていたブランチ」という意味だ。"feature" がチェックアウトされたなら、"@{-1}" は "master" を表している。
Gitでブランチのトラッキング先を設定する

```
$ git push -u origin トラッキングするブランチ
```

トラッキングするブランチが設定されていないのにgit pullした場合（めったに起きないけど）、

```
$ git branch --set-upstream いまのブランチ origin/<branch>
```

しろってメッセージが出るけど、git push -u するだけでいい。
`make`で澄ました表示をする方法・騒がしくする方法


git なんかをビルドするときには、makeを実行するとgcc等の実行されるコマンドがそのまま騒がしく表示されることなく

~~~
  CC    hoge.o
  CCLD  hoge
~~~

のように澄ました出力のみが表示がされます。
このような表示方法はどうやってやるのか。とはいえデバッグ・トラブルシュート時には実行されるコマンドそのものを表示させたいが、その時はどうするのか。

# 答え

## 澄ました表示にする

すました表示にする機能はAutomakeのものなので、Automakeを使ってビルドしていることが前提となります。
この機能を有効化するためには、`configure.ac` の `AM_INIT_AUTOMAKE` で指定する Automake のオプションに `silent-rules` を追加すればよいです。

~~~
...
AM_INIT_AUTOMAKE([… silent-rules …])
...
~~~

デバッグ用途で `make` 時のコマンドを表示したいときは、makeのときに環境変数`V`に1を設定すればよいです。

~~~
$ make V=1
~~~
NetCommons2に自前CSSを読みこませる方法


NetCommonsアドオンセミナーで教えてもらった方法をもとにして、自前スタイルシートファイルがあるときは、自前スタイルシートファイルを読みこみ、ファイルがなければ、何もしないようにしてみました。

いじるのは、webapp/templates/main/header.html 75行目あたり

```
<{/if}>
</head>
```
があるので、上記を下記に書換

```
    <{if file_exists($smarty.const.HTDOCS_DIR . '/mystyle.css')}>
    <link rel="stylesheet" type="text/css" href="<{$smarty.const.BASE_URL}>/mystyle.css">
    <{/if}>
</head>
```
これで htdocs/mystyle.css があると、mystyle.css が読みこまれ、無ければ何もしないので、mystyle.cssはユーザさんが自分で作成して好きにいじればOKってなります。

毎回ファイルがあるかどうかチェックするのでムダっていえばムダなんですが、これ本体に取り込んでくれないかなぁ〜
シェルスクリプトの二重起動抑止（起動コマンドライン完全一致時）

pgrepコマンドやlockファイルを使用した抑止については一般的にいくつかありますが、なかなかシンプルに完全な二重起動抑止をするのは難しいようです。
色々と検討中ではありますが、その中で（恐らく）限定状況下においては効果を発揮しそうな形の抑止処理がありましたので記述します。

・起動コマンドラインが引数を含めて完全一致する場合
　※cron起動で引数が固定である場合などで有効か？

```bash:Bash
# 起動プロセスの完全名を取得
# cmdlineはnull区切りなのでxargsをかませる
CMDLINE=$(cat /proc/$$/cmdline | xargs --null)

# 名称が完全に一致しているプロセスが他に無ければOK
if [[ $(pgrep -oxf "${CMDLINE}") -ne $$ ]];then
    echo "error message."
    exit 1
fi
```
CSSでチェックボックス、ラジオボタンのデザインをいじる

チェックボックスをサイトデザインに合わせたいなって時のために。
基本的にはCSSで弄れないので。


チェックのデザインはみんな大好きFont Awesome( http://fortawesome.github.io/Font-Awesome/ )


[DEMO](http://play.amgw.jp/custom-inputs/)


+ デフォルトのinputは要らない子なので`opacity: 0` と `position: absolute` で空気に。
+ これでinputが見た目空気になったので、チェックボックスがチェックされてない状態を用意。今回は `label::before`のborderでそれっぽく。
+ チェックは`input:checked`を使って兄弟要素の `%i.icon-ok` のopacityをトグルする。


haml 

```haml

%label.custom-checkbox
  %input{type: "checkbox"}
  %i.icon-ok
  チェックボックス
```
sass 

```sass
@import compass

.custom-checkbox
  display: inline-block
  position: relative
  margin: 0 1rem 1rem
  padding: 1px 0 0 2px
  cursor: pointer

  &:before,
  &::before
    content: ""
    position: absolute
    top: 3px
    left: 0
    height: 13px
    width: 13px
    border: 2px solid
    +border-radius(2px)

  input
    position: absolute
    +opacity(0)

    & + i
      margin-right: 3px
      +opacity(0)
      +single-transition(opacity,100ms,linear)

    &:checked + i
      +opacity(1)

.custom-radio
  @extend .custom-checkbox
  padding: 3px 0 0 4px


  &:before,
  &::before
    height: 16px
    width: 16px
    +border-radius(10px)
```


label内のテキストをspanかなんかでくくって
そいつのbeforeとafter使えば`%i.icon-ok`も減らせるけど
でも結局その分のCSSを書かないといけないので一先ずこれで。
ダメな技術書の見定め方

技術書を自分のお金で買うようになってから、かれこれ十数年。

ダメな技術書が放つ独特のニオイがやっとわかるようになってきたので、書いてみました。

以下、主観を多分に含みます。「あー、あるある」と思いながら軽く読んでくださいね。

(逆バージョンの「良書のみつけかた」は、近日公開予定でございます。)


ダメな技術書の「あるある」
=========================

誤字・脱字が多い
----------------------

推敲に時間を割いてないことの証拠である。よって誤字・脱字が多い本は技術書としてもクソ本である確率が高い。


正誤表・サポートページがない
-------------------------------------------

多少の誤字・脱字は仕方がないとしても、それを Web で補う気すらない著者がいる。そういう方の書いた本は、えてしてクソ本であることが多い。



レビュアーの名前が献辞に載ってない
-------------------------------------------------

レビューを経ていないと、著者のひとりよがりな内容だったり、技術的に正しくない内容があったりするので要注意だ。(※レビューなしで良書を出してる方もいるので、これだけでクソ本判定してはいけない。)


監訳者がいない or いるけど監訳してない
-----------------------------------------------------------------

翻訳書の場合、その道に詳しい人に監訳をしてもらわずに出版されてしまった本がある。監訳者がいたとしてもほとんど仕事をしていないような場合がある。ひどい場合だと翻訳会社にベロンと丸投げしてそのまま出してしまったような本すらある。それらのどれであったとしても、訳文がしっちゃかめっちゃかになるのは避けられない。

この場合、原書が良書であったとしてもクソ本と化す。ただ単にクソ本を出すことでも大罪なのだが、翻訳独占権によって他の良識ある人が別訳を出すことができなくなってしまうので、その業は深い。


サンプルコードがバグバグ or 動かない 
--------------------------------------------------

こういうのに遭遇するたびに、コードは実際に動かしてチェックしてくれよ、と思う。


サンプルコードに脆弱性がある
------------------------------------------

[高木先生に首を刈られる危険性](http://takagi-hiromitsu.jp/diary/20051227.html)を知らずに出版してしまっている時点でヤバい。


著者のプロフィールが長い or カッコ良すぎる
-----------------------------------------------------------

プロフィールがやたら長いと、クソ本率が高まる。海外大学卒とか、何かの資格を当時最年少で取得したとか、ナントカ協会の理事だとか、そういうのをひけらかしている場合なぜか技術的な内容もクソであることが多い。バズワード (「クラウド」とか「BYOD」とか) がそこに含まれていると、クソ本率がMAXになる。不思議だ。


やたらと多い参考文献
---------------------------------

参考文献が何ページにもわたってずらずらと列挙されている本は、何故かクソ本であることが多い。

RFC・I-D・本・Webページ・言語仕様・リファレンス、その他やたらめったらとリストアップされている (しかも本文中との関係が示されていない) 本があって、内容をみたら案の定クソであった。


無意味な付録
-----------------------

本文と関係がない無意味なものを、そのままベロンと巻末に採録している本はクソ本率高し。PHPの言語仕様を採録している本があった。内容をみたら案の定クソであった。GPLの翻訳全文を無意味に採録している本があった。内容をみたら案の定クソであった。


危険人物
-------------------------------

クソ本ばかりのくせに何冊も出版している著者がいる。なぜそんなことが可能なのかよく分からないけど、本当にそんな人がいるんだよ!

買う前にググって、著者がネタ人物扱いされていないかどうかよくよくチェックするべき。



油断してはいけない……
=========================

以下はダメとはいえないまでも、注意しておいたほうが良い場合。

古い
-----------------

技術書は経年劣化が激しい。

ものすごくおおざっぱに言うと、2005年以前のJavaの本、2009年以前の Ruby・Ruby on Rails の本、2006年以前の JavaScript の本、2005年以前の MySQL の本は概ね使えないと思っておいたほうが良いと思う。

もちろんそのなかにも良書はあるので、よくよく確かめてから買ってほしい。


「○○公式」「○○認定」
------------------------------

「公式と書いてあるから」と安心して買ってしまうとひどい目に遭ったりする。よくよく考えてみれば公式だろうと認定を受けていようとダメな本はダメな本だし、良い本は良い本である。

内容の良さにはあまり関係がない。


ポケットリファレンスの類
-------------------------------------

個人的にはイマイチ。買ったけど結局使わないことが多い。


クックブックの類
--------------------------

同じく。好きな人もいるみたいなので、相性の問題かも。


余談
=========

誤字・脱字がやたらと多いことで有名な、とある方がいる。そのお方、著書について Amazon のレビューで誤字・脱字についてボロクソに書かれたら、自身のブログで「誤字・脱字が多少あったとしても技術書なんだから別に良いだろ、普通わかるだろ」みたいなことを言って開き直っていた。多少ってレベルじゃねーよ、とツッコミはさておき、開き直ってる時点で書き手として論外でしょ、と思った。

実はつい最近、似たようなことを言ってる人を他にも見つけた。良書とクソ本の区別がつきやすくなるので助かるなぁと思った。

もちろん、その本には正誤表が無かった。
PHPにおける再帰処理の高速化

鉄則： C言語レベルで再帰処理させろ！
=============================

PHP言語レベルで再帰させるのとC言語レベルで再帰させるのでは、処理速度に雲泥の差がある。
圧倒的にC言語レベルの方が高速。

よく使う関数・クラス
==============

以下の関数やクラスを使えば、配列の要素を辿っていく再帰処理であっても、
葉ノードだけを (PHP言語レベルでは) **単一のループ** で処理させることが可能。

`array_walk_recursive()`
-------------------------------

http://php.net/manual/ja/function.array-walk-recursive.php
最速。

`RecursiveIteratorIterator`
-------------------------------

http://www.php.net/manual/ja/recursiveiteratoriterator.construct.php
`array_walk_recursive()`より速度的には僅かに劣るが、こちらにしか出来ないこともある。

> - **`RecursiveIteratorIterator::LEAVES_ONLY`**  
デフォルト。イテレーションで葉ノードだけを取り上げます。
> - **`RecursiveIteratorIterator::SELF_FIRST`**  
イテレーションで葉と親を (親から先に) 取り上げます。
> - **`RecursiveIteratorIterator::CHILD_FIRST`**  
イテレーションで葉と親を (葉から先に) 取り上げます。

このようにモードを切り替えることが可能。
更に、 **`RecursiveArrayIterator`** 以外にも

- **`RecursiveDirectoryIterator`**
- `RecursiveCachingIterator`
- `RecursiveCallbackFilterIterator`
- `RecursiveFilterIterator`
- `RecursiveRegexIterator`
- `RecursiveTreeIterator`

と併せて使うことが可能。

応用例
=====

`array_map_recursive()`
-----------------------------

`array_map()`みたいに複数の配列引数は受け付けないけど。

```php:PHP5.3の場合はcallableタイプヒンティング消してください
<?php
function array_map_recursive(callable $func, array $arr) {
    array_walk_recursive($arr, function(&$v) use ($func) {
        $v = $func($v);
    });
    return $arr;
}
```

**追加記事: [array_map_recursiveはPHPに標準実装されていた！](http://qiita.com/mpyw/items/2967ea1e36a144f76587)** もご覧ください。

`array_flatten()`
--------------------

葉要素だけを取り出して1次元の配列にする。

```php
<?php
function array_flatten(array $arr) {
    $ret = array();
    array_walk_recursive($arr, function($v) use (&$ret) {
        $ret[] = $v;
    });
    return $ret;
}
```

`dirsize()`
-----------

指定したディレクトリのサイズを取得する。

```php
<?php
function dirsize($dir) {
    $sum = 0;
    foreach (new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(
            $dir,
            FileSystemIterator::SKIP_DOTS
        )
    ) as $item) {
        if ($item->isFile()) {
            $sum += $item->getSize();
        }
    }
    return $sum;
}
```

`scan_image()`
-------------------

指定したディレクトリ下にあるGIF/JPEG/PNG画像へのパスを再帰的に取得する。

```php
<?php
function scan_image($dir) {
    $ret = array();
    foreach (new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator(
            $dir,
            FileSystemIterator::SKIP_DOTS
        )
    ) as $item) {
        switch (true) {
            case !$item->isFile():
            case ($info = @getimagesize($path = $item->getPathname())) === false:
                break;
            case $info['mime'] === 'image/gif':
            case $info['mime'] === 'image/jpeg':
            case $info['mime'] === 'image/png':
                $ret[] = $path;
        }
    }
    return $ret;
}
```
angular-ui-router が便利すぎてやばいという話

https://github.com/angular-ui/ui-router

URL に状態を記録するステートマシンのようなもの。
動的なアプリケーションでも意識せずにパーマリンクが作れてすごい。
特定のスコープだけ差し替えたいみたいなことがいとも容易く実現できます。
そしてなによりも experimental すぎてやばい。開発は活発なのでしっかり追っていれば大丈夫だとは思いますが。
それでも一度使ってしまうと ngRoute には戻れなくなるくらいの力を秘めてます。

詳しくは wiki と簡単なデモをどうぞ
https://github.com/angular-ui/ui-router/wiki
http://plnkr.co/p9Q60bu0G6qAda2yExzm
Ubuntuでz.shを使う

インストール
----
`git-clone`で`~/.zsh.d`ディレクトリにインストールすることにします。

```shell-session:
$ git clone https://github.com/rupa/z.git ~/.zsh.d/z
```

設定
----
`~/.zshrc`に追記します。
`_Z_CMD`を編集して、デフォルトのコマンドの`z`を、`j`に変更しています。

```zsh:
_Z_CMD=j
source "$HOME/.zsh.d/z/z.sh"
```
WebアプリでDebugビルドとReleaseビルド時にconnectionStringsを切り替える

Webアプリを作ってて、「Debug時とRelease時で勝手にDBの接続先が変わってくれたらなぁ・・・」と思うことはありませんかっ？

かく言う私もソウデシタ・・・。

でもこれ、簡単にできるんですよねぇ。
まず、Web.configに普通にconnectionStringsを書く。

```xml:Web.config
<configuration>
  <connectionStrings>
    <add name="OracleDB" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ホスト名)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=サービス名))); User Id=ユーザー名; Password=パスワード" />
  </connectionStrings>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
</configuration>
```

んで、ソリューションエクスプローラを見てみると・・・なにやらWeb.configに`＞`マークがあるではありませんか？
そこにはWeb.Debug.configと、Web.Release.config・・・あやしいですね！

おもむろにWeb.Debug.configにさっきのconnectionStrings＋αを書く

```xml:Web.Debug.config
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings>
    <add name="OracleDB" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ホスト名)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=サービス名))); User Id=ユーザー名; Password=パスワード" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
  </connectionStrings>
  <system.web>
  </system.web>
</configuration>
```

Web.Release.configにも同様に書く。
で、＋αの部分は以下の所

```xml:connectionStringsの最後
 xdt:Transform="Replace" xdt:Locator="Match(name)"
```

これを書いておけば、ビルド時に置換してくれるんですねぇ。
いやぁ楽になったものです。


>つか、Web.Debug|Release.configのコメントに書いてあるけどな・・・。'\`,､('∀\`) '\`,､
WebアプリからOracleに接続するconnectionStrings（tnsname.ora不要）

Webアプリケーションからデータベースに接続するとき、必要なのはconnectionStrings。
通常、Oracleに繋ぐには`Provider=OraOLEDB.Oracle~`とか`Data Source=myoracleDB`とか書くけれど、たいていの場合は``tnsname.ora``が必要だったりする。

で、いちいち用意してサーバー管理者に「入れて～」というのはものすごくめんどくさい。
なので、tnsname.ora無しで繋いでしまおうというのが以下のconnectionStrings。

```xml:Web.config
<connectionStrings>
  <add name="OracleDB" connectionString="Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=ホスト名)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=サービス名))); User Id=ユーザー名; Password=パスワード" />
</connectionStrings>
```

これを書いて、あとはコード側で

```csharp:DatabaseAccess.cs
using System.Configuration;

string ConnectionString = ConfigurationManager.ConnectionStrings["OracleDB"].ConnectionString;
```

とすれば読み出せる。
楽チンである。

tnsname.ora書いたことがある人ならわかると思うけど、これはtnsname.oraに書いてるままのをWeb.configに書いてるだけだったりする。
分解するとこんな感じ

```text:
Data Source=(
    DESCRIPTION=(
        ADDRESS=(PROTOCOL=TCP)(HOST=ホスト名)(PORT=1521)
    )
    (
        CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=サービス名)
    )
);
User Id=ユーザー名; Password=パスワード
```
インスタンス変数・メソッドに外部からアクセスする方法


・値をセットする場合
setValue: forKey:

・値を取得する場合
valueForKey:

例）

```objc:
- (void)hogehoge
{
        OtherClass *obj = [[OtherClass alloc]init];
        [obj setValue:obj forKey:@"name"];
        NSLog(@"%@", [obj valueForKey:@"name"]);
    }
}
```

・参照：Objective-C Key-Value Coding
http://cx5software.com/blog/2012/01/01/objective-c-key-value-coding/
vimで\を/に変換したりする方法

MacとWindowsが混在する環境で，共有フォルダーのPathを渡されるときに
WindowsでPathを送られると「\」を「/」変換しないとダメだったりします．
そこで毎回置換を行いたいのですが，
Vimの置換コマンドは
:%s/hoge/huga/g
といった感じで，区切り文字に/を使っているので，どうしたものかと悩んでいました．

TwitterのVimmerさん達はすぐに答えを返してくれました．
　　↓
:%s/\\/\//g
:%s#\\#/#g

2回書くことで，文字だと判定しているのですね．
にしても，みなさんどこでこんな知識をえているのやら．不思議です．
rbenvを利用して複数バージョンのRubyをインストール


## brewのアップデート

```
brew update
```

## rbenvのインストール

```
brew install readline ruby-build rbenv
```

## パスの設定

```
export PATH=$HOME/.rbenv/bin:$PATH
eval "$(rbenv init - zsh)"
```
## 再読込

```
source .zshrc
```

## インストール可能なrubyのバージョンを表示

```
rbenv install -l
```
一覧を表示

```
Available versions:
  1.8.6-p383
  1.8.6-p420
  1.8.7-p249
  1.8.7-p302
  1.8.7-p334
  1.8.7-p352
  1.8.7-p357
  1.8.7-p358
  1.8.7-p370
  1.8.7-p371
  1.8.7-p374
  1.9.1-p378
  1.9.1-p430
  1.9.2-p0
  1.9.2-p180
  1.9.2-p290
  1.9.2-p318
  1.9.2-p320
  1.9.3-dev
  1.9.3-p0
  1.9.3-p125
  1.9.3-p194
  1.9.3-p286
  1.9.3-p327
  1.9.3-p362
  1.9.3-p374
  1.9.3-p385
  1.9.3-p392
  1.9.3-p429
  1.9.3-p448
  1.9.3-preview1
  1.9.3-rc1
  2.0.0-dev
  2.0.0-p0
  2.0.0-p195
  2.0.0-p247
  2.0.0-preview1
  2.0.0-preview2
  2.0.0-rc1
  2.0.0-rc2
  2.1.0-dev
  jruby-1.5.6
  jruby-1.6.3
  jruby-1.6.4
  jruby-1.6.5
  jruby-1.6.5.1
  jruby-1.6.6
  jruby-1.6.7
  jruby-1.6.7.2
  jruby-1.6.8
  jruby-1.7.0
  jruby-1.7.0-preview1
  jruby-1.7.0-preview2
  jruby-1.7.0-rc1
  jruby-1.7.0-rc2
  jruby-1.7.1
  jruby-1.7.2
  jruby-1.7.3
  jruby-1.7.4
  maglev-1.0.0
  maglev-1.1.0-dev
  maglev-2.0.0-dev
  mruby-dev
  rbx-1.2.4
  rbx-2.0.0-dev
  rbx-2.0.0-rc1
  ree-1.8.6-2009.06
  ree-1.8.7-2009.09
  ree-1.8.7-2009.10
  ree-1.8.7-2010.01
  ree-1.8.7-2010.02
  ree-1.8.7-2011.03
  ree-1.8.7-2011.12
  ree-1.8.7-2012.01
  ree-1.8.7-2012.02
  topaz-dev
```

## インストール

```
rbenv install 1.9.3-p448
rbenv install 2.0.0-p247
```

## インストールしたrubyの確認

```
rbenv versions
```

一覧

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

## 現在のglobalなrubyのバージョンを確認

```
rbenv global
```

システム標準のrubyが使用されている

```
system
```

## rubyのバージョンを変更

```
rbenv global 1.9.3-p448 
```

変更を確認

```
rbenv global
```

```
1.9.3-p448
```

rubyを起動してバージョンを確認

```
ruby -v
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
```
PHPの参照について


参考: [PHPの参照渡しは関数の引数だけじゃない - cloned.log](http://d.hatena.ne.jp/cloned/20060510)


ポイントは3つ。
- 関数/メソド引数の参照渡し
- 代入の参照代入
- 関数/メソドの参照返し

##引数の参照渡し
　個人的にはこれもよく忘れるのです。仮引数に`&`か実引数に`&`か非常にややこしい気がする。

~~~~PHP:
$v = "default";
rewrite($v);
print $v;

function rewrite(&$arg) {
    $arg = "HelloWorld";
}
~~~~

## 関数/メソドの参照返し
　この辺は動的プログラミングとかで地味に効いてくる。

~~~~PHP:
$hoge = "this is hoge";

function &fuga() {
    return $this->value;
}

$fuga =& fuga();
$fuga = "this is fuga";
var_dump($hoge);//"this is fuga";
~~~~

　関数名と返り値取得の両方に`&`が必要、との事。クラスで可変となるプロパティ部にアクセサつけたりとかそういう感じの時何かと便利。

　受け取るときに`&`抜いたら参照じゃなくなる辺りとかも便利だと思う。

## 参照渡し
　最後に、参照を代入で渡すこともできる。が、まぁあんまり使うことはないとは思う。

~~~~PHP:
$hoge = "this is hoge";
$fuga =& $hoge;
$fuga = "this is fuga";
var_dump($fuga);
~~~~

　ちなみにforeachとかも参照で受け取れる。渡した値を変更する時、とか`$arr[$key]`ってすること多そうだけど、アレだと`$value`側が浮く。それだけの為にわざわざ`array_keys`とか使うのもあれだしねぇ

~~~~PHP:
foreach($arr as $key=>&$value)
{
    $value = "new value";
    //$arr[$key] = "new value"; // これだと$valueが浮く
}

~~~~
オートローダ設計のポイント


オートローダの設計のポイントについて。個人的メモ。

spl_autoloader_registerの使い方については[こちら](http://qiita.com/mikakane/items/47549b2f29263235ca57)

##概要
　ポイントとなるのは以下の様な感じ?

- 読み込みルールについて
    - 名前空間使う?
    - ベースディレクトリは1つ?複数?
- エイリアスルールの有無
- 静的コンストラクタ使うかどうか

##読み込みルールについて
　基本的なところはあんまり変わらないかと。

- クラス名を全部小文字に置き換える。
- 名前空間の区切りをディレクトリ区切りに置き換える。
- _をディレクトリ区切りに置き換える。
- ベースディレクトリから拡張子`.php`で読み込む。

拡張子`.cls`なんてイマドキ使ってる所あるのんかしらん。うちの現場では使ってるみたいです。謎。

　名前空間とか使っちゃうと,レガシーなおっちゃん達の劣等感煽るだけって可能性もあるので現場の雰囲気見てから決めましょう。

　んでポイントはベースディレクトリを複数用意するか否か。この辺りが判断の分岐点。

###ベースディレクトリが複数の場合
　あるクラス名に対して,複数の箇所からの読み取りを試みるようなタイプ。

　`core/classes`ディレクトリがあって,`app/classes`があって…みたいな。　ベース部分とアプリケーション部分、みたいな感じで階層化することが可能。結構便利。と同時に、いくつかの問題も。

　まずクラス名を見ただけで,ファイルの場所を一意に特定できない。あとセキュリティ的な問題とか。同じクラスを使っていても参照先が違う、、、とかね。

###ベースディレクトリがひとつの場合
　クラス名からファイルの場所を一意に決定出来る。まぁ上の形式の逆バージョン。小規模なアプリケーションだとこちらのほうが管理楽だけど、一度作ったクラス同名で処理上書きとかするの面倒。

## エイリアスルールの有無
　上記の基本的なオートローダルールとは別に,再優先で適用されるエイリアスルールを設けるかどうか。これがあるとクラス名とファイル名を紐付けたくない時とか,ベースディレクトリがひとつなんだけどクラス名を変えずに参照先変えたいときとかに対処できる。

　でもまぁやっぱりその分管理はややこしくなる。実装方法としてはグローバルな配列(クラスの静的プロパでも可)とかにクラス名=>パスで登録してオートローダに配列走査させる、みたいな感じになる。

## 静的コンストラクタ使うかどうか
　静的コンストラクタ。あると便利です。実装方法としては

- インターフェイスでやる。
- ダックタイプでやる。

のどっちか。例えば`__init()`とか決めてダックタイプ方式にすると静的コンストラクタの存在知らない開発者が作った`__init()`とかも起動してしまう。その点インターフェイス方式は安全だけど実装がいちいち面倒。implementとか打ってる間に指つるわ。

## コード
　多分汎用的に使える。

~~~~PHP:
call_user_func(function($base_dir){
    $autoload = function($className)use($base_dirs) {
        $file_name = strtolower($className);//小文字に揃えて
        $file_name = str_replace(["\\","_"], DIRECTORY_SEPARATOR, $file_name);//置換して
        
        foreach($base_dirs as $basedir){
            if(is_readable($basedir . $file_name)){
                include $basedir . $file_name;
                break;
            }
        }
    };
    spl_autoload_register($autoload);
}, [__DIR__ . "/classes/",__DIR__."/vendor/"]);
~~~~

　ベースディレクトリを複数にするときには`is_readable`とかで事前にパスのチェックをすればいい。

　インターフェイスで初期化する時は`instanceof`演算子とかで。ダックタイプしたい時は

~~~~PHP:
if (method_exists($class, '_init') and is_callable($class.'::_init'))
{
    call_user_func($class.'::_init');
}
~~~~

みたいな感じで。

参考:
色んなタイプのオートローダとか紹介
http://phpmaster.com/autoloading-and-the-psr-0-standard/
Qiita:Team の投稿を HipChat に通知する Ruby スクリプト

会社で Qiita:Team を使っているのですが、どうにも読み忘れることが多いので、これまた会社で使っているチャットツール HipChat に通知する Ruby スクリプトを組んでみました。

[Qiita gem](https://github.com/yaotti/qiita-rb)があるので簡単でした。

```ruby
require 'hipchat'
require 'qiita'
 
hipchat = HipChat::Client.new(ENV['HIPCHAT_API_KEY'])
qiita = Qiita.new token: ENV['QIITA_API_TOKEN']
 
users = ENV['USERNAMES'].split(',')
users.each do |user|
  items = qiita.user_items user, team_url_name: ENV['TEAM']
  items.select {|item| Time.parse(item.created_at) > (Time.now - 24 * 3600)}.each do |item|
    html = <<-EOF
<a href='https://#{ENV['TEAM']}.qiita.com/#{item.user.url_name}'>#{item.user.url_name}</a>
wrote <a href='#{item.url}'>#{item.title}</a>
at #{item.created_at_in_words}
EOF
    hipchat[ENV['ROOM']].send('Qiita', html, notify: true, color: 'green')
  end
end
```

環境変数が多めなのは Heroku Scheduler で運用する予定だからです。
別途サーバがあるなら、cron で実行するのでも良いでしょう。

チームのメンバー一覧をとるAPIはまだないようなので、ユーザの一覧は自分でしてしないといけないのでそこは少し面倒ですね。追加されないかなー。
iPhoneアプリで本番環境用Push通知の動作確認をする


前回に関連してまたPush通知に関するメモ。

[この記事](http://mihyaeru21.hatenablog.com/entry/2013/05/17/174910)に、本番環境ではテスト出来ないと書いてあったので、「へーそうなんだー」と思っていたのですが、アプリを申請する段階になって、動作確認していない事が不安になり、試しにやってみた所出来たのでメモっときます。

##方法

1. 本番環境のAPNS証明書を発行して、pemファイルに変換してサーバにセットします。

2. XcodeでAd-Hocビルドしたアプリを実機に転送します
参考：[Xcode 4を使ってアドホック版のiOSアプリを作る方法 | aguuu](http://www.aguuu.com/archives/2011/04/xcode-4-ad-hoc/)

3. 動作確認します。

4. おわり


こんな感じでAdH-Hocビルドにすれば本番環境用の動作確認が出来ました。
これで安心して申請できますねー！
コードにコメントを書く上でのポイント

# 概要

コードにコメントを書く上でのポイント。
Pete Goodliffeさん（Code Craft　エクセレントなコードを書くための実践的技法」の著者）の教えの要約です。

# 大切なこと
* ソースコード自体を最高レベルのコメントと考えて、コメントがなくても理解できるコードを書く
* コードと同じように、「見直し」と「修正」を何度も繰り返しながら質を高める

# コメントを書く上でのポイント

## 方法ではなく理由を説明する
処理の内容の説明ではなく、

**なぜそのように書かれているのか？**

という理由や、

**最終的に何が達成されるのか？**

を説明する。


:::note alert
// UserRegistryからのデータで、Registryオブジェクトを更新する。
:::



ではなくて、


:::note info
// 登録情報を後で参照できるようにキャッシュする。
:::


と、 **コードの意図** を説明する。
コメントを書くときは、どちらの種類のコメントを書こうとしているかを常にチェックする。

保守によってコードに手を加える場合でも、その修正によって

**コードの存在理由が変化すること**

は、

**その実現方法を変更すること**

に比べれば少ない。
コメントに理由を記述した場合のほうが、コメント自体の保守作業もずっと楽になる。

また、コメントには「特定の実装方法を選択した理由」を書くことも考えられる。
あるコードの実装方法として2通りの選択肢があって、その一報を採用した場合など、
その選択の根拠を説明するコメントなどがあると良い。


## コードの内容を言い換えただけの説明は避ける


:::note alert
// iを1増やす
i++;
:::


コードの内容を単に繰り返すだけの説明は書かない。

## コメントをコードの代用にしない
言語自体の機構で強制することが可能な制約


:::note alert
// この変数にxxxクラス以外からアクセスしてはならない
:::


この条件を言語の具体的な構文で表現することを検討する。

自分がコードを説明するためのコメントをたくさん書いていることに気づいたら、
とりあえず作業をやめる。
そして、 **先に解決する大きな問題がないか** を考える。

## 役に立つコメントを書く

### 特異な要素や通常は予期しない処理
###  読み手にとって意外に思われる記述
コードを書いた本人でさえ忘れることが多いので、
あとになって「コメントを書いておいて良かった！」と実感できる。

###  正しい情報
コメントがコメントでないのはどんなとき？それは「ウソ」が書いてあるときです。
コメントが記されているコードを修正するときにとてもありがちなので注意する。

### 書く価値のあるコメント
混乱を招くようなコメント、ごく一部の人しか理解できないコメントを書かない。

### 明瞭である
あいまいな記述は禁物。
可能な限り具体的で明確な内容を書くようにする。

:::note alert
// とりあえず無限ループでもしときます
:::



### 理解しやすい
読んで理解できるもの。
とくに略語等は読み手を混乱させることがある。


:::note alert
// 彼がSGGKかどうかの判定
// FPMPの威力を測定する
:::


#　まとめ
* コメントは量より質！
* より少なく、良質のコメントを書くように努める。
* 理由を説明するコメントを書く。
* コメントをたくさん書くより、優れたコードを書くことに集中する。

> Pete Goodliffe『Code Craft～エクセレントなコードを書くための実践技法～』、毎日コミュニケーションズ、2007年。
cd -P

シンボリックリンク先のディレクトリに移動します。

```bash:
$ ls -l wiki
lrwxrwxrwx 1 username username 44  8月 22 14:14 wiki -> /home/htdocs/public/wikitten/library
$ cd -P wiki
$ pwd
/home/htdocs/public/wikitten/library

```
さくらVPSに複数のMacからSSH接続（２台目以降）



###SSHキーの作成

```
% cd ~/.ssh
% mkdir sakura_vps
% cd sakura_vps
% ssh-keygen -t rsa -C "任意のコメント" //コメントはなんでもいいらしいです

//セキュリティ強化
% chmod 600 作成した秘密鍵
```

###Rootとパスワードでのログインを許可する（VPS側）

`/etc/ssh/sshd_config`を以下のように編集

```/etc/ssh/sshd_config
// パスワードログインを許可
PasswordAuthentication yes

// rootログインを許可
PermitRootLogin yes
```
```
// sshdリスタート
% service sshd restart
```

###公開鍵をさくらVPSに送信（Mac側）
scpで公開鍵を送信

```
% sudo scp -P sshのポート番号 ~/.ssh/sakura_vps/公開鍵 root@xxx.xxx.xxx.xxx:/home/USERNAME
```

###sshdの再設定と公開鍵の追加（VPS側）

先ほど編集した`/etc/ssh/sshd_config`を以下のように再編集

```/etc/ssh/sshd_config
// パスワードログインを禁止
PasswordAuthentication no

// rootログインを禁止
PermitRootLogin no
```
```
// sshdリスタート
% service sshd restart
```

先ほど送信した公開鍵を`~/.ssh/authorized_keys`に追記

```
cat 送信した公開鍵 >> .ssh/authorized_keys 
```

### ホスト名を設定

`~/.ssh/config`に以下の内容を追加

```~/.ssh/config
HOST sakura_vps
    HostName      xxx.xxx.xxx.xxx
    Port          SSHのポート番号
    User          ユーザ名
    identityfile  ~/.ssh/sakura_vps/秘密鍵
```

以上の設定で

```
% ssh sakura_vps
```
で、ログインできます。

##参照
・[03.さくらインターネットVPSを使ってみる。〜複数のMacからssh接続〜](http://www.aguuu.com/archives/2010/09/sakura_internet_vps_03/ "03.さくらインターネットVPSを使ってみる。〜複数のMacからssh接続〜")
Chefのレシピでmysql_secure_installation(bashリソース利用)

<!-- too_old -->
> **この記事は最終更新から1年以上経過しています。** 気をつけてね。


まず`mysql_secure_installation`するじゃないですか。もののついでにChefでやっておこうと思いました。

`mysql_secure_installation`実行時の質問を抜粋。

1. Change the root password [Y/n]
2. Remove anonymous users? [Y/n]
3. Disallow root login remotely? [Y/n] 
4. Remove test database and access to it? [Y/n] 
5. Reload privilege tables now? [Y/n]

で、同様のことを実施。

```ruby:mysql_secure_install.rb
bash 'mysql_secure_install emulate' do
  code <<-"EOH"
    /usr/bin/mysqladmin drop test -f
    /usr/bin/mysql -e "delete from user where user = '';" -D mysql
    /usr/bin/mysql -e "delete from user where user = 'root' and host = \'#{node[:hostname]}\';" -D mysql
    /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'::1' = PASSWORD('newpassword');" -D mysql
    /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpassword');" -D mysql
    /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpassword');" -D mysql
    /usr/bin/mysqladmin flush-privileges -pnewpassword
  EOH
  action :run
  only_if "/usr/bin/mysql -u root -e 'show databases;'"
end
```

パスワードは`encrypted_data_bag`に置くとして、フルbashじゃないですか。

> 追記： `3. Disallow root login remotely? [Y/n] `に当たる処理はコメント欄にある方が適切です。

## result

試してみます、パスワード無しでmysqlに接続できるようなら`mysql_secure_installation`相当の処理をさせます。

```shell:chef-apply
# cat <<'EOL' | chef-apply -s
> bash 'mysql_secure_install emulate' do
>   code <<-"EOH"
>     /usr/bin/mysqladmin drop test -f
>     /usr/bin/mysql -e "delete from user where user = '';" -D mysql
>     /usr/bin/mysql -e "delete from user where user = 'root' and host = \'#{node[:hostname]}\';" -D mysql
>     /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'::1' = PASSWORD('newpassword');" -D mysql
>     /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpassword');" -D mysql
>     /usr/bin/mysql -e "SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpassword');" -D mysql
>     /usr/bin/mysqladmin flush-privileges -pnewpassword
>   EOH
>   action :run
>   only_if "/usr/bin/mysql -u root -e 'show databases;'"
> end
> EOL
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * bash[mysql_secure_install emulate] action run
    - execute "bash"  "/tmp/chef-script20130822-12249-10qdpq7-0"
```

```shell:mysql_user_table
# mysql -e 'select user,host,password from user;' -D mysql -pnewpassword
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *FE4F2D624C07AAEBB979DA5C980D0250C37D8F63 |
| root | 127.0.0.1 | *FE4F2D624C07AAEBB979DA5C980D0250C37D8F63 |
| root | ::1       | *FE4F2D624C07AAEBB979DA5C980D0250C37D8F63 |
+------+-----------+-------------------------------------------+
```

まあできてるか。

２度目以降は`only_if`が効いてお断りしてくれます。

```
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * bash[mysql_secure_install emulate] action run (skipped due to only_if)
```
Facebook Chat APIでメッセージ送信がひっそり失敗する場合

Facebook Chat APIを使ってメッセージ送信をしていたのだが、ごくまれに一定周期（？）でメッセージ送信が失敗する。その場合の条件が下記。

* 日本語が含まれている（恐らく半角英数以外の文字が入っている、だろう）
* ある一定の時間の間断続的に（一度失敗し出すと暫く失敗。暫くするとまた成功する）

ローカルのMacからやっても、Herokuからやっても同じ事が起こった。MacとHerokuの周期はかなり近い気がする。どちらか失敗すると両方失敗してしまう可能性が高い。

恐らくメッセージ送信は半角英数で構成した方が無難。


この件は本当にそうなのかどうか怪しい部分もあります。もしもどこかで同じような問題に当たった人がいたらお話伺いたい気持ちもあり、書いておきます。自分の環境は下記です。
http://qiita.com/ms2sato/items/d111d22ebebaea447c3e

ひょっとしたら利用しているライブラリや環境の問題かもしれません。まだそこまで追い込めていません。
Unite.vimで.gitignoreで無視したファイルを候補から除外する

Unite.vimでfile_recとかgrepとかでvendor/bundle以下のgemとかが出てきてウザいときがある。そこで`.gitignore`で無視したファイルを候補から除外するように設定した。

```vim:.vimrc
" .gitignoreで指定したファイルと.git/以下のファイルを候補から除外する
function! s:unite_gitignore_source()
  let sources = []
  if filereadable('./.gitignore')
    for file in readfile('./.gitignore')
      " コメント行と空行は追加しない
      if file !~ "^#\\|^\s\*$"
        call add(sources, file)
      endif
    endfor
  endif
  if isdirectory('./.git')
    call add(sources, '.git')
  endif
  let pattern = escape(join(sources, '|'), './|')
  call unite#custom#source('file_rec', 'ignore_pattern', pattern)
  call unite#custom#source('grep', 'ignore_pattern', pattern)
endfunction
call s:unite_gitignore_source()
```

Vim Scriptはほとんど書いたことがないのでアレかもしれない。ただ`.gitignore`を一行ずつロードしてリストに追加してjoinしてエスケープしてUnite.vimの設定に追加してるだけ。ついでに`.git`以下も除外するようにした。
EC2+Mercurial+Rails環境でcapistranoを使ったデプロイ方法


EC2+Mercurial+Railsという少し限定的な環境でのデプロイ設定方法。

[前提条件]
リポジトリが存在する。
デプロイサーバーが存在する。
デプロイ先のサーバーが存在する。
デプロイサーバーにmercurialがインストールされている。
(mercurialのバージョンは1.7以上)


##デプロイユーザー作成
SSHで接続可能なdeployユーザーを作成する。
http://qiita.com/dahugani/items/e1fc5c212bf6a7365f8f

##capistranoのインストール
gemからcapistranoする。
ついでに色を変えたり、環境先を変えたり、railsアプリ以外をデプロイできるなど設定ができるgemも入れる。

```Gemfile
gem 'capistrano'
gem 'capistrano-ext'
```
capistranoはコメントインでもいい。

##AWS-SDKインストール

Gemfileにaws-sdkを追加

```Gemfile
gem 'aws-sdk'
```
```
bundle install
```

##capistranoの設定

設定ファイルの作成

```
capify .
```
EC2+bitbucket+rails用に書き換える(全てを書き換える)。

```deploy.rb
require 'rubygems'

#AWSdefine
set :aws_access_key_id,     ENV['アクセスキー']
set :aws_secret_access_key, ENV['シークレットキー']

set :application, "linknet"
set :deploy_to, "/var/www/apps/#{application}"
set :repository,  "リポジトリのURL"
# set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
set :scm ,:mercurial
set :deploy_via, :copy

# The address of the remote host on EC2 (the Public DNS address)
set :location, "EC2のホスト名"

set :user, "デプロイ用ユーザー名"
set :use_sudo, false
ssh_options[:forward_agent] = true
ssh_options[:keys] = ["デプロイ用ユーザーの秘密鍵"]
default_run_options[:pty] = true

# setup some Capistrano roles
role :app, location
role :web, location
role :db,  location, :primary => true
```

セットアップのコマンドを実行する。

```
cap deploy:setup
```
EC2にSSH接続用のユーザーを作成する


EC2に対してcapistranoでデプロイするためにはSSH接続できるユーザーが必要になる。
今回はdeployユーザーを作成する。

##ユーザー作成
既存ユーザー(ec2-user)EC2に接続する。

```
ssh -i /home/vagrant/.ssh/XXX.pem ec2-user@XX.XXX.XXX.XXX
```

ユーザーを作成する。

```
useradd deploy
passwd deploy
```

sudoができるように/etc/sudoersファイルを変更する。
(sudo vi /etc/sudoersだと読み取り専用になってしまうので次のコマンドでファイルを開く)

```
sudo visudo
```

ファイルに１行追加する。
rootに同じ設定があるので、そのすぐ下に追加するといい。

```etc/sudoers
deploy    ALL=(ALL)       ALL
```

##鍵の作成

作ったユーザーに変更して鍵を作成する。

```
sudo su - deploy
cd /home/deploy
mkdir .ssh
cd .ssh
ssh-keygen -t rsa
mv id_rsa.pub authorized_keys
```

※ファイル名を書き換えるのはAMILinuxのSSHの初期設定がauthorized_keysとなっているため。

権限を変更する。

```
chmod 600 authorized_keys
cd ../
chmod 700 .ssh
```
※権限が適切でないと後にSSH接続できなくなる。

ローカルに秘密鍵をコピーする。
catで中身を確認してそれをローカルに保存しておく。

```
cat id_rsa
```
※後でssh接続に必要なのでホームの.sshなどに入れておくといい。


##SSHの設定
設定ファイル/etc/ssh/sshd_configを確認する。

```
vi /etc/ssh/sshd_config
```次の記述があることを確認する。
なければ追加する。```/etc/ssh/sshd_configAuthorizedKeysFile      .ssh/authorized_keys
```

※AMILinuxは初期状態でこれが記述されている。


##接続の確認

接続できれば無事終了。

```
ssh -i /home/vagrant/.ssh/id_rsa deploy@XX.XXX.XXX.XXX
```
WebGLで作られた作品まとめ


サイトで見つけた、WebGLで作られた作品をまとめていきます。
随時更新予定。

![sample1](http://f.cl.ly/items/3W3W1H3U3k243J0Y3y3I/webgl-sample1.jpg)
http://do.adive.in/music/

![sample2](http://f.cl.ly/items/0K0v2d3J2K1043103V10/webgl-sample2.jpg)
http://www.eveonline.com/universe/spaceships/magnate/

![sample3](http://f.cl.ly/items/2f3s0r0c0M1T3G0N0N2q/webgl-sample3.jpg)
http://www.ro.me/
Starling Framework使う時のコピペ用ドキュメントクラス


```as3:starlingTemplate.as
package 
{
    import starling.core.Starling;

    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Rectangle;

    /**
    * starling つかうときのコピペ用ドキュメントクラス
    */
    public class StarlingSample extends Sprite
    {
        private var _starling : Starling;
        public function StarlingSample()
        {
            if(stage) _initialize(null); 
            else  addEventListener(Event.ADDED_TO_STAGE, _initialize);
            
        }

        private function _initialize(event : Event) : void
        {
            removeEventListener(Event.ADDED_TO_STAGE, _initialize);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            this.mouseEnabled = false;
            this.mouseChildren = false;
            this.loaderInfo.addEventListener(Event.COMPLETE, loaderInfo_completeHandler);
        }

       

        private function loaderInfo_completeHandler(event : Event) : void
        {
            Starling.handleLostContext = true;
            Starling.multitouchEnabled = false;

            _starling = new Starling(Main, stage);
            _starling.enableErrorChecking = true;
            _starling.start();

            this.stage.addEventListener(Event.RESIZE, stage_resizeHandler, false, int.MAX_VALUE, true);
            this.stage.addEventListener(Event.DEACTIVATE, stage_deactivateHandler, false, 0, true);
        }

        private function stage_resizeHandler(event : Event) : void
        {
            _starling.stage.stageWidth = stage.stageWidth;
            _starling.stage.stageHeight = stage.stageHeight;

            const viewPort : Rectangle = _starling.viewPort;
            viewPort.width = stage.stageWidth;
            viewPort.height = stage.stageHeight;
            try {
                _starling.viewPort = viewPort;
            }
            catch(error : Error) {
            }
        }

        private function stage_deactivateHandler(event : Event) : void
        {
           _starling.stop();
            stage.addEventListener(Event.ACTIVATE, stage_activateHandler, false, 0, true);
        }

        private function stage_activateHandler(event : Event) : void
        {
            stage.removeEventListener(Event.ACTIVATE, stage_activateHandler);
            _starling.start();
        }
    }
}
```
とりあえず設定ファイルの修正くらいできるVimの使い方

たまにどうしてもLinux上でテキストを修正しないといけない場合がある。
そのたび毎度リファレンス片手に、たどたどしく修正するのをやめようと思った。

入門書などでは新規作成の手順から入るけれど、
個人的にViで必要となる動作の需要は以下の順序になる。
>
1,既存テキストの確認
2,既存テキストの修正
3,テキストの新規作成

ので、上記の順で、手順を書いていく。

---


### ファイルの確認（読み取り専用）
対象のファイルがある場所まで移動して

``` 
view ファイル名
```
「vi -R」と同義。
読み込み専用でファイルを開く。
Vi慣れてない内は、誤って編集してしまいそうになるので、これが安全。
下記はtestのみ書かれたテキストを開いた状態。
![スクリーンショット 2013-08-21 16.46.11.png](https://qiita-image-store.s3.amazonaws.com/0/27781/3dd20985-bfec-f696-9b3d-f45ce0a0dfd7.png)

* ファイルを閉じる

```
:q 
:q!    //強制終了
```
 誤って修正した場合保存せず閉じたい場合は！をつける
viewコマンドから使われることはないはず。新規や編集の際に使用。

---

### ファイルの編集
``` 
vi 既存ファイル名
```
testと書かれたテキストファイルを開いている状態。
![スクリーンショット 2013-08-21 18.01.55.png](https://qiita-image-store.s3.amazonaws.com/0/27781/25e329f2-3cca-5275-f5ab-80b26540427c.png)

viは開いた直後はコマンドモードになっているため入力できない。
入力するには` i`キーを入力する。 

``` 
i      //入力モード
Esc //元に戻す
```

セットで覚えておいた方がいい。
入力モードに移行して、左下がINSERTになっているのが確認できる。
![スクリーンショット 2013-08-21 18.11.30.png](https://qiita-image-store.s3.amazonaws.com/0/27781/20933400-d66d-a755-bd71-d5d7ac970ca7.png)
入力
![スクリーンショット 2013-08-21 18.14.23.png](https://qiita-image-store.s3.amazonaws.com/0/27781/bb81508d-56eb-2e9d-b47d-b53db0aaa460.png)
入力終わったらコマンドモードに移行（Escキー）

``` 
u      //やり直す
Ctrl + R //元に戻す

:w //保存
```

ショートカットキー的な挙動はすべてコマンドモードで、
入力モードに関しては、本当に文字のみの入力という感じだろうか。

編集のときと同じく:qで終了
![スクリーンショット 2013-08-22 12.12.10.png](https://qiita-image-store.s3.amazonaws.com/0/27781/57c125be-6b98-9c65-7ed0-507a3c123f37.png)
コマンドモードかつ、半角英数字の入力であれば、左下にコマンドが表記される。

編集して保存せずに:qで閉じようとすると怒られる。
![スクリーンショット 2013-08-21 19.06.17.png](https://qiita-image-store.s3.amazonaws.com/0/27781/b53b6ee2-fe39-0a41-4449-55c31ac4bb92.png)
:wで保存するなり、:q!で保存せず終了なりで対応すること。

---
### ファイルの新規作成

``` 
vi 新規ファイル名
```
左下がNewFileとなっているが、基本的に編集と同じように操作してよい（はず）
![スクリーンショット 2013-08-22 12.07.32.png](https://qiita-image-store.s3.amazonaws.com/0/27781/d7fe218c-35d9-7389-5b96-72a7f551cd06.png)

ファイル名を指定しないと、タイトル画面が表示されたり、
![スクリーンショット 2013-08-22 12.17.44.png](https://qiita-image-store.s3.amazonaws.com/0/27781/64488ee9-6f6c-1581-c92d-fa1f8e8e1661.png)
vi新規起動時のタイトル画面はCtrl + L（画面再描写）で消える。

また、新規時にファイル名を指定していないので、
保存する際には引数にファイル名を指定すること。
![スクリーンショット 2013-08-22 12.26.23.png](https://qiita-image-store.s3.amazonaws.com/0/27781/7486e536-ad4d-099d-3c57-f9e9787566ae.png)


---

</br>
補足
テキスト量が多い場合、上記のみだと厳しいので。。。


``` 
//vi起動中からの行表示
:set num
:set number
```
![スクリーンショット 2013-08-22 12.47.00.png](https://qiita-image-store.s3.amazonaws.com/0/27781/61b58ac3-2d42-b78c-1526-b5afc212eea8.png)


| コマンド | 挙動 | 
|:-----------|------------:|
| Ctrl + F       |        画面1ページ分進む | 
| Ctrl + B       |        画面1ページ分戻る | 
| :行番号       |        カーソルを指定行に進む | 
| /文字列       |       検索 |
Wikittenの見栄えを修正した

wikittenとは
====
* [公式HP](http://wikitten.vizuina.com/)
* markdownで記述したファイルをwebブラウザでいい感じに表示してくれる君。
* 各種言語対応 (sh,php,css,python,ruby,sql,xml)
* Webでの編集機能が無かったが[EightMinusEight](https://github.com/EightMinusEight)さんができるようにしました。今回、これをフォークして手を加えました。

修正前
----
![](https://github-camo.global.ssl.fastly.net/49c07895d2ee3d967776e244f5af092a2fed17ed/687474703a2f2f77696b697474656e2e76697a75696e612e636f6d2f73637265656e73686f742e706e67)

修正後
----
![修正後.PNG](https://qiita-image-store.s3.amazonaws.com/0/25728/52f2a1db-78f0-155e-2187-2f2b8f06ab59.png)

修正内容
----
1. Alt-T でソースをトグル表示、Alt-S で保存、Alt-C でContentタブに切り替え。
1. 猫消した。
1. 最初から編集許可。
1. ツリーで画像ファイルの場合は画像アイコンを表示するようにした。また拡張子を非表示にした。
1. ツリーで画像リンクをクリックすると、同一ウィンドウで表示するように修正した。
1. h1〜h5,aタグなどをqiitaのものにした。
1. ページ表示した時、検索枠にフォーカスが移るのをコンフィグで切り替えられるようにした。

インストール
====

```bash:
$ cd /var/www
$ sudo git clone https://github.com/tukiyo/Wikitten.git
```

```bash:
$ sudo ln -s /etc/apache2/mods-available/rewrite.load \
  /etc/apache2/mods-enabled/
$ sudo /etc/init.d/apache2 restart
```

http://localhost/Wikitten でアクセスできます。


sambaでlibraryを共有
====

/var/www/Wikitten/library/ が文書データなので、自由なテキストエディタで編集できるようにsambaで共有する。
その際、ファイル権限の問題があるため、以下のスクリプトを用意してcronで定期的に修正かける。

```bash:chown_wiki_library.sh
#!/bin/sh
PATH_WIKI_LIBRARY=/var/www/Wikitten/library
chown -R www-data:www-data $PATH_WIKI_LIBRARY
chmod -R 777 $PATH_WIKI_LIBRARY
```

```bash:cronに追加
*/5 * * * * /root/cron/chown_wiki_library.sh
```

download
====
* [download](https://github.com/tukiyo/Wikitten.git)
商品名・・・・・・100円とかの「・・・」を作るJS

よく、商品一覧ページとかである

```
商品名1・・・・・・・100円
商品名2・・・・・・1,000円
商品名その３・・・10,000円
商品名その4・・・・・・10円
```

の「・・・」の部分を作るJS。

背景がベタ塗りならCSSだけで出来るけど、背景にテクスチャ敷いてたりしてると難しい（CSSだけでは無理？）だと思ったので、JS使って実現させる事に。

<del>しかし、「・・・」ってなんて言いうんだろう。
勝手にdotListとかいう名前にしちゃったけど、それだと

```
・ほげほげ
・ふがふが
```

と混同するよね・・・。
</del>

調べたら「リーダー」で良いみたいなので、leaderListにしました。
http://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC_(%E8%A8%98%E5%8F%B7)


```html:HTML
<div class="leaderList"><span class="left">ほげほげ</span><span class="dot"></span><span class="right">1,000円</span></div>
<div class="leaderList"><span class="left">ふがふがぴよ</span><span class="dot"></span><span class="right">100円</span></div>
<div class="leaderList"><span class="left">うわぁぁぁぁぁぁぁ</span><span class="dot"></span><span class="right">900円</span></div>
```

```css:CSS
div.leaderList{
  margin: 5px 0;
  width: 400px;
  overflow: hidden;
}

div.leaderList span.left {
  display: block;
  float: left;
}

div.leaderList span.right {
  display: block;
  float: right;
}
```

```js:JavaScript
/**
 *	ほげ・・・・・・・・100
 *	ふがふが・・・1000
 *	とかの「・・・」を作る
 *	
 *	@param	element (jQueryElemet)
 *	@param	imagePath (ドット画像のURL)
 *	@param	margin (ドット画像のマージン)
 *
 */
function addLeaderList(element, imagePath, margin){
	var margin = margin || 0;
	element.each(function(){
		var dWidth = parseInt($(this).width());
		var dHeight = parseInt($(this).height());
		var lWidth = parseInt($(this).children('.left').width());
		var rWidth = parseInt($(this).children('.right').width());
		
		var dotElement = $(this).children('.dot')
		dotElement.css({
			margin: margin,
			display: 'inline-block',
			height: dHeight + 'px',
			width: dWidth - (lWidth + rWidth) - 10 + 'px',
			background: 'url(' + imagePath + ') repeat-x left bottom'
		});
	});
}

addLeaderList($('.leaderList'), 'image/dot.gif', '0 5px');
```