OmniAICreator/Qiita-1.07M huggingface dataset:
RubyでYouTube Data APIを利用したときのメモ


動画情報の設定をプログラムでしたいのでYouTube Data APIをRubyで叩いた。
ライブラリは[google-api-client](https://github.com/google/google-api-ruby-client)を利用した。


# 準備

まずAPIを有効化する。YouTube Data API。

[デベロッパコンソール](https://console.developers.google.com/) > APIと認証 > API

クライアントを登録して、登録情報をダウンロードする。

[デベロッパコンソール](https://console.developers.google.com/) > APIと認証 > 認証情報

OAuth で新しいクライアントIDを作成。
ローカルで利用するのでネイティブアプリケーションを選択。
JSONをダウンロードして`client_secrets.json`でカレンドディレクトリに保存。
(この名前だとライブラリが自動認識する)

# APIを利用する。

client.execute で api_method を指定して実行するだけ。
どんなパラメータをとるかはドキュメントに記載されている。

https://developers.google.com/youtube/v3/docs/videos/update?hl=ja

動画情報の更新には `youtube.videos.update` が使える。
parametersのpartにはどの部分の情報を更新するか設定する。
タイトルや概要はsnippetというpartにある。

bodyには情報を渡す。
partにsnippetを指定しているのでsnippetの値をセットする。
情報は基本的にすべて設定する必要がある。
元の値がどうなっているのか知りたい場合はlistapiを叩くと良い。

```ruby
#!/usr/bin/env ruby
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'

client = Google::APIClient.new(
  :application_name => 'youtube updater',
  :application_version => '1.0.0'
                              )

youtube = client.discovered_api('youtube','v3')

client_secrets = Google::APIClient::ClientSecrets.load

flow = Google::APIClient::InstalledAppFlow.new(
  :client_id => client_secrets.client_id,
  :client_secret => client_secrets.client_secret,
  :scope => ['https://www.googleapis.com/auth/youtube']
)
client.authorization = flow.authorize

body = {
  id: video_id # YouTubeのURLの ?v=hogehoge のhogehoge
  snippet: {
    title: 'hoghoge',
    categoryId: '22',
    tags: [],
    description: 'hogehoge'
  }
}

client.execute(
  api_method:  youtube.videos.update,
  parameters: {part: 'snippet'},
  body_object: body )
end
```

# 参考文献

https://developers.google.com/youtube/v3/?hl=ja
https://developers.google.com/youtube/v3/docs/videos/update?hl=ja
iPhoneアプリがRejectされてしまった


一週間ほど前にVer1.1として、バージョンアップしたアプリを審査依頼していましたが、昨晩Rejectされてしまいました。備忘録を兼ねて記録しておきます。
## 背景
- 2/1 プログラムの勉強を始める（Swift）
- 2/21 初めて作ったアプリ「SpaceShooter」をアップロード
- 2/28 審査を無事にクリア！（AppStoreに並ぶ）
- 3/5  細かなバージョンアップをして再度審査依頼
- 3/12 下記理由でリジェクト
- 3/13 プログラムを修正して再度審査へ提出

## 理由
> 2.9 - Apps that are "demo", "trial", or "test" versions will be rejected. Beta Apps may only be submitted through TestFlight and must follow the TestFlight guidelines

> - 2.9 Details
Your app contains references to test, trial, demo, beta, pre-release or other incomplete content. 
Specifically the application shows a frames per second rate as well as node count in the bottom right corner of the app.
We’ve attached screenshot(s) for your reference.

> - Next Steps
Please remove all references to “demo,” “trial,” “beta,” or “test” in your application description, app icon, screenshots, previews, release notes, and binary.

スクリーンショットも付けて「ここがダメだよ」と指摘してくださってました。
アップしたソースを確認してみると、ものの見事にFPSとNodeCountを表示しっぱなしでした…。
初歩的なミスで、本当に申し訳ないことをしてしまいました。
これを教訓に、アップロード前に確認すべき項目をチェックリスト化します。

## 対応方法
- Buildの変更
XcodeからBuildのバージョンを変更します。
※今回、iTunesConnectからバージョンを上げることができなかったため、Buildだけを変更し対応しました。

- プログラムを修正
今回は、FPSとNodeCountを表示しないようにコメントアウトしました。

- アーカイブのアップロード
普段アーカイブをアップロードする手順と同様、iOS Deviceに切り替えてアーカイブし、サブミットします。

バイナリを再アップロードしたら、問題解決センターからお礼のメッセージを送信しようと思っていたのですが、バイナリを上げ直したタイミングで、返事が書けなくなっていました。
泣けなしの英語力でせっかく書いたのに…苦笑

> Thank you for review of my app.
I apologize for making a mistake.
I corrected the issue, FPS and nodeCount displayed on the screen.
I would appreciate it if you review my app again.

## 余談
バイナリアップ後、すぐに"審査へ提出"を押すと、以下のようなエラーが発生しました。
> App情報を保存できませんでした。もう一度やり直してください。問題が解決しない場合はご連絡ください。

下記記事の現象に引っかかっていたようです。
しばらくして再申請したところ、無事アップロードできました。
[App 情報を保存できませんでした。もう一度やり直してください。](http://matty-studio.jp/post-161/)

## 参考
[iOSアプリ審査Reject　～再審査・再申請手順～](http://examination-03.hatenablog.com/entry/2014/08/29/iOS%E3%82%A2%E3%83%97%E3%83%AA%E5%AF%A9%E6%9F%BBReject_%EF%BD%9E%E5%86%8D%E5%AF%A9%E6%9F%BB%E3%83%BB%E5%86%8D%E7%94%B3%E8%AB%8B%E6%89%8B%E9%A0%86%EF%BD%9E)
ランダムなFizzBuzz列をソートするためにクイックソートを学ぶ

はじめに
---
ランダムなFizzBuzz列をソートするために、クイックソートを学ぶことにした。

クイックソートとは（他サイトから引用）
---
クイックソートは、データの比較と交換回数が非常に少ないのが特徴で、一般的なばらばらデータ（ランダムに散らばっているデータ）に対して、最も効率良く並べ替えを実行します。

クイックソートは、実用上もっとも高速であるとされている並べ替えアルゴリズムで、多くのプログラムで利用されています。
http://www.ics.kagoshima-u.ac.jp/~fuchida/edu/algorithm/sort-algorithm/quick-sort.html

コード
---
上記サイトに載っているJavaのコードを（たぶんほぼそのまま）pythonに置き換えてみた。

```py
import random
def make_randoms(start=1,finish=100):
  seq = range(start,finish+1)
  randoms = []
  while seq:
    randoms.append(seq.pop(random.randint(0,len(seq)-1)))
  return randoms

def pivot(target, i, j):
  k = i + 1
  while k <= j and target[i] == target[k]: k += 1
  if k > j: return -1
  if target[i] >= target[k]: 
    return i
  else:
    return k

def partition(target, i, j, x):
  l, r = i, j
  while l <= r:
    while l <= j and target[l] < x: l += 1
    while r >= i and target[r] >= x: r -= 1
    if l > r: break
    target[l], target[r] = target[r], target[l]
    l, r = l + 1, r - 1
  return l

def quick_sort(target,i ,j):
  if i == j: return 
  p = pivot(target, i, j)
  if p != -1:
    k = partition(target, i, j, target[p])
    quick_sort(target, i, k-1)
    quick_sort(target, k, j)
```

FizzBuzz列をソートするための懸念点
---
大小関係を判断しているところが多すぎる。どうしよう？
EC2でnginxの過剰な404|403に対しfail2banをかける

nginxで404を発生させる攻撃が増えてきたため、いくつかのセキュリティ対策しました。
そのうちの一つとして、fail2banを使って404を過剰に発生させるホストについては一時的に受付ないようにします。


###まずはインストール

```bash
#インストール
yum install fail2ban

#起動時に自動起動
chkconfig --add fail2ban
chkconfig fail2ban on
```

###log設定

```bash
vim /etc/fail2ban/fail2ban.conf
```

```bash:fail2ban.conf
# logtarget = SYSLOG  # ←これをコメントアウト
logtarget = /var/log/fail2ban/fail2ban.log # ←これを追加
```

```bash
mkdir /var/log/fail2ban/
```

###filterを追加する

```bash
vim /etc/fail2ban/filter.d/nginx-404.conf
```

```bash
[Definition]
failregex =  ^<HOST>.*"(GET|POST).*" (403|404) .*$
ignoreregex =
```

404か403の時に評価する

###banする設定

```bash
vim /etc/fail2ban/jail.local
```

```bash:jail.local
[nginx-404]
enabled = true
port = http,https
filter = nginx-404
logpath = /var/log/nginx*/*access.log
action = iptables-multiport[name=404, port="http,https", protocol=tcp]
maxretry = 5
findtime = 30
bantime = 7200
```

「30秒の間に5回404出したら、7200秒BANする」という意味です。

※注意：どのくらいの閾値かは、一概には言えません。特に今回のシステムでのaccess.logは画像やjs,cssなどのログを吐かない設定にしてあります。もし画像やcssなどもアクセスログとして履いている場合、気づかない404が正しいユーザーにも発生して、BANしてしまうリスクがあります。この辺はちゃんと理解し、テストした上でやりましょう。

###logrotateの設定

```bash
vim /etc/logrotate.d/fail2ban
```

```bash:fail2ban
/var/log/fail2ban/fail2ban.log {
    missingok
    notifempty
    weekly
    rotate 5
    compress
    dateext
    create 0644 root root
    postrotate
        /usr/bin/fail2ban-client set logtarget /var/log/fail2ban/fail2ban.log 2> /dev/null || true
    endscript
}
```

###準備完了。開始！

```bash
service fail2ban start
```


###必要があればホワイトリストを設定する

```bash
vim /etc/fail2ban/jail.conf
```

```bash:jail.conf
ignoreip = 127.0.0.1/8 xxx.xxx.0.0/16
```
CPUのベンチマーク SPEC CPU2006の見方

CPUのサイジング方法がわからないと言われて
SPECintの見方をまとめ。
これでベンダーから高いサーバを買わされずに済む（といいなあ）

※あくまで一般的です！ベンチを鵜呑みにすると痛い目を見ます！

#SPEC CPU2006

##SPEC
SPEC(Standard Performance Evaluation Corporation)は、コンピュータの公平で意味のあるベンチマークを作成することを目指して設立された非営利団体です(wikipediaより)

各ベンダーがベンチマークを提供して成り立っています。
素晴らしいですね！

https://www.spec.org/cpu2006/
ここから調べることができます

##2つのベンチマーク指標
CPUのベンチマーク指標には大きく分けて2つあります

**スピード**
ある単位のタスクをどれくらい早く完了できるか

**スループット**
単位時間あたりにどれだけのタスクを完了できるか

SPEC CPUでは、CPU・メモリアーキテクチャ・コンパイラを複合した性能、と位置づけています。
なので、実際にデータを見てみると各ベンダーのサーバーの情報が細かく載っていると思います。
実際の運用結果に近い、意味のあるベンチマークを目指しているということですね。

##2つのテスト
SPEC CPUでは2つのテストがあります。

**CINT2006**
整数演算により評価するテスト

**CFS2006**
浮動小数点演算により評価するテスト

整数演算と浮動小数点演算の話は長くなりますが、、、
わかりやすく言うと単純計算か複雑な計算か、ということです。
CPUは独立したユニットを持っているので、
整数演算が得意で浮動小数点演算が苦手、なんてCPUも多々あります。
（昔は整数演算はIntel、浮動小数点演算はAMDなんて言われてましたよね…）

目的に合わせて見るテストを選びましょうってことですね！

私はサーバ屋なんでもっぱらCINTしか見ないです。
CAD?レンダリング?あばばば...

##コンパイルの手法
コンパイルの手法が２パターン、公開されています
右上に書いてある、SPECint_base のbaseの部分などですね！

**Base metric**
すべてのプログラムで同じコンパイルオプションを使用した結果

**Peak metric**
それぞれのプログラムでコンパイルオプションを適切に変更して、測定した結果

##スピードとスループット
シングルタスクとマルチタスクの結果も公開されています

**SPEC speed metric**
一つのタスクを完了するのにかかった時間を評価した結果

**SPEC rate metric**
複数のタスクを同時に実行したときのスループットの合計から評価した結果

##調べ方
https://www.spec.org/cpu2006/
にアクセスして、
左上のResults Searchか最下部のSearchのリンクをクリック

プルダウンをProcessor(CPU型番)などに変えて、
CPUの型番を入れて（E3-1230とか）検索するだけ！

##なんとなくサイジングするとき
「なるはやでヨロ！」みたいなことを言われた時の計算方法
１）現行のCPUのCINT2006 Ratesを確認
２）スレッド数とCINT2006 Ratesが現行以上のものを提案
３）保証はしませんと3回言う
sudo初回実行時のメッセージ

# sudo初回起動時のメッセージはどういう内容なのか
sudo初回起動時の英語のメッセージを読み飛ばしてたんですが、
頑張って読んでみたらいいことが書かれていたので書いてみます。
あってるかどうかわかりませんが、だいたいこういうことだと思います。

> We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
(管理者から日常的なレクチャーを受けていると信じています。要約するとこれら3つのことです。）

>    #1) Respect the privacy of others.（他のユーザのプライバシーを尊重すること）
    #2) Think before you type.（入力する前に考えること）
    #3) With great power comes great responsibility.（大いなる力には大いなる責任が伴うこと）

4月からIT屋さんになる人たちや、
経験が増えてきて権限の強いアカウントで仕事をまかされるだろう若手の方は心に刻んでおいてください。
あと、私のように英語だからと読み飛ばすような大人にはならないでください。
メッセージは言語がどうあれメッセージなので、意味のあるはずのものです。
（↑いいことを書いたつもりになりました）

※#3はｽﾊﾟｲﾀﾞﾏﾝのネタみたいですね
ちょいちょいわからなくなるcheckbox, radio, selectboxの値の取り方

## 前書き

- 重要なのは、selectorの使い方
- 重要なのは、propの使い方

## selectbox

```html
<select id="select" name="select">
    <option value="0">sample</option>
    <option value="1">sample1</option>
    <option value="11">sample11</option>
    <option value="101">sample101</option>
</select>
```

```js
$("#select").val()
```

選択中のoptionのvalueを取ってくれる。multipleのselectboxでも配列で（[value1, value2]）取ってくれる。

### selectboxのtextを取得したい

```js
$("#select").text()
```

こうしてしまうと、全optionのtextがでてくる。選択中のoptionのtextが欲しい場合は以下。

```js
$("#select option:selected").text()
```

selectorの:selectedを使用する。selectboxなのでselected。
:selected Selector (http://api.jquery.com/selected-selector/)

multipleで複数選択している場合、残念ながら配列では返してくれない。
（[text1, text2]こんな感じにはならない）

複数選択している場合は、eachを使う。

```js
var text = [];
$("#select option:selected").each(function() {

	text.push( $(this).text() );

});
```

## radio

```html
<input type="radio" name="radio-group" value="0">
<input type="radio" name="radio-group" value="1">
<input type="radio" name="radio-group" value="2">
```

基本はnameでグループ化するのでnameで取得することが多いと思う。

以下はダメな書き方

```js
$("[name=radio-group]").val()
```

radioに限った話ではなく、同じnameがたくさんある場合、最初にヒットしたvalueだけ返ってくる。
こういう時はやはりselectorを使う。

焦らしてもう一つダメな書き方

```js
$("[name=radio-group]:seleted").val()
```

先ほどのselectboxの:selectedを使ってみる。結果はエラー。selectboxじゃないからエラー。
checkboxとradioは別のselectorである:checkedを使う、となっている。

### チェックされているradioの値を取得する

次は動く書き方

```js
$("[name=radio-group]:checked").val()
```

上記の書き方で選択中のradioだけ取ってきてくれる。
ちなみにselectboxでしか:selectedは使えないけど、:checkedはselectboxでも使える。selectedの存在意義がうすい。

```js
$("#select option:checked").text()
```

:checked Selector (http://api.jquery.com/checked-selector/)

valueはどうでもよくて特定のradioが選択されているかどうか知りたい場合はpropを使う（attrじゃないよ）。
checkboxも同じなのでpropについてはcheckboxの章で解説する。

## checkbox

```html
<input type="checkbox" name="checkbox1" value="1">
<input type="checkbox" name="checkbox2" value="2">
<input type="checkbox" name="checkbox3" value="3">
```

group化してないcheckbox。

### チェックされているcheckboxの値を取得する

```js
$("[name=checkbox1]").val()
```

上記の場合、チェックされていてもされてなくても、ただvalueを取るだけ。
チェックされている場合、値を取得したい場合は、radioと同じ。

```js
$("[name=checkbox1]:checked").val()
```

この場合、チェックされていたらvalueを返す。チェックされていなかったらヒットする要素自体がないのでundefinedが返る。
もし同じnameの要素が複数あり、checkedで返る要素が複数の場合、selectboxのmultipleと同じようにeachを使う。

### チェックされているかどうかをチェックする

```js
$("[name=checkbox1]").prop("checked")
```

チェックされていたらtrue、チェックされていなかったらfalseが返る。

## おまけ：typeのselector

```html
<input type="checkbox" name="checkbox1" value="1">
```

タイプで要素を取得したい場合、以下で取得できる。

```js
$("[type=checkbox]")
```

typeはselectorでも取得できる。

```js
$(":checkbox")
```

ただこの場合、画面上のすべてのcheckboxを取得してしまうので、htmlの書き方を工夫する。

```html
<div class="checkbox">
    <input type="checkbox" name="checkbox1" value="1">
    <input type="checkbox" name="checkbox2" value="2">
    <input type="checkbox" name="checkbox3" value="3">
</div>
```

```js
$(".checkbox :checkbox")
```

これで特定DIV内のcheckboxのみ取得できる。

```js
$(".checkbox :checkbox:checked")
```

選択中のすべてのcheckboxが取得できる。これはeach使うパターン。
アプリのバージョンチェックAPIを作ってみて


## バージョンチェックAPIとは

* アプリのアップデートがあるか
* そのアップデートは強制か

を調べるためのAPI。アプリの起動時に必ず叩かれる。

## 何のために必要なのか

割愛

[[iOS]アプリに強制アップデート機能を導入すべき理由と、簡単に実装する方法](http://qiita.com/kazu0620/items/f2f6c711c8800d127eb2)

## 僕達が既に持っていた仕組み

リリースされているアプリのバージョン一覧を返すAPI。

```json
[
	"1.0.0",
	"1.1.0",
	"2.0.0"
]
```

アプリでこれを取得し、最新バージョンの1桁目が自分自身のバージョンの1桁目より大きければ強制アップデートダイアログを出す、というふうになっていた。（うろ覚え）

利点は、リリースするたびに1つ追加するだけで良いので更新がラクなこと。

## 今までの問題点

* バージョン番号のパースなど複雑なロジックがクライアントサイドにあった
	* 複雑なロジックは極力サーバーサイドに持たせたい
	* バグってて古いアプリが強制アップデートされなかったら目も当てられない
* 強制アップデートしたいのは、①提供の終了したAPIを使っているバージョン、 **②バグってるバージョン**
	* バグったバージョンがリリースされてしまったときに1桁目のバージョンを上げるのがカッコ悪い
	* 1桁目を上げるとそれ以前のバージョンも強制アップデートになるし

## 今回作ったAPI

リクエストヘッダーのUser-Agentを見て、「アップデートがあるか」「強制アップデートがあるか」を返すAPI

### 擬似コード

```python
latestVersion = Version(1,2,0)

def isUpdateRequired(version):
	version < Version(1,1,0) || # サポートされていない
	version == Version(1,1,4) # バグってリリースされてしまった等

def handleRequest(request):
	version = parseUserAgent(request)

	return {
		"latest_version": latestVersion,
		"update_available": version < latestVersion,
		"update_required": isUpdateRequired(version)
	}
```

アプリがリリースされるたびに `latestVersion` を更新する。特に必要な時だけ `isUpdateRequired` のロジックも更新する。

## クライアントサイドの処理（擬似コード）

```python
if response.update_required:
	強制アップデートダイアログを出す
	（ストアに飛ぶかアプリを終了するしかない）
else if response.update_available:
	if isIgnored(response.latest_version): # 既にこのバージョンを無視したことがある
		何もしない
	else:
		アップデート通知ダイアログを出す
		if 無視する:
			ignore(response.latest_version) # このバージョンを無視する
		else:
			ストアに飛ぶ
```

ポイント

* 無視したことをアプリ内に保存するためにサーバーから `latest_version` を返してもらっている
	* `latest_version`をキーに`ignored`という値を保存するなど
* **既に無視したことがあっても、強制アップデートであれば必ず強制アップデートダイアログが出る**

## その他

* 今まではリソースAPIとは別のドメインでバージョンチェックAPIを作っていたが、今回はリソースAPIと同じドメインにした。
	* これはもしかすると良くなかったかもしれない。アプリを公開する人（クライアントサイドの人）が気軽に更新できるようにHerokuとかに分離しても良かったかも。
	* と言っても今でも `latestVersion` を更新しなかったからといって特に困るわけでもない。
* バージョンチェックとは別に、リソースAPIがメンテ中であることを示すAPIも別ドメインでやったほうがよかったかもしれない。
	* ドメインが解決できないとかサーバー全滅レベルの障害のときにもメンテ中APIだけは動き続けることができるので。
	* 今はリソースAPIを叩く処理の中で、ステータスコードが503であればメンテ中ダイアログを出すようになっている。

ここらへんはもうちょっと考えてみてもよいかも。
【c++】デストラクタにvirtualを付ける場合、付けない場合。

[元ブログ、【c++】デストラクタにvirtualを付ける場合、付けない場合。 - 技術は熱いうちに打て！](http://blog.dalt.me/1009)

```cpp
virtual ~Hoge();
```

C++を書いていると良くvirtual宣言されているデストラクタを見ます。

まだまだC++初心者なので、なんでデストラクタにvirtualが付くのか分からず調べてみた結果をまとめてみたいと思います。
突っ込みあればお待ちしております。

## まとめ
<strong>・ポリモーフィズムを利用すべく作った基底クラスのデストラクタはvirtualが必要である</strong>
=> でないと、派生クラスのデストラクタが呼ばれずメモリリークが起きる

<strong>・逆にポリモーフィズムを利用する意図がないのであれば派生クラスを作るつもりであってもvirtualなデストラクタにすべきではない</strong>
=> メモリの無駄遣いに繋がる

### 参考としたサイト・書籍
[ビャーネ・ストラウストラップ (著) プログラミング言語C++第4版](http://www.amazon.co.jp/gp/product/4797375957/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797375957&linkCode=as2&tag=dalt1003-22)
[C++では基底クラスにvirtualデストラクタを書こう](http://d.hatena.ne.jp/ajiyoshi/20080925/p1)
[C++ でデストラクタを virtual にしなくてはならない条件と理由](http://www.yunabe.jp/docs/cpp_virtual_destructor.html)

では一つずつ見ていきましょう。

## ポリモーフィズムを利用すべく作った基底クラスのデストラクタはvirtualが必要である

テストコードを見てみましょう。(<font style="font-size:70%;"><em><a href="http://d.hatena.ne.jp/ajiyoshi/20080925/p1" target="_blank">C++では基底クラスにvirtualデストラクタを書こう</a>より</em></font>)

```cpp:BadPractice.cpp
#include <stdio.h>

class BadBase {
  public:
    BadBase(){}
    ~BadBase(){}
};
class BadSub : public BadBase {
  public:
    BadSub(){ printf("open\n"); }
    ~BadSub() { printf("close\n"); }
};

int main() {
  BadSub* sub = new BadSub();
  delete sub;

  printf("\n");

  BadBase* base = new BadSub();
  delete base;

  return 0;
}
```

出力は以下の様になります。
<em>
open
close

open
</em>
ポリモーフィズムを用いている下部はcloseが呼ばれていない = デストラクタが呼ばれていません。

ではどうすれば良いかと言うともうお分かりかと思います。
virtualを付けてみましょう。

```cpp:GoodPractice.cpp
#include <stdio.h>

class Base {
  public:
    Base(){}
    virtual ~Base(){}
};
class Sub : public Base {
  public:
    Sub(){ printf("open\n"); }
    ~Sub() { printf("close\n"); }
};

// mainは一緒
```

出力は以下です。
<em>
open
close

open
close
</em>
closeが呼び出されているのが分かります。

なぜこうなるのでしょうか。

[ビャーネ・ストラウストラップ (著) プログラミング言語C++第4版](http://www.amazon.co.jp/gp/product/4797375957/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797375957&linkCode=as2&tag=dalt1003-22)にはこの様に書かれています。


*17.2.3 基底とメンバのデストラクタ*

*コンストラクタは、クラスオブジェクトを"下から順に"構築する。*
*[1] まず、基底クラスのコンストラクタを実行する。*
*[2] 次に、メンバのコンストラクタを実行する。*
*[3] 最後に、自身の本体を実行する。*

*デストラクタは、逆の順序でオブジェクトを"破壊"していく。*
*[1] まず、自身の本体を実行する。*
*[2] 次に、メンバのデストラクタを実行する。*
*[3] 最後に、自身の本体を実行する。*


悪い例の方では、親クラス(BadBase)のポインタに子クラス(BadSub)のポインタを代入しています。
デストラクタの[1]に書いてある"自身"とはこの例で言えばBadBaseの事になります。
なので、virtualがなければBadSubの存在に気付く事がなく子クラスのデストラクタが呼ばれないと言う仕組みなのでしょう。

## 逆にポリモーフィズムを利用する意図がないのであれば派生クラスを作るつもりであってもvirtualなデストラクタにすべきではない

[C++ でデストラクタを virtual にしなくてはならない条件と理由](http://www.yunabe.jp/docs/cpp_virtual_destructor.html)によると、virtualを付ける事により
*・インスタンスのサイズが大きくなる*
*・関数呼び出しが遅くなる*
事が生じるので不用意に付けるべきではないと言う事です。

この辺はまだ勉強不足なので引き続き勉強を続けていきたいと思います。
今回はここまで。

誰かのお役に立てば。
TwistOAuthを使ってユーザータイムラインを取得する

**TwistOAuthは現在非推奨になっています。代わりに同じ作者の[cowitter](https://github.com/mpyw/cowitter)を使うようにしてください。**

#はじめに

PHPでTwitter連携のアプリをつくろうと思って調べてみるとTwistOAuthっていうのが便利そうだった。とりあえずこれを使ってタイムラインを取得出来るだけ取得してみる。

TwistOAuthは以下のURLで公開されてます。
<https://github.com/mpyw/TwistOAuth>


#実装する

##準備
あらかじめ、<https://apps.twitter.com/>からアプリケーション登録して、

- CONSUMER KEY
- CONSUMER SECRET
- ACCESS TOKEN
- ACCESS TOKEN SECRET

の4つを取得しておく。方法は色んなとこに載ってるので省略。

TwistOAuthライブラリはpharアーカイブにまとまってるのでダウンロード

```
wget https://github.com/mpyw/TwistOAuth/raw/master/build/TwistOAuth.phar
```

##コード
###ライブラリを読み込む
各種キーの設定もしてしまう

```p

<?php

require_once 'TwistOAuth.phar';

define('CONSUMER_KEY', '取得したキー');
define('CONSUMER_SECRET', '取得したキー');
define('ACCESS_TOKEN', '取得したキー');
define('ACCESS_TOKEN_SECRET', '取得したキー');

$screen_name = '取得したいユーザのID(@なし)';
```

###認証しよう
TwistOAuthクラスのコンストラクタで認証が行われるので。キーを渡してあげる。

```php

try {
	$to = new TwistOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);//OAuth認証
} catch(TwistException $e) {
	$error = $e->getMessage();
}
```


###ついーと取得
tweetはstatusと呼ぶそうです。一回のリクエストで最大200件しか取得できないので、forで回して取得できる最大数の3200件取得してみる。

```php

$statuses = array(); //すべてのツイート用の配列

for($i = 0; $i < 3200; $i += 200) {

	$param = array('screen_name' => $screen_name, 'count' => '200'); //200件取得
	if(isset($max_id)) {
		$param['max_id'] = $max_id;
	}

    try {
		$tmp_statuses = $to->get('statuses/user_timeline', $param);
    } catch (TwistException $e) {
        $error = $e->getMessage();
    }

    if(count($tmp_statuses) == 0) { //取得件数0だったら終了
        break;
    } else { //取得したツイートがあった時
    	$statuses =  array_merge($statuses, $tmp_statuses); //配列の最後に追加
        $max_id = $tmp_statuses[count($tmp_statuses)-1]->id - 1; //取得した最古のツイートのidを保存
    }
}

?>
```

これで```$statuses```には最大3200件(あれば)のツイートの配列が入ります。

###表示
とりあえずリストで表示してみる

```php
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title><?php echo htmlspecialchars($statuses[0]->user->name); ?>'s timeline</title>
</head>
<body>
	<?php if(isset($error)): echo $error; ?>
        <?php else: ?>
	<ul>
		<?php foreach ($statuses as $status): ?>
			<li><?php echo htmlspecialchars($status->text); ?> </li>
		<?php endforeach; ?>
	</ul>
        <?php endif; ?>
</body>
</html>
```

#おわりに
アクセストークンが自分のものなので、基本的に鍵アカのツイートは取得できない。取得するには各ユーザにOAuth認証してもらう必要がある。
SQL ServerからTeradataに接続する

自分のメインブログで書きました。
[SQL ServerからTeradataに接続する](http://blog.yakumomo.com/2015/03/sql-serverteradata.html)

簡単に書くと、リンクサーバー機能を使います。
と言ってもすでに書いてある情報の写し。
[Setup SQL Server 2008 R2 Linked Server To the Teradata Database](http://developer.teradata.com/blog/netfx/2011/12/setup-sql-server-2008-r2-linked-server-to-the-teradata-database)

んで、重要なのは64ビットのインストールをしろ、ということ。
でないと、エラーが起きちゃうよ、という話。
体で覚えるGitHub



#####Git-flowの使い方（こうすけさん)
http://qiita.com/KosukeSone/items/514dd24828b485c69a05



#####今更聞けないgitの使い方
http://qiita.com/mountcedar/items/682743c95fd3b8fc274b



#####一石の日記
http://d.hatena.ne.jp/ISSEKI/?of=2 



####Source Tree編
http://celtislab.net/archives/20140527/git-sourcetree/




---



①作業ディレクトリ
>作業をはじめに行うところ

②ステージングエリア（インデックス）
>①が終わったら②番に上げる

③リポジトリ（ローカル、リモート）
>

---



1.ディレクトリの作成
mkdir myweb(←ディレクトリ名)

2.移動
cd myweb

3.gitにmywebを使うことを知らせる
git init

4.ファイルの作成
vim index.html
>line 1　：と記述

5.ファイルの中身を見る
cat index.html

6.②ステージングエリアに上げる
git add index.html

7.③に上げる(ローカル)
git commit -m "コミット"
*-mでエディタを立ち上げずにcommitできる

8.エディタが立ち上がるので、コメントを入れる

9.commit履歴を確認
git log
>git log --oneline：でコンパクトに表示
>git log -p：で変更箇所の確認
>git log --stat：どのファイルが変更されたかわかる

10.どのファイルがどんな状況かわかる（どのファイルが変更されたのか）
git status
>modified: index.html //index.htmlが変更されてるよ！

11.変更の取り消し
git checkout -- index.html
>先ほど変更した場所が取り消される

12.そしてcat index.htmlで確認すると、元に戻っている

13.line 2　：と記述し変更箇所の確認
git diff

14.全ての編集ファイルをステージングエリアにあげる
git add .

15.commitのあとに消去や移動
git rm/mv index.html

16.ファイルを限定してアップしない
vim .gitignore
>*.log　：拡張子が.logの物は無視される←ワイルドカード

17.git add後にやっぱり編集が気に入らないから前に戻る
git reset --hard HEAD

18.git branch：現在作られているbranchの確認
現在の場所は*で示される

19.branchの作成
git branch hoge

20.*をhogeに移動
git checkout hoge

21.checkoutされているものにmergeする
git merge [mergeするもの]

22.conflictの解決
git status　：conflictの場所を確認

23.

---

###空でないディレクトリにリモートリポジトリからcloneする方法
$ cd ~
$ git init
$ git remote add origin [ファイルURL].git
$ git pull origin master




gitの管理・運用方法
-
①developからshoheiheiへリベース
②shoheiheiからshoheiheiへ強制プッシュ
③shoheiheiからdevelopへプッシュ
で、完了！！
Bootstrap3とSeasar2(SAStrats/S2JDBC)・JSPを組み合わせて使うには？

プログラマー２年目です。

IDEはeclipse,フレームワークSeasar2(SAStrats/S2JDBC),言語Java,ViewはJSP
を使ってWebアプリケーションを作成しています。

CSSフレームワークとしてBoostrap3を使い、カッコイイWebページを作成しようとしています。
<br>
そこで結論から言うと、
<br>

>####Bootstrap3とSeasar2(SAStrats/S2JDBC)・JSPを組み合わせて使うにはどうしたらいいでしょうか？


<br>現在ログインページを実装したのですが、Seasar2の規約に縛られて、このJSPにBoostrap3を組み込む書き方がわかりません。s:formタグやhtml:textタグ,propertyの値とActionFormのフィールドが一致しているなど。
<br>

抽象的より具体的のほうがいいと思うので
具体的に言うと、
下記のlogin.jspをbs3Login.jspの見た目にしたいのです。
<br>


↓ login.jsp

![スクリーンショット 2015-03-13 11.09.59.png](https://qiita-image-store.s3.amazonaws.com/0/60528/91fa1b88-9a53-3760-677a-40217b783f60.png)

![スクリーンショット 2015-03-13 11.07.05.png](https://qiita-image-store.s3.amazonaws.com/0/60528/f81129b2-a4a2-ef81-92a7-57b2d4248c67.png)
<br><br>
- - -

↓ bs3Login.jsp

![スクリーンショット 2015-03-13 11.10.23.png](https://qiita-image-store.s3.amazonaws.com/0/60528/c51572f4-5dc8-42d0-a422-644b47b5df53.png)

![スクリーンショット 2015-03-13 11.07.25.png](https://qiita-image-store.s3.amazonaws.com/0/60528/dc69b0a5-5725-9923-3d11-6c382ce97679.png)

![スクリーンショット 2015-03-13 11.07.41.png](https://qiita-image-store.s3.amazonaws.com/0/60528/3941164b-5099-e795-a300-2b479553666e.png)

<br>

わかる方がいればアドバイスいただけると嬉しいです。
ColdFusion用MVCフレームワーク『Model-Glue』のチートシートを作りました。

CakePHPのチートシートを見ていい感じだなぁと思ったので、Adobe ColdFusionのフレームワークであるところの[Model-Glue](http://www.model-glue.com/)のチートシートを作りました（というか、だいぶ過去に作ったものをアップしました）。

[The CheatSheet for Model-Glue 3](https://github.com/sengokyu/model-glue-cheatsheet/blob/master/ModelGlueCheatSheet.pdf?raw=true) **PDFです**

印刷して壁に貼ったり、枕の下に入れたりしてください。

＃ ファイル自体はVisioで作成しました。
Mysql2::Error: Column 'created_at' in order clause is ambiguousの対策

Railsのモデルで以下のように関連モデルをincludesしてタイトルのようなエラーがでたときの対策です。

```rb:book.rb

book = Book.includes(:author)
book = book.order("created_at DESC")

```

これだと以下のようなエラがでます。

```
Mysql2::Error: Column 'created_at' in order clause is ambiguous
```

これは、どのモデルの```created_at```か分からないよとおっしゃっているそうです。

なので、以下のようにテーブル名を明示すれば大丈夫です。

```rb:book.rb

book = Book.includes(:author)
book = book.order("books.created_at DESC")

```

以上ちょっとしたメモです。
SpringでRSpecを高速化する


# 1. Gemfileに`spring-commands-rspec`を追加する

```Gemfile
gem 'spring-commands-rspec'
```

# 2. `bin/rspec`を作成する

spring-commands-rspecの場合

```bash
$ bundle exec spring binstub rspec
```

bin/rspec

```bin/rspec
#!/usr/bin/env ruby
begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError
end
require 'bundler/setup'
load Gem.bin_path('rspec-core', 'rspec')
```

注意：すでにbundleのbinstubsを使って`bin/rspec`がある場合は、一度削除する

```bash
$ bundle binstubs rspec-core
```

binstubsで生成した`bin/rspec`

```bin/rspec
#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'rspec' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('rspec-core', 'rspec')
```

この`bin/rspec`はspringが使われない

# 3. 測定

## Springなし

実行

```
$ bundle exec spring status
Spring is not running.
```

出力結果

```
bundle exec rspec  3.83s user 0.94s system 97% cpu 4.887 total
```

## Springあり

実行

```
$ time bundle exec bin/rspec
```

出力結果

```
bundle exec bin/rspec  0.53s user 0.10s system 45% cpu 1.379 total
```
Chromeのカスタム検索エンジン、使ってますか？


## カスタム検索エンジンとは？
Chromeの設定からGoogleやYahooなど以外の検索エンジンを追加できる
また、特定のサイトでは自動的にその他の検索エンジンの中に追加される。
[![Settings.png](https://image.docbase.io/uploads/fd4782df-ed4a-4417-98c2-3c36cf7f97ea.png)](https://image.docbase.io/uploads/fd4782df-ed4a-4417-98c2-3c36cf7f97ea.png)

## 使い方
基本Chromeではアドレスバーから既定の検索エンジンを使用して検索できるが、
そこに検索エンジンの設定で決めたキーワードを入力してスペース(Tab)を入力すると、
そのキーワードで設定した検索エンジンを使用できる。

たとえば、上記の画像で言えば、Yahoo検索は「y」というキーワードを設定している。
そこで、アドレスバーに「y」とスペース（Tab)を打ち込むと、
下記のように表示される。
![New_Tab.png](https://qiita-image-store.s3.amazonaws.com/0/30442/570b7318-9da5-8e30-8bff-9fe3f4b01fdc.png)

この後に検索したいキーワードを入力すると、その検索エンジンで検索できる。

## でもどうせGoogle先生しか使わんよ？
まあ、通常はGoogle先生のお世話になるわけだが、
英単語を調べたい時やQiitaで記事検索したい時などは重宝するかも。
英単語検索でよく使う「codic」や「Weblio」もこれに対応しているので、
英単語検索ではとても捗るようになった。

## まとめ
普段はアドレスバー検索からGoogle先生のお世話になるけれども、
特定のサイト検索をよく利用するならば使って損はなさそう。
sameersbn/docker-gitlab　の起動手順

https://github.com/sameersbn/docker-gitlab
一番人気のあるGitLabの起動手順


```lang:postgresql起動
docker run --name=postgresql -d \
  -e 'DB_NAME=gitlabhq_production' -e 'DB_USER=gitlab' -e 'DB_PASS=password' \
  -v /opt/postgresql/data:/var/lib/postgresql \
  sameersbn/postgresql:latest
```

↓

```lang:redis起動
docker run --name=gitlab -d --link redis:redisio \
  sameersbn/gitlab:7.8.4
```

↓

```lang:gitlab起動
docker run --name='gitlab' -it --rm -e 'GITLAB_PORT=10080' -e 'GITLAB_SSH_PORT=10022' -p 10022:22 -p 10080:80 -v /var/run/docker.sock:/run/docker.sock -v $(which docker):/bin/docker --link redis:redisio --link postgresql:postgresql -v /opt/gitlab/data:/home/git/data sameersbn/gitlab:latest
```
みんな大好きlombokでimmutableなクラスを簡単に作る等

lombokはアクセッサ系のアノテーション(@GET,@SET,@DATA)だけを使っていても十分便利ですが、
@Valueでimmutableなクラスを生成するのはもっと便利です。

lombokなしで、immutableなPairクラスを作ってみます。
コンストラクタは隠蔽して、staticメソッドのofでオブジェクトを生成しています。

```java
public final class ImmutablePair<L, R> {

    public static <L, R> ImmutablePair<L, R> of(L left, R right){
        return new ImmutablePair<>(left, right);
    }
    
    private ImmutablePair(L left, R right) {
        this.left = left;
        this.right = right;
    }
    
    private final L left;
    private final R right;
    
    public L left() {
    	return left;
    }

    public R right() {
    	return left;
    }

    public ImmutablePair<L, R> right(R r) {
    	right = r;
    	return this;
    }

    public ImmutablePair<L, R> left(L le) {
    	left = le;
    	return this;
    }
}

// 生成
ImmutablePair<String, Integer> pair = ImmutablePair.of("name", 10);

```

。。。面倒ですね。

これをlombokで書くと、たったこんだけです。使わない理由がありませんね。

```java
@Value(staticConstructor="of")
@Accessors(fluent=true)
public final class ImmutablePair<L, R> {
    L left;
    R right;
}

// 生成
ImmutablePair<String, Integer> pair = ImmutablePair.of("name", 10);
```

フィールドが多いときはビルダーパターンを実現してくれる@Builderを使うといいです。
同じ型のフィールドがあり、コンストラクタでパラメーターの順番を間違えちゃうというありがちな
ミスを防ぐことができます。


```java
@Value
@Accessors(fluent=true)
@Builder
public final class Person {
    String firstName;
    String lastName;
    String email;
    int age ;
}

// こんな感じで使います。
Sample sample = Sample.builder()
						.firstName("first")
						.lastName("last")
						.email("mail@xxxxx.com")
						.age(18)
						.build();
```
Actionクラスに付与するインタフェースと機能

# Struts2のActionクラスに拡張できる機能

Struts2のActionクラスに対して、あらかじめ用意されたインタフェースを実装することで、機能の拡張ができます。

例えばActionクラスでHttpSessionに格納されるオブジェクトを扱いたい場合には、SessionAwareを実装し、インタフェースが提供するメソッドとフィールドを実装するだけです。

このように、ActionクラスのフィールドとしてActionクラスが扱えるオブジェクトを追加することや、Actionクラスの実行前に書きたい処理がある場合に実装するインタフェースなどが用意されています。

簡単に言うと、
**～Aware = Struts2が機能拡張を「気づく(Aware)」Actionである**
ですね。

## 使い方

次の例は、先ほどあげたSessionAwareの実装例です。

```java:SessionSampleAction.java
package sample.action;

import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;

/**
 * @author A-pZ
 *
 */
public class SessionSampleAction extends ActionSupport implements SessionAware {

	/**
	 * @see org.apache.struts2.interceptor.SessionAware#setSession(java.util.Map)
	 */
	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	private Map<String, Object> session;
}
```

手順は次のとおりです。

1. Actionクラスにて、implements SessionAware を宣言
2. 実装メソッドである setSession(Map<String, Object> session)にて、ActionのフィールドへHttpSessionのオブジェクトを格納する処理を実装する。this.session = session; でほぼ十分。
3. 2.の手順で実装したフィールドを用意する

これにより、このActionクラスのsessionフィールドへ、Struts2が自動的にHttpSessionの内容をMap<String,Object>の型で格納します。

このMapの内容を更新すれば即時にHttpSessionへ格納され、Mapから削除をすればHttpSessionから削除されます。

## その他の拡張インタフェースと機能

他にもいくつか便利なインタフェースがあります。標準で継承が推奨されているActionSupportクラスが標準で搭載している機能もありますので合わせて紹介します。

中にはAwareがついていないものもありますが、これは標準機能としてStruts2のActionクラスが利用している webwork2時代のインタフェースです。

|Awareインタフェース名|機能の概要|ActionSupportで搭載済|
|:-----------|:-----------|:-----------|
|ValidationAware|Actionクラスで格納するメッセージ、エラーメッセージ、Validationで検出したエラーをactionMessages、actionErrors、fieldErrorsに格納する|○|
|Validateable|Validationを有効にする|○|
|TextProvider|メッセージ定義プロパティからテキストを取得する|○|
|LocaleProvider|Actionクラスからリクエストのロケールを取得する|○|
|ApplicationAware|サーブレットコンテキスト(アプリケーション属性)をMap&lt;String,Object&gt;で取得する|-|
|ParameterAware|サーブレットが受け取ったリクエストパラメータをMap&lt;String,String[]&gt;で取得する。Actionクラス内でリクエストパラメータの内容を増減させるために扱う特殊な機能|-|
|PrincipalAware|認証情報を扱うPrincipalを、PrincipalProxyの型で取得する|-|
|RequestAware|サーブレットリクエスト属性をMap&lt;String,Object&gt;で取得する|-|
|ServletRequestAware|HttpServletRequestオブジェクトを取得する。濫用に注意。|-|
|ServletResponseAware|HttpServletResponseオブジェクトを取得する。あらたなレスポンス形式で出力する場合に扱う。|-|
|SessionAware|セッション属性をMap&lt;String,Object&gt;で取得する|-|

## アプリケーションを作る時のコツとして

これらを逐一ActionSupport implements ～Aware , ～Aware , ～Aware とするのも良いですが、そのアプリケーションで頻出する機能については、拡張Actionクラスにて実装しておいて、さらにいくつか必要なパターンの数を用意して、実装時にはそれを利用する規約なりお手本を提供するのがよいでしょう。
mod_h2 を試す

Apache を HTTP/2 対応にする mod_h2 を Mac OS X で試してみました。依存関係のあるライブラリをダウンロードするために curl を SSL 対応でビルドしておく必要がありました。homebrew であれば、次のコマンドを実行します。

```
brew install curl --with-openssl
```

http2 対応版の curl を使いたいのであれば、次のコマンドを実行します。

```
brew install summerwind/http2/curl --with-openssl
```

mod_h2 を git でダウンロードします。

```
git clone https://github.com/icing/mod_h2.git
cd mod_h2
```

依存関係のライブラリをダウンロードしてビルドします。SSL エラーになってダウンロードできないのであれば、Makefile で curl のオプション (CURL_OPTS) を修正して、gen/ 以下のファイルを削除して再度試してください。


```bash
CURL_OPTS = --progress-bar -k
```

```
cd httpd
make
cd ../
cd nghttp
make
cd ../
```

mod_h2 をビルドします。

```
autoreconf -i
automake
autoconf
./configure
make
```

/etc/hosts に次の行を追加します。

```
127.0.0.1       test.example.org        test
```

Apache を起動させてテストを実行してみましょう。

```
make test
```

Apache を直接起動させるには `gen/install/bin/apachectl start` を実行します。

自分で `nghttp` コマンドを実行するには次のようになります。

```
gen/install/bin/nghttp -nv https://test.example.org:12346
```

nghttp ビルドオプションをつけた curl では次のとおりです。

```
curl -k -v https://test.example.org:12346
```

Firefox でサイトにアクセスするには about:config から `network.http.spdy.enforce-tls-profile` の値を `false` に変更する必要がありました。Google Chrome では `ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY` のエラーメッセージが表示され、アクセスできませんでした。
npm Tab で検索できますね GitHub, Amazon, Facebook, Twitter も

Google で良く npm のパッケージを検索するんですけど、
アドレスバーのショートカットを発見しました。

Chromeのアドレスバーで **`npm` `Tab`** とキーインして、
検索したい単語を入れるだけで、すぐに検索できます。

![npm-tab.png](https://qiita-image-store.s3.amazonaws.com/0/16128/dbdb32fa-4a16-c28b-5448-2a81e9f74b70.png)

同様に **`GitHub` `Tab`** でもできる様です。
更に **`np` `Tab`** や **`gi` `Tab`** などと省略もできる様です。

**`am` `Tab`** や **`ama` `Tab`** で Amazon, 
**`fa` `Tab`** や **`fac` `Tab`** で Facebook, 
**`tw` `Tab`** や **`twi` `Tab`** で Twitter, 
など、URLを認識できる所まで入力した後に、**`Tab`** を押せば
それ専用の検索画面になりますね。

他にもあるんだろうなぁ。

**`Ctrl`+`L`** でアドレスバーにすばやく移動できるというのも使うと結構速く検索できるね。

以下のリンクにヘルプが書いてあるんだけど、よくわかりませんね。

[Chrome ヘルプ: キーボード ショートカット - Google]
(https://support.google.com/chrome/answer/157179?hl=ja)
bash > null command(:)の用途 > 足し算 / if文内のコメント / 変数定義チェック

動作確認

    CentOS 6.5

[こちら](http://qiita.com/lazynick/items/ad86bede4e28f434da87)のheliac2000さんのコメントにてnull commandというのがあるというのを知った。

    $ I=1
    $ : $((I++))
    $ echo $I
    2
という使い方ができるとのこと。

<hr>
また、別の用法としては、以下のようなものがあるのを[こちら](http://homepage1.nifty.com/y-osumi/works/code/shell_script.html)で知った。

```bash:test_exec
#!/bin/env bash

word='abc'
if [ word = 'abc' ]; then
#	echo "abc is same"
fi
```

上記のようにif文の中をコメントだけにすると以下のエラーが出る。

```    
$bash -x test_exec
test_exec: line 6: syntax error near unexpected token `fi'
test_exec: line 6: `fi'
```

if文の中に`:`を入れることでエラーが出なくなるとのこと。

```bash:test_exec
#!/bin/env bash

word='abc'
if [ word = 'abc' ]; then
#	echo "abc is same"
:
fi
```

```    
$bash -x test_exec
+ word=abc
+ '[' word = abc ']'
```

<hr>
(追記 2015/03/13 10:30)
@ngyuki さんに教えていただいた用途。

```bash:test2_exec

#!/bin/bash
a=1
: ${a:?}
: ${b:?} # b: parameter null or not set
echo "test"
```

実行結果

```
$bash -x test2_exec
+ a=1
+ : 1
test2_exec: line 4: b: parameter null or not set
```

定義済みの変数(a)の場合はdebugモードで`+ : 1`のように値が表示される。
未定義の変数(b)の場合は`... b: parameter null ...`のようにエラーとなり、処理が中断される。
PC/Mac からスマートフォンに URL を送りたいときは Pushbullet が便利

# 解決したい問題

PC/Mac からスマートフォンに URL を送るのをなるべく簡単にやる。

# これまでのソリューション

適当なツールで URL から QR コードを生成し、スマートフォン端末にインストールした適当な QR コードリーダーアプリでスキャンして開く。

# Pushbullet を使う

Pushbullet という、プッシュ通知送受信に特化したアプリを使うことで同じ問題をより簡単に解決できます。

## スマートフォン端末に Pushbullet アプリをインストールする

* [iOS](https://itunes.apple.com/jp/app/pushbullet/id810352052?mt=8)
* [Android](https://play.google.com/store/apps/details?id=com.pushbullet.android&hl=ja)

インストールしたら Facebook 認証とかで適当にログインしてください。

## PC/Mac に Chrome 拡張版の Pushbullet をインストールする

* [Chrome 拡張](https://chrome.google.com/webstore/detail/pushbullet/chlffgpmiacpedhhbkiomidkjlcfhogd?hl=ja)

こちらも Facebook 認証とかで適当にログインします。
もちろん PC/Mac と共通のアカウントでログインしましょう。

あと、当然プッシュ通知は許可しましょう。

# Pushbullet から URL を送る

## 現在開いているタブ

ブラウザのメニューから Pushbullet のボタンを押すとこんな感じになります。

![Screenshot 2015-03-13 02.15.35.png](https://qiita-image-store.s3.amazonaws.com/0/208/5732004a-1874-aba3-12b8-3546c8b2e6e2.png)

送信先の端末を選択して Push it! しましょう。
(LAN to the Hills というのは私の iPhone 端末の名前です)

そうすると指定した端末側にプッシュ通知が送られるので Open Link します。

![2015-03-13 02.18.27.png](https://qiita-image-store.s3.amazonaws.com/0/208/cfe0898f-945d-0bb2-5e53-5f8bf922f372.png)

![2015-03-13 02.18.50.png](https://qiita-image-store.s3.amazonaws.com/0/208/89a3c751-cb6b-39b1-6a14-09abcd17a07c.png)

## ページ中の URL

ページ中のリンクを選択してコンテキストメニューから Pushbullet を開くこともできます。

![Screenshot 2015-03-13 02.27.48.png](https://qiita-image-store.s3.amazonaws.com/0/208/3f751797-b16d-cfaf-21b8-a56f033160a2.png)

プッシュを受け取ってからの操作は特に変わりません。

# まとめ

Pushbullet はアプリを作らなくてもプッシュで更新通知ができる、的なアプリかと思ってましたが、こういう使い方も便利なようです。

Enjoy!
マクロ読み込み

```JScript
function textReplace(text, word1, word2) {
	word1 = word1.replace(/[\r\n]/g,"");
	word2 = word2.replace(/[\r\n]/g,"");
	text = text.replace(new RegExp(word1, "g"), word2);
	return text;
}

var fs = new ActiveXObject("Scripting.FileSystemObject");
var ts = fs.openTextFile("Test1BLogic00.tpl");
var template = ts.ReadAll();

selectAll();
var text = GetSelectedString(0);
var cnt = 0;
var lines = text.split("\n");
for (var cnt in lines) {
	if (lines[cnt].match(/^(%.*%)=(.*)$/)) {
		r = lines[cnt].match(/^(%.*%)=(.*)$/);
		template = textReplace(template, r[1], r[2]);
	}
}

insText(template);
```
Kotlin事始め

## 追記2
公式のチュートリアル見たほうが早いかもしれません
http://kotlinlang.org/docs/tutorials/kotlin-android.html

## 追記
2015/04/04時点でバージョンが0.11.91になってました。どんどんバージョンアップしてますね。

## はじめに
Kotlinという名前だけは過去に聞いたことがありましたが、「ふーん」ぐらいに思っていました。
しかし先日,[2015年のAndroid開発はKotlinで決まりかもしれない](http://kirimin.hatenablog.com/entry/2015/03/03/090603)という記事を見て触発されまして
かわいいは正義！( ｰ`дｰ´)と感じたのでKotlinをプロジェクトに導入しました。

しかし地味にハマったので、現時点（2015/03/13）でおそらく最新の構成でKotlinを始めるための設定を残しておこうと思います。


## 手順
1. AndroidStudio(v1.1.0)をインストールする
2. AndroidStudioにKotlinプラグイン(v0.10.206.7)を入れる
3. 何も考えずに新規プロジェクトを作成する
4. 自動で作成されたMainActivity.javaを選択した状態で`Alt+Shift+コマンド+J`を押してMainActivity.ktにコンバートする

5. Tools>Kotlin>Configure Kotlin in Projectを選択し、バージョンを選択する
（バージョンは後ほど手で書き換えるので何でもいいです）
![スクリーンショット 2015-03-13 5.32.33.png](https://qiita-image-store.s3.amazonaws.com/0/9143/6c8054fb-38c2-eb14-a289-2b9675e6fae5.png "スクリーンショット 2015-03-13 5.32.33.png")

ここまでやるとbuild.gradelがいい感じに書き換わっていると思います。ここで一手間加えます

6.gradle.propertiesにバージョンをうつす。この時、バージョンを`0.10.770`にする
![スクリーンショット_2015-03-13_5_37_59.png](https://qiita-image-store.s3.amazonaws.com/0/9143/0708eeb0-a827-658b-79b0-c38e1a7226d5.png "スクリーンショット_2015-03-13_5_37_59.png")

7.app内のbuild.gradleに`buildscript{}`が追加されているはずなので、プロジェクトルートのbuild.gradleにうつす
(mavenのリポジトリは存在しないかもですが、この通りに書きます)
![スクリーンショット_2015-03-13_5_42_29.png](https://qiita-image-store.s3.amazonaws.com/0/9143/29b0ebcd-3f9b-2fa6-1031-d04f7bc0d1d9.png "スクリーンショット_2015-03-13_5_42_29.png")

ここまでやればビルドが通り、実行するとアプリが起動するはずです。

##最後に
僕の場合なぜかManifestからActivityの記述が消えていてはまったので、その部分の記述と、プロジェクト構成のキャプチャも載せておきます。（プロジェクト名は恥ずかしいので隠していますｗ）
![スクリーンショット_2015-03-13_5_28_01.png](https://qiita-image-store.s3.amazonaws.com/0/9143/731c0fc7-dcb5-d6ca-f819-6a2b44594a07.png "スクリーンショット_2015-03-13_5_28_01.png")

![スクリーンショット_2015-03-13_5_47_33.png](https://qiita-image-store.s3.amazonaws.com/0/9143/0fb69bbb-cdb2-0dba-4243-2d944570d619.png "スクリーンショット_2015-03-13_5_47_33.png")
mod_security環境でRedmineを動かす際の注意点

WAF(Web Application Firewall)としてmod_securityを導入したWebサーバで、
Redmineを動かす際、ハマった点等まとめました。

# mod_securityによってRedmineの様子がおかしいときの傾向と特定方法

* フォームやファイル送信後にInternal Server Error(500)が表示される。
* (当たり前だけど)mod_securityはApacheにリクエストが到着した時に処理されるので、Redmineのlog/production.logを見ても何も記録されていない。

>投稿前にプレビューをしていると、問題の文字列を含む本文が(プレビューの)正常処理として記録されていたりして混乱する。

* apacheのerrorログで、該当URIに関するModSecurityの文字がないか確認する。
* ↑があれば続いてauditログを確認  

>auditログ所在は/etc/httpd/conf/modsecurity.conf内をauditで検索する

* auditログを該当URIで検索し、同じ識別子で記録された一連のグループの中から、
誤判定されたルールのIDを控える。

```lang:識別子がa84cdd54の例
--a84cdd54-B--
POST /RedmineのURI/issues HTTP/1.1
Host: example.com
(中略)
--a84cdd54-H--
Message: Access denied with code 44 (phase 2). Match of "eq 0" against "MULTIPART_UNMATCHED_BOUNDARY" required. [file "/etc/httpd/conf.d/mod_security.conf"] [line "39"] [id "200003"] [msg "Multipart parser detected a possible unmatched boundary."]
```
ルールIDは**[id "200003"]**の部分

後はルールIDをもとに適切に除外する等の対策をする。

# 例1：ファイルサイズによってアップロードに失敗する時

* Redmineの設定パネルから添付ファイルのアップロード上限サイズを設定しても反映されない
* 画面の表記と異なるファイルサイズまでしかアップロードできない

mod_securityのSecRequestBodyLimitによって上限サイズが制限されている場合がある。

## 対策

```lang:httpd.conf等に
<IfModule mod_security2.c>
..略..
#SecRequestBodyLimit 5242880 #5MBを
SecRequestBodyLimit 52428800 #50MBに
..略..
</IfModule>
```

httpd.confのバーチャルホストやLocation/Directoryディレクティブ内に書いてもOK。

# 例2：「--」等、特定の文字列が含まれる本文が、Internal Server Errorとなる

テキストメールと同じように区切り線の意味で使おうとする人が良く引っかかる。

フォームのマルチパート(バイナリデータを含むリクエスト)を拒否する設定が、
本文中の「--」をHTTPヘッダーの

```lang:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarys.....
```

が含まれていると誤判定する模様。

## 対策

例1と同様に、httpd.conf等にredmineディレクトリ以下等に除外設定を行う

```lang:auditログのルールIDが[id"200003"]だった場合の例
<IfModule mod_security2.c>
SecRuleRemoveById 200003
</IfModule>
```

### 参考リンク
http://www.agilegroup.co.jp/technote/mod_security.html#jump6
Go言語のクロスコンパイル・環境設定

#Go言語のクロスコンパイル

##Linux(Ubuntu14.04) -> Windows
###前準備（Golangをソースコードからインストール）
 
// バージョン管理ツールのインストール（Golangはmercurialで管理されているため）
```sudo apt-get install mercurial```
 
// パスを設定（今回はこれ）
```GOROOT=$HOME/go
GOBIN=$GOROOT/bin
PATH=$PATH:$GOBIN ```

// ソースコードのダウンロード  
```hg clone -r release https://go/googlecode.com/hg/ $GOROOT```
 
###Golang環境をビルド
```cd $GOROOT/src
./all.bash``` 
###実行ファイルの生成
```GOOS=windows GOARCH=amd64 go build test.go ```
 
###[注意点]
[apt-get install golang]もしくは[apt-get install gccgo-go]でもインストールはできる。  
しかし、そのままだとWindows用exeを作成し実行すると正常に生成できていないので実行時にエラーが発生する。
Windows用環境をビルドしようとしても一部ソースコードがないので出来ないことがあるのでソースコードからインストールするのが無難。 


##Windows -> Linux(Ubuntu14.04)
// 一時的な環境変数を設定し、ビルド
```set GOOS=linux
set GOARCH=amd64
go build test.go ```

go build runtime: linux/amd64 must be bootstrapped using make.bat  
エラー出てビルドできない
 
###前準備
// 他プラットフォーム用のビルド設定を作る  
mingwをインストール
（環境変数PATHにmingwのbinフォルダを設定しておく）
```cd [golangインストールフォルダ]\src  
set GOOS=linux
set GOARCH=amd64
make```
 
これでlinux/amd64へのビルド環境ができる
###実行ファイルの生成
```set GOOS=linux
set GOARCH=amd64
go build test.go```
 
書き出せる。実行できる。
NGUI3.8 on Unity5 ノウハウまとめ

自分自身としてのノウハウなのでこれが正解だなんて言ってないし時と場合による！

# 開発環境
NGUI3.8
Unity5.0.0p2 (4.6.2 から移行済み)

# 俺的ノウハウ
- UIのサイズ調整
  - モバイルように作るのであればUIRootでConstrained On Mobiles に設定すると幸せになれる。
  - 縦横のサイズは想定される最大のサイズの端末にあわせる
  - 基本的にAnchorを設定することで多様なサイズの端末に合わせていく。
     - Set to Current Position 最強説ある
  - ただし、Anchorの動作するタイミングはよく考えること
     - デフォルトでonUpdateだが、1度読み込めばサイズが変わらないようなUIの場合onStartにするなどしないとパフォーマンスに影響有り
- UILabel
   - Batches(Draw Call)とDepthの関係上、Depthは99999等固定でスクリプト等でまとめると後で管理しやすくBatchesも減らせる
   - Fontは基本的にNGUIのフォントではなくUnityのフォントを使う
   - フォントの装飾としてtextに直接色等指定できる。こんな感じ(※ただしBBcode にチェックを入れる必要あり)
     - `[FF0000]Just this text is red.[-]`
- その他
  - Manager的なシングルトンのクラスを定義してUIの最初の描画系は処理しちゃう
  - オブジェクトの子オブジェクトを追加するときはNGUITool.AddChildをなるべく使う


-----------
下記はNGUIを本当に始めるときの話
NGUI3.6以降であれば下記のものをみれば問題なく初められる。
ただし、NGUI2.X、NGUI3.6より前のVersionの場合は様々な仕様が異なるようなので要注意

## チュートリアル
チュートリアルはNGUIに入っているExampleとにらめっこしながら、
Youtubeの3.6.0 Versionをひと通り見るのがいいと思う。
このチュートリアルを全部理解したら作りたいものはもう大体作れる気がする。

- Youtubeチュートリアルリンク
   - チュートリアル1(環境について)
     - https://www.youtube.com/watch?v=dM44h752LyA
   - チュートリアル2(基本)
     - https://www.youtube.com/watch?v=aWZaq1eLqyE
   - チュートリアル3(各UIについて)
     - https://www.youtube.com/watch?v=jDxWG81sNPc
   - チュートリアル4(D&D、Grid、Scrollについて)
     - https://www.youtube.com/watch?v=UK3aMHRfgcw
   - チュートリアル5(レイアウト、UIRoot、ローカライズ対応、AtlasとFontメーカー)
     - https://www.youtube.com/watch?v=GIpccFRIXmo

## 最低限抑えるTips
- Depth、Zによるオブジェクトの描画順について
  - http://qiita.com/snaka/items/eb8837c33bad6835a876
  - http://udasankoubou.blogspot.kr/2012/07/unitynguidepth2atlas.html
- スクリプトによるNGUI構築
   - http://qiita.com/hanapage/items/fd2720997fe84294b107
- PanelとDrawCallについて
   - NGUI側の描画のバッチシステムはなんか色々やってるのでちゃんとソースを読まないと理解できそうにない。
   - Panelが増える毎にDrawCallが増えるという話と、PanelがあってもZが同じであれば描画がまとめられるという話もある
   - Versionによって挙動は違いそう。要調査
   - UIScrollViewにはPanelが元から付いている

## バグ？謎の挙動について
###独自のスクリプト等でPanelをまたいだ時のスプライトオブジェクトの描画順について
Drag&Dropでアイテムを移動した後に、例えばキャンセルボタン等を実装し、元の親オブジェクトに戻したい時がある。
この時NGUIのスクリプトを介さず、オブジェクトの移動を行った場合スプライトの描画順がおかしくなる場合がある。
応急処置として、移動したオブジェクトを

```
gameObject.SetActive(false);
gameObject.SetActive(true);
```
とすることで、再度オブジェクトの描画が行われ、意図した通りの描画順になる。
※これに関してはいつか別途まとめる。。。


###UIScrollViewにおける動的なオブジェクトの追加とResetPosition

UIScrollViewに動的にオブジェクトを追加したい場合はよくあることだと思う。
何も気にせずオブジェクトを追加していると、どんどんスクロール位置がずれるので、
オブジェクトを追加したあとに一度ResetPositionを行う

参考 http://bribser.co.jp/blog/reset-position/

このとき、ScrollViewのSmoothTweenだかのオブションにチェックをしているとScrollViewの枠から要素が飛び出る。
オフにするとズレない。

また、同じオブジェクトにUIScrollViewとUIGridをつけての制御はしないほうがいい。
UIGridの初期表示位置がどうしてもずれてしまうので、UIScrollViewの子オブジェクトにUIGridのオブジェクトを追加したほうが良い

    


# その他
- 公式ドキュメント
   - http://www.tasharen.com/forum/index.php?topic=6754
- NGUIとuGUIとその開発者のすったもんだ
   - http://gamesonytablet.blogspot.kr/2014/02/nguiunity.html
- 2系は無料
   - http://tsubakit1.hateblo.jp/entry/20140317/1395066435
SizeClassでハマった話...

※追記で書きましたけど、理由がわかったのでタイトル変更(笑)
(旧タイトル：NSAttributedStringの罠にハマった話..)

--------

文字の装飾等で便利な`NSAttributedString`ですが…
こいつの意外な罠にはまったお話

## 事象

**文字サイズの変更ができない…効かない**

この一言に尽きるのですが…
`NSFontAttributeName`で`UIFont`を指定しても全然文字サイズが変わらない**場合がある**


## 原因

原因というか…なんというか

**ストーリーボード上で`UILabel`のFontをサイズクラス別に指定が合った場合、コードでの設定が無視される**

っていう仕様なのか、バグなのか…
(xib単体では検証してません...TextViewもしてません)


## 詳細

具体的にはもろもろこんな感じ

### ストーリーボードの設定

![Main_storyboard.png](https://qiita-image-store.s3.amazonaws.com/0/33521/7d5ce10d-d83e-0221-2827-130ad92191cb.png)

ストーリーボードでこういう設定
Fontの指定を追加してるだけで、あとは一緒(デフォルトのまま)


### 検証コード

```swift:ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var label2: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.setupAttributedString("hello world!!", target: self.label)
        self.setupAttributedString("good-bye world...", target: self.label2)
        
    }
    
    func setupAttributedString(text: String, target: UILabel) {
        
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSFontAttributeName, value: UIFont(name: "Helvetica Neue", size: 30.0)!, range: NSMakeRange(0, 5))
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSMakeRange(0, 5))
        
        target.attributedText = attributedString
    }

}

```

短いのでまるっとのせておきます  
どこか変でしょうか…。  
期待してる装飾内容は
**先頭5文字を大きくして、赤文字に**
という感じ


### 結果

実行結果はこう

![iOS_Simulator_Screen Shot.png](https://qiita-image-store.s3.amazonaws.com/0/33521/bf9dcc72-8a14-37c6-1d4c-47ab4d4de5a7.png)

Fontの追加設定をしてない`label1`のほうは期待通り...
`label2`の方はアカーーーーーン！！！

有名な話なのでしょうか…

## 解決策

わかりません、すみません…
教えてください、お願いします。

あれこれやってもできなかったので、
Fontの追加指定を諦めました(汗)
コードでポチッと設定したらもとより意味無いですしね。。。ですよねorz

ちなみに、実際はTableCell上のLabelで発生してたのですけど
そのときは、最初はこの通りだめでしたが
スクロールとかして reuse させると期待通りになるんですよね。。。
謎いです....


## 追記

寝て起きたら分かった
サイズ毎に指定されていた場合、お得意の`viewDidAppear:`ぐらいのタイミングで決定するんですね。。
(‘viewDidAppear:`で同じことしたら大丈夫でした)
AutoLayoutも然りですもんね...
だからcellのreuseだと効くし、別にNSAttributedStringどーのこーのという話でもない
初歩の話でした

睡眠大事(汗)
Rails(Grape)でAPIを作成する備忘録1

追記　2017/01/28
rails5でapiモードができているのでそちらを参照されたほうが良いと思います
とても簡単にrestAPIが作成できますよ

#目的
研究室内wikiツールの作成

##開発方針
* フロントはAngularを用いる
* そのためRailsではデータだけ返すAPIさえ作れれば良い

##目標
* wikiの作成、更新、削除、コメント機能の実装
* ユーザー認証の仕組みを勉強するため1から作成

##やったこと
grapeを追記

```rb:Gemfile
gem 'grape'
```

config/route.rbに以下を追加

```rb:config/route.rb
mount API => "/"
```

config/application.rbに以下を追加

```rb:config/application.rb
config.autoload_paths += %W(#{config.root}/lib/api)
```

lib以下にapi/api.rbを作成

```rb:lib/api/api.rb
class API < Grape::API
  prefix "api"
  format :json
  mount Document_API
  ...#以下作成するAPIを追記
end
```

Document_APIクラスを定義

```rb:lib/api/document_api.rb
class Document_API < Grape::API
  resource "documents" do
    helpers do
      def document_params
        ActionController::Parameters.new(params).permit(:user_id, :content, :title)
        #ここでstrong_parametersの設定
      end
    end
    
    #全件取得
    desc "returns all documents"
    # http://localhost:3000/api/document
    get do
      Document.all
    end

    #ID単一取得
    desc "return a document"
    params do
      requires :id, type: Integer
    end
    # http://localhost:3000/api/documents/{:id}
    get ':id' do
      Document.find(params[:id])
    end

    desc "create a document"
    params do
      requires :content, type: String
      requires :title, type: String
      requires :user_id, type: Integer
    end
    # http://localhost:3000/api/document
    post do
      document = Document.new(document_params)
      #ここでStrongParameterを用いたオブジェクトの作成
      document.save
    end

    desc "edit a document"
    # http://localhost:3000/api/documents/{:id}
    params do
      optional :content, type: String
      optional :title, type: String
    end
    patch ':id' do
      document = Document.find(params[:id])
      document.content = params[:content] if params[:content].present?
      document.title = params[:title] if params[:title].present?
      document.save
    end

    desc "delete a document"
    # http://localhost:3000/api/documents/{:id}
    params do
      requires :id, type: Integer
    end
    delete ':id' do
      document = Document.find(params[:id])
      document.destroy
    end
  end
end
```

一応これにてGET,POST,PATCH,DELETEは出来るようになりました
methodの中身が書いてあるサイトが少なかったので全部晒したいと思います

ここから認証を通したり、クロスドメインの設定などもやっていきたいと思います

意見や改善点などあればお願いします


参考
[RailsとGrapeでRESTのWebApiを作ってみた](http://derabon.com/2014/07/02/rails%E3%81%A8grape%E3%81%A7rest%E3%81%AEwebapi%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/)
[Grape での mass assignment 対策](http://qiita.com/milkcocoa/items/8d827ac92b179c8aa7e4)