OmniAICreator/Qiita-1.07M huggingface dataset:
Rails4.2 で devise + paranoia を使った論理削除後に同じメールアドレスで登録しようとした場合のユニーク制約を回避する方法（案）


devise + paranoia を使った論理削除の実装が簡単、かつ便利なわけですが、実装時に参考にした以下のページに、

[Rails4+devise+paranoiaで退会ユーザーの論理削除を簡単に実現する](http://qiita.com/akasakas/items/f57286a1de9b6403c745)

> 削除済のユーザーと同じemailを登録しようとするとユニーク制約にひっかかり、登録できない
>
> [Rails4 + devise + paranoiaで論理削除を考慮したユーザーバリデーションを実現する](http://dangerous-animal141.hatenablog.com/entry/2014/09/08/133533)
> これで解決できると思ったら・・・
> Rails4.2ではvalidates_uniqueness_of_without_deleted が undefined method になる。。

> Issueにもあがってたのね。。
> [validates_uniqueness_of_without_deleted undefined in Rails 4.2](https://github.com/ActsAsParanoid/acts_as_paranoid/issues/20)

> Rails4.2でユーザーバリデーションを実現する方法はないですかねぇ。。。

とあり困っておりました。

で、結局は `destroy` 直後にメールアドレスを変更しちゃえばいいんじゃないかと思い立ち、

```ruby:app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController

...

def destroy

  ...

  resource.destroy

  resource.update(email: resource.deleted_at.to_i.to_s + '_' + resource.email.to_s)

  ...
```

ってオーバーライドしたらいい感じに動きました。

論理削除後のメールアドレスは `[POSIX Time]_[元のメールアドレス]` になり、余程の事がなければ衝突はしないだろうし `/lib/` 内の devise の元のコード触るのも気が引けたので、むしろこっちのが良いかなと考えています。
ベストプラクティスに習ってAnsibleのPlaybookの構成を変更 for mac

前々回書いた[AnbileのPlaybook](http://qiita.com/takapan/items/ccf82085ee946228a44f)を[ベストプラクティス](http://docs.ansible.com/ansible/playbooks_best_practices.html)に習って、
再構成した。
昔作ったsetup.ymlをroleに分割し、commonに共通系のtaskを持ってみた。

# Role
Roleは各機能ごとにわけて作るのがいいらしい。たとえば、macの初期設定とかrbenvの設定、
calabash-iosの設定とか、fastlaneの設定とかそういう単位でだ。
ベストプラクティスに習うと、default、files、handlers、meta、tasks、templates、varsの構成で、特殊なことをしなくても基本的にはそれぞれのディレクトリのmain.ymlを読みに行くようだ。


# 具体的な構成
共通系のtaskは呼び出しタイミングは様々なので、別途rootpathにbaseSetting.ymlをおいて、commonのそれぞれのpathを変数定義しやることで、各role内から呼び出せるようにしている。

```lang:tree
├── README.md
├── baseSetting.yml
├── common.yml
├── hosts.list
├── macSetting.yml
├── main.yml
├── rbenv.yml
├── roles
│   ├── common
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   │   └── main.yml
│   │   ├── handlers
│   │   │   ├── fontCache.yml
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   ├── brewPakcagesInstaller.yml
│   │   │   ├── caskPackagesInstaller.yml
│   │   │   ├── gemPackagesInstaller.yml
│   │   │   ├── homebrewDepends.yml
│   │   │   └── main.yml
│   │   └── vars
│   │       └── main.yml
│   ├── fastlane
│   │   └── vars
│   │       └── gem_packages
│   ├── mac_setting
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   │   └── main.yml
│   │   ├── handlers
│   │   │   ├── fontCache.yml
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   │   └── main.yml
│   │   └── vars
│   │       ├── brewCaskPackages.yml
│   │       ├── brewPackages.yml
│   │       ├── brewTapList.yml
│   │       ├── gemPackages.yml
│   │       └── main.yml
│   ├── rbenv
│   │   ├── defaults
│   │   │   └── main.yml
│   │   ├── files
│   │   │   └── main.yml
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   ├── main.yml
│   │   │   └── setBashProfile.yml
│   │   ├── templates
│   │   │   └── main.yml
│   │   └── vars
│   │       ├── brewTapList.yml
│   │       ├── devEnvBrewPackages.yml
│   │       ├── main.yml
│   │       └── rbEnvBrewPackages.yml
│   └── sample
│       ├── defaults
│       │   └── main.yml
│       ├── files
│       │   └── main.yml
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       │   └── main.yml
│       └── vars
│           └── main.yml
├── setup.yml
└── site.yml

```

ソースは[github](https://github.com/takapan/macAnsible)においてるので参考までに。
batファイルでhostsへバーチャルホストを追記する方法


## batファイル作成

```bat
@echo off
if not "%1" == "-" powershell "$obj=New-Object -Com Shell.Application ; $obj.ShellExecute('%~f0','-','','runas')" & exit /b
type C:\WINDOWS\System32\drivers\etc\hosts
set /p INPUT="please type vhostname: "
echo .
echo 127.0.0.1		%INPUT% >> C:\WINDOWS\System32\drivers\etc\hosts
cmd /k type C:\WINDOWS\System32\drivers\etc\hosts
```

## 問題点
右クリックの「管理者として実行」からじゃないとアクセスを拒否される。

どなたか解決策を・・・！

## 追記
[zetamatta](http://qiita.com/zetamatta)さんからご教授頂いた部分を追記しました！ありがとうございます！
現在（2.2.4）のRiot.jsのifステートメントはfalseでも実行されてしまう件とその回避法


Riot.jsに魅せられてしまったemadurandalさんですこんにちは。

Riot.jsいいですよね。Reactから移ってきたのですがもう戻れません。

* 記述がとにかくシンプルかつHTMLセントリック（デザイナーさんにとっても抵抗少ない）。
* HTMLとJavaScriptだけでなく、CSSまでコンポーネントにカプセル化できる。
* サイズが超小さい（モバイルにも優しい）

などなど、メリットは計り知れません。ただ、まだ若いプロジェクトなので、罠もそれなりにありますね。

今回はそんな罠の一つ。表題の件です。

例えばですね。↓こういうのがあったとしましょう。

```
<my-app>
  <my-heavy-ui if={enable} arg={opt.foo} />
  
  this.enable = false;
</my-app>
```

これ、`if=false` なわけですが、実はページ上見えなくなるだけで、実際は`<my-heavy-ui>`は実行されてしまいます。取るに足らない小さい部品ならいいんですが、色々処理するような重たい部品だった場合は、嫌ですよね。

それに、再帰的に同じコンポーネントを使いたい場合は、ifで処理を止めようとしても、`if=false`でも実行されてしまうために、結局延々とネスト処理が続いてスタックオーバーフローになってしまいます。

```
<my-folder>
  <my-folder if={!isLeaf()} arg={opt.foo} />  ←ifだとうまくいかない！
  
  this.isLeaf = function(){
  	// 末尾かどうかを判定する処理
  }
</my-folder>
```

では、どうすればいいのか。eachステートメントを使います。

```
<my-app>
  <my-heavy-ui each={enable ? [true]:[]} arg={parent.opt.foo} />
  
  this.enable = false;
</my-app>
```

```
<my-folder>
  <my-folder each={!isLeaf() ? [true]:[]} arg={parent.opt.foo} />  
  this.isLeaf = function(){
  	// 末尾かどうかを判定する処理
  }
</my-folder>
```

どういうことかというと、`enable`や`!isLeaf()`が真の時は、要素数１（trueとか適当な値が１個入っている）の配列になるため、１個だけコンポーネントが生成されるのです。偽の場合は、空の配列なので、コンポーネントは生成されません。これで、擬似的にifっぽいことをしています。
注意点としては、eachステートメントを使うので、`opts.foo`は`parent.opts.foo`にしないといけませんね。

これなら、重たい部品が実は生成されていたとか、コンポーネントの再帰がスタックオーバーフローだよウワァァァンとかいうことがなくなります。

私の場合、このやり方をするようにしてから、自作のチャットシステムの表示パフォーマンスがざっと体感で数倍〜１０倍くらい速くなりました（ifを多用しまくっていたせいもありますが）。
特に、IE系はパフォーマンスの改善が顕著です。みなさま、騙されたと思ってぜひお試しを！

しかし、このifの挙動、なんなんですかね。Riot.jsのソース読んだり、Githubコミュニティに入り浸っているほど、深く足を突っ込んでいるわけでもないので、よくわかりません。

めんどくさいので、将来のバージョンでは仕様を変えて欲しいところですね。

## 2015/10/26追記

Riot.js公式サイトの日本語翻訳プロジェクトを主導され、[ikki](http://cognitom.github.io/ikki/) などのRiot拡張なども手がけていらっしゃる、国内におけるRiotの第一人者 @cognitom さんにこのifの挙動について質問したところ、こんなお答えがありました。

<blockquote class="twitter-tweet" data-cards="hidden" lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/emadurandal">@emadurandal</a> 経緯についてはこちらをどぞ。 <a href="https://t.co/xLZpdf1kHL">https://t.co/xLZpdf1kHL</a></p>&mdash; Tsutomu Kawamura (@cognitom) <a href="https://twitter.com/cognitom/status/658506965887258625">2015, 10月 26</a></blockquote>

なるほど、そうでしたか……。
実装上のやむない理由により、今のような仕様になっているのですね。もちろん、本来のifの役割として望ましい挙動でないことは開発の方々も認識されているわけなので、いずれ解決されることを期待したいですね。

それでは、皆様もよいRiot.jsライフを！^o^/
CentOS7にHHVMをインストール


## HHVM本家GitHubにドキュメントが！
[ここ](https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Centos-7.x)に載ってます！
~~消えちゃったみたいです・・・~~
復活してる(・∀・)!!

## [Fedora Copr](https://copr.fedorainfracloud.org/)版(no1youknowz/hhvm-repo)インストール

※下記は、本家GitHubのドキュメントに頼らず、[Fedora Coprにて公開されているパッケージ](https://copr.fedorainfracloud.org/coprs/no1youknowz/hhvm-repo/)を利用する方法です：

### epelのインストール

```bash
$ sudo yum install epel-release
```

### HHVMのインストール

```bash
$ sudo wget https://copr.fedoraproject.org/coprs/no1youknowz/hhvm-repo/repo/epel-7/no1youknowz-hhvm-repo-epel-7.repo -O /etc/yum.repos.d/no1youknowz-hhvm-repo-epel-7.repo
$ sudo yum install hhvm
```

または：

```bash
$ sudo yum install https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/Packages/y/yum-plugin-copr-1.1.31-508.fc24.noarch.rpm
$ sudo yum copr enable no1youknowz/hhvm-repo
$ sudo yum install hhvm
```

※ `yum-plugin-copr`はCentOSでは提供されていない模様。

### デーモン起動・有効化

```bash
$ sudo systemctl enable hhvm
$ sudo systemctl start hhvm
$ sudo systemctl status hhvm
```
Smarty 小ネタTips集

PHP言語のプロジェクトでよく用いられているテンプレートエンジン***Smarty***のTips集です。この項目では、テンプレート内のみで処理を完結させたい場合の処理が多いと思います(表示の為だけにロジックに手を入れたくない場合など)。
このページは随時更新していきます。

## 表示桁数の指定
例えばアサインされた数値「57」の頭にゼロを追加して「0057」と四桁に揃えたい場合。

```php:SmartyTemplate
# $int = 57;

# %04dの数値部分が桁数に対応
{$int|string_format:"%04d"}
# 出力結果は「0057」
```

## 文字列の分割、配列化
Smartyテンプレート内で配列を生成したい場合。下記の方法で文字列に指定の区切り文字を挿入することで分割、配列化することが可能です。

```php:SmartyTemplate
{assign var="array" value=","|explode:'apple,orange,banana'}
# $array = Array('apple','orange','banana');
```

上記で配列が生成されるが、ループ時に文字列分割を行う方法もあります。

```php:SmartyTemplate
# 文字列としてアサイン
{assign var="fruits " value="apple,orange,banana"}

# ループ構文内で文字列分割
{foreach from=","|explode:$fruits item="fruit"}
    {$fruit}
{/foreach}
```

要は`","|explode:"文字列,文字列…"`と記述することで、内部的にはPHPの`explode()`関数が実行されます。

このページは随時更新していきます。
passport-yjをWindows環境のnode.js command promptでnpm installする方法

普通にnpm install passport-yjするとOauth.plでエラーになる。
Windows環境だとPerlのパス書かないと動かない

npmをローカルに持ってきて、package.jsonを
次のように変更するとnpm installできた
 "postinstall" : "perl ./oauth2_patch.pl"
        
npm install <localpath>/passport-yj
5分でわかるSelenium IDEの使い方

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/5%E5%88%86%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8BSelenium-IDE%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/)をご覧ください😀

# はじめに
Selenium IDEでは
・テキスト入力する。
・ボタンを押す。
・メッセージが表示されていることを確認する。
といったユーザー操作に近いテストが自動で簡単にできます。

さっそく体験してみましょう。
※インストールがまだの方はこちら
[Selenium IDEをインストールする](http://qiita.com/naoqoo2/items/413dfa0aa01e9f294c53)

# 使用するサイト
今回は日本Seleniumユーザーコミュニティが用意してくれているデモサイトを使用します。
http://example.selenium.jp/reserveApp/
![予約情報入力 2015-10-09 16-00-23.png](https://qiita-image-store.s3.amazonaws.com/0/56789/56995b79-9e4a-8c17-7494-fbb8c2fd5c96.png)


# やりたいこと
今回は下記バリデーションエラーのテストをしてみましょう。

1. 名前を入力する
2. 「次へ」ボタンをクリック
3. 「宿泊日には、翌日以降の日付を指定してください。」とエラーが表示されること

# テストケースを作ってみる
Selenium IDEで上記テストをするのはとても簡単です。
ブラウザ操作を記録させることでテストケースを作ることができます。

## selenium IDE を起動
※記録ボタンが有効になっていることを確認してください。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/1eb2ae24-cc3a-29e3-dc7c-935358d3fa9d.png)

## ブラウザをいつも通り操作する
1. お名前欄に「せれにうむテスト」と入力
2. 「次へ」ボタンを押下して画面遷移

※操作が記録されていきます。


![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/71bfb435-b26e-17dd-1fa0-9bd97240deb9.png)


## メッセージを確認する
確認したいメッセージの上で右クリック→「verify Text」を選択してください。
これで表示されていることをテストできます。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/44db9c0c-9d5e-3b76-c402-6975ba950476.png)

## 記録を終了する
記録ボタンをクリックして停止します。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/cec47cf6-4cb4-d9a3-aaeb-bf4e7b8e21c7.png)

これでテストケースの完成です。
※ファイル→テストケースを保存で保存することができます。

# 実行してみる
再生ボタンを押すだけです。
※ブラウザを見ていると自動で動いているのがわかります。（スピード調整も可能です）

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/682517fb-dae1-22fd-208a-e6085b808eb9.png)

テストケースが成功すると緑になり、失敗すると赤くなります。

## 失敗例
エラーメッセージの仕様が
　「宿泊日には、翌日以降の日付を指定してね。」
だった場合、画面上は
　「宿泊日には、翌日以降の日付を指定してください。」
と表示されているため、
赤くなりバグがあることがわかります。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/fb324adf-4a4e-0d6d-6e3a-d0ed84ab38c2.png)
※テストケースを書き換えて実行する。


# さいごに
今回はブラウザ操作からテストケースを作成しましたが、
失敗例のように保存したテストケースを元に新たなテストケースを作るといったことも可能です。

ぜひテスト自動化やリグレッションテストに活用してください。
Selenium IDEをインストールする

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/Selenium-IDE%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)をご覧ください😀

# はじめに
Selenium IDEはwebブラウザのテスト自動化ツールです。
開発者でなくとも簡単に操作することが可能です。

さっそくインストールしてみましょう。

# インストール
## Firefoxをインストール
Selenium IDE はFirefoxのプラグインです。
Firefoxが入っていない場合は検索してサクッとインストールしましょう。

## Selenium IDEをインストール
※以降はFirefoxで作業してください。
Selenium IDEはアドオン検索からは見つからないため公式サイトからダウンロードする必要があります。

### 公式ダウンロードサイトを開く
http://docs.seleniumhq.org/download/
![Downloads 2015-10-09 14-58-52.png](https://qiita-image-store.s3.amazonaws.com/0/56789/53018b3d-8ba4-c52e-5987-abd0f728525d.png)


### Selenium IDE の欄へ移動
※「Selenium IDE」でページ検索するとよい

![Downloads 2015-10-09 15-04-18.png](https://qiita-image-store.s3.amazonaws.com/0/56789/5f2d6b5f-f62e-6ed9-6ec1-aa3ae1a59113.png)

### インストール
1. 上記赤枠のバージョン番号をクリックしてインストール。
2. 「このサイトからはFirefoxにソフトウェアをインストールできない設定になっています」と警告
3. 『許可』をクリック
4. 「このサイトは～未検証アドオンのインストールを求めています。～」と警告
5. 『インストール』をクリック

これでインストール完了です。

# 起動してみる
下記から起動できます。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/3e5a92b3-6a2a-a0c0-fe8c-799e778c6fcd.png)

起動するとこのようなポップアップが表示されます。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/56789/1833c6c3-579f-7e94-e35e-444f076c5b03.png)


これで準備は完了です。

さっそく使ってみましょう。
[5分でわかるSelenium IDEの使い方](http://qiita.com/naoqoo2/items/90d382cd9370d3526509)
Apacheへの接続がwinで遅い!!!!

解決方法を忘れそうだったのでメモ、
だいぶ前に設定作ったので間違っているかも・・・
解説はまとめる必要がアリアリんす（Apacheはあんまし関係無かった気が・・）

# 方法

イメージの設定→ネットワーク→ポートフォワーティング

|項目|値|
|:--|--:|
|プロトコル|TCP|
|ホストポート|22|
|ゲストポート|22|

あとはCygwinでトンネリング

```bash

ssh -L80:localhost:80 user@localhost
```
Gitの最新のタグのコミットを表示する

## 今からリリースするのでタグうってリリースだ！
ってときに変更内容とかちょろっと見たいなって時に標準であると思ったけどなかったので適当にrubyで書いた
https://github.com/jumbo-in-Jap/GiLog

このぐらいならワンライナーでshellでもかけそう

```Ruby
#!/usr/bin/ruby

class GitLog
   
    def run
         gitlog = `git log --oneline --decorate --tags --remotes`;
         latest_tag = ""
         gitlog.each_line {|line| 
            commit = line.chomp
            if commit.include?("tag:") then
                if latest_tag != commit && latest_tag != ""
                    break
                end
                latest_tag = commit
            end

            if latest_tag != ""
                p commit
            end
        }
    end
end

l = GitLog.new()
l.run()
```

↓usai氏がコメントでやってくれました :+1:
【Unity】アセットストアの無料アセット「Water Flow Free」を頂点シェーダーを使って波打たせてみた

頂点シェーダーを使って遊んでみました。


#Water Flow Free
https://www.assetstore.unity3d.com/jp/#!/content/26434

#インポートしてみる
インポートしてついてくるDemo.unityを開くとこんな画面が出てきます。
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/b281a094-a67c-d118-0c25-7f92ad13ed2c.png)

これのシェーダーに頂点シェーダーを付け足して波打たせます。

#頂点シェーダーを付け足す
Water Simple.shaderの　```#pragma surface surf Lamber```　の下に以下のコードを加えます。

```
#pragma vertex vert
void vert(inout appdata_full v)
{
	float freq = 1.4;
	float speed = 1.5;
	float size = 0.7;

	float wave =  size* sin(v.vertex.x * freq - _Time.z * speed);
	v.vertex.y -= wave;
}

```

#結果
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/78a8e81a-24a0-6ec4-4123-1c4278e08d72.png)
波打ちました。


#【おまけ】 リング状に波打たせる

先ほどの頂点シェーダーを以下のように変更します。 
座標(0.5,0.5,0.5)を中心として円形に広がるように波打つようになります

```
#pragma vertex vert
void vert(inout appdata_full v)
{
	float freq = 1.8;
	float speed = 1.5;
	float size = 1.8;
	float3 center = float3(0.5, 0.5, 0.5);

	float wave =  size* sin( length(v.vertex - center) * freq - _Time.z * speed);
	v.vertex.y -= wave;
}
```


![image](https://qiita-image-store.s3.amazonaws.com/0/44288/16f74c1a-9f81-5e32-e66c-e304449bbb6b.png)
円形に波打ちました。
楽しい！
tmuxについて(初稿)

初めて投稿いたします。
今回は、プログラミングビギナーの私が初めて使用したtmuxについてです。

よく使いそうなコマンドをまとめます。

・tmuxの立ち上げ
　tmux

・tmuxのセッション確認
　tmux ls

・新しいタブを開く
　ctrl-b + c

・タブの変更
　ctrl-b + タブの数字

・tmux終了
　ctrl-b + D


今回は軽いメモ程度のものです。

読んでくださった方、今後もよろしくお願いいたします。
【備忘録】ネットワークドライブとUNCの変換と、それに伴うハック

そもそもさ、 UNC でふつーのファイル参照と同じ事させてくれないのがイケてないよねとゆー話をグッと飲み込みつつ。

# バッチにしておく

これ確かどこかのブログからひっぱってきたんですよね。
`netuse` でドライブの一覧を出して、そこからUNCをひっぱってきて引数のパスとくっつける。

``` bat:getunc.bat
@echo off
if "%~1" == "" (
 echo no args
 exit /b 1
)
SETLOCAL
SET "D_=%~d1"
SET "P_=%~pnx1"
for /F "tokens=1,2,3" %%I in ('net use ^| findstr /I %D_%') do if "%%I" == "OK" (set "UNC=%%K" ) else ( set "UNC=%%J" )
if "%UNC%" == "" (
    echo %~dpnx1
) else (
    echo %UNC%%~pnx1
)
```

# `sendto` フォルダにでも入れておく
explorerで開いたりクリップボードに貼りつけるようなバッチをつくっておいて sendto フォルダに入れましょう。
win7 以降ならアドレスバーとかに `shell:sendto` って入れれば行けます。

# バグ

    * パスの中に一部の全角文字と、カンマがはいっているとうまくうごかないです。
AWS SNS用のiOS push通知証明書でエラー続きの君へ

# こんな時ありますよね
````
You provided a certificate of type that is not currently supported.
```

AWS SNSへ何度アップロードしてもこの状態から逃げられない場合に犯している罪について説明します

# p12ファイルの出力を当然証明書の上でやっていますよね！？
![tmp.png](https://qiita-image-store.s3.amazonaws.com/0/41027/c3b337cb-8dda-351d-27d9-20b8bf44d9d6.png)

秘密鍵の上で右クリックしてずっとエラーしてました。気をつけよう！
c++ builder XE4, 10.2 Tokyo > 動的生成 > TLabelを動的に生成する

```txt:動作環境
C++ Builder XE4 on Windows 7 pro
Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/26)
```

TLabelをフォームデザインでなく、コードで生成したい。

参考
https://groups.google.com/forum/#!topic/delphicbuilder-ml-archive/h3lxsfy1ABI


```cpp
void __fastcall TPressuresForm::Button2Click(TObject *Sender)
{
	TLabel *work;

	work = new TLabel( this );
	work->Name = L"L_test";
	work->Height = 20;
	work->Width = 100;
	work->Left = 10;
	work->Top = 5;
	work->Caption = L"TEST LABEL";
	work->Visible = true;
	work->Parent = this;
}
```
bundle exec はもういやだ


```bash
$ bundle exec rails server
```

railsにしてもrakeにしてもrspecにしても、1日に100回くらいbundle execを入力していて帰りたくなったので真面目に調べた。

ごめん、100回は言いすぎた。

[rbenv-binstubs: A Bundler binstubs Plugin for rbenv](https://github.com/ianheggie/rbenv-binstubs)

```bash
$ mkdir -p ~/.rbenv/plugins
$ cd ~/.rbenv/plugins
$ git clone https://github.com/ianheggie/rbenv-binstubs.git
```

これをいれて、後はbundle installの時にbinstubsを指定すれば、bundle execなしで実行できるぽい。

```bash
$ bundle install --path=vendor/bundle --binstubs=vendor/bin
```

bundle execと入力するのに3秒かかっていたとして、1日に100回実行していたら300秒ですよ、1日5分ですよ。

さっさと入れればよかった・・・。
DockerでRStudio Serverをサービスする手順


簡単なのは、[DockerHub](https://hub.docker.com/)に登録されている、[rocker/rstudio](https://hub.docker.com/r/rocker/rstudio/)を使うことかもしれません。

``` bash

DockerHost$ sudo docker run -d -p 8787:8787 rocker/rstudio

```

Rstudio Serverのユーザ認証は、コンテナ内のunixアカウントの認証を利用します。
Dockerfileを読むとわかりますが、rstudio:rstudioにてログインすることができます。

rocker提供wikiの中の[Using the RStudio image](https://github.com/rocker-org/rocker/wiki/Using-the-RStudio-image)も合わせて読むことをおすすめします。
CoffeeScript クラスの変数とメソッドの定義方法まとめ


CoffeeScriptのクラスまわりのシンタックスが分かりづらすぎるのでまとめました。
privateなインスタンス変数・メソッドは未実装なようです。悲しい。
protectedなんて勿論ありません。

##メソッド
###インスタンスメソッド(publicのみ)
```coffeescript:hoge.coffee
class Hoge
    hello: -> console.log('hello')

a = new Hoge()
a.hello()
```

###クラスメソッド
####public
二種類の定義方法がある。

```coffeescript:hoge.coffee
class Hoge
    @hello: -> console.log('hello')
    @hi = -> console.log('hi')

Hoge.hello()
Hoge.hi()
```

####private
```coffeescript:hoge.coffee
class Hoge
    hello = -> console.log('hello')
    @moge: -> hello()
    piyo: -> hello()
```

##変数
###インスタンス変数(publicのみ)
三種類の定義方法がある。

```coffeescript:hoge.coffee
class Hoge
    x: 10
    constructor: (@y) -> @z = 30
    print: -> console.log(@x)

a = new Hoge(20)
console.log(a.x)
```

###クラス変数
####public
二種類の定義方法がある。

```coffeescript:hoge.coffee
class Hoge
    @x = 10
    @y: 20
    @printClass: -> console.log(Hoge.x)
    printInstance: -> console.log(Hoge.x)

console.log(Hoge.x)
```

####private
```coffeescript:hoge.coffee
class Hoge
    x = 10
    @printClass: -> console.log(x)
    printInstance: -> console.log(x)
```

##参考
http://memo.devjam.net/clip/943
http://memo.devjam.net/clip/983
http://qiita.com/mm-git/items/ced8482a41cd070c245a
Visual Studio 2015 CommunityでOpenCVを使う (C++)

#Visual Studio 2015 CommunityでOpenCVを使う (C++)

OpenCVの環境構築って時間が掛かりますよね。
ライブラリを作る側は一からビルドするのが楽しいですが、
使う側にすれば大変です。

**Visual Studioの拡張機能**である**NuGet**により、
**簡単にOpenCVをインストールし利用する方法**を記録した(はず)。

ただし、Visual Studio2015と2013の２つインストールが必要になるかも...かえって面倒?

> IDEは「*VisualStudio2015*」ですが、
プラットフォームツールセットを「*VisualStudio2013*」に
変更してしまいます。

##1. NuGet Package Manager for Visual Studio の更新

1. Visual Studioを起動し、「*ツール(T)*」の「*拡張機能と更新プログラム*」から「*更新プログラムのリスト*」を選択する。
2. 「*Visual Studio ギャラリー*」 から「*NuGet Package Manager for Visual Studio*」の「*更新*」ボタンをクリックする。
3. Visual Studioを再起動する。

##2. プロジェクトにOpenCVのパッケージを追加

1. C++のプロジェクトを作成
2. 作成したプロジェクトで「*ツール(T)*」の「*NuGetパッケージマネージャ*」をクリック
3. 「*OpenCV*」で検索し、一番上にあるOpenCVを選択し「*インストール*」をクリック

> OpenCVのバージョンは本記事を編集時は
2.4.10をインストールしましたが、他のOpenCVのパッケージを
選択すれば、Ver3.0移行も存在するようです。


##3. OpenCVのパッケージの設定
NuGetを利用したOpenCVの利用方法では、*v150*は対応していなかったため、
**プラットフォームツールセットをv120に変更して利用する。**

###変更方法
1. 作成したプロジェクトのプロパティページに行く
2. 構成ページの全般にあるプラットフォームツールセットを  
「*Visual Studio 2013 (v120)*」へ変更

###Visual Studio 2013 (v120)がインストールされていないと表示されるとき
> 以下のサイトから 「*Visual Studio Express 2013*」 をインストール 
[Microsoft Visual Studio Express 2013 for Windows Desktop Update 4](https://www.microsoft.com/ja-jp/download/details.aspx?id=44914)

##実行確認
試しに以下のソースをビルドしで実行してみる。
緑色の正方形に赤色斜線が表示されたウィンドウが表示されるはずです。

```cpp:sauce.cpp
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

int main(int argc, const char* argv[])
{
	// Create Image
	cv::Mat_<cv::Vec3b> greenImg(300, 300, cv::Vec3b(0, 200, 0));

	// Draw Line
	for (int i = 0; i<greenImg.cols; ++i)
		greenImg(i, i) = cv::Vec3b(0, 0, 255);

	// Show Window
	cv::namedWindow("greenImg", cv::WINDOW_AUTOSIZE);
	cv::imshow("greenImg", greenImg);

	// PressKey Close
	cv::waitKey(0);
	cv::destroyAllWindows();

	return 0;
}
```
Swift2.0でdeviceTokenをNSUserDefaultsに保存

### 概要

NSUserDefalutsにdeviceTokenをStringで保存して、
どこかで呼び出し、という処理をやったのですが、
キャストまわりではまったので書いたコードのメモをしておきます。

1. NSDataをNSStringで受け取るにはdescriptionを参照する点
1. swiftはas!を使うとキャストできる、

といった２点がよくわかっていなくてはまりました。

swiftまだまだ勉強中です。

### 実装

以下追加します。

```swift:AppDelete.swift
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // for APNs
        let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge], categories: nil)
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()
        
        // Override point for customization after application launch.
        return true
    }

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        let ud = NSUserDefaults.standardUserDefaults()
        ud.setValue(deviceToken.description, forKey: "token")
        ud.synchronize()
    }
```

使いたいところで以下を呼び出し

```swift
let token:String = ud.objectForKey("token") as! String;
```

そもそもNSUserDefalutsに保存するがよいかどうかはあるのですが、
経験が浅いためわからないです。
やりたいことはサーバにdeviceTokenを送りたい、というシンプルなことです。

Application直下に保存しておくのがよいのかな？？

### 参考

swiftはキャストとかが直感的になりました。
まだ馴染みがないのですが馴れるとすごくよいと思います。

[swfitのcastまわりの公式ドキュメント](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html#//apple_ref/doc/uid/TP40014097-CH8-ID105)
あら怖い、さくらのDBパスワード忘れてwordpressのバックアップがとれない

#パスワード設定したの誰よ
新しくjoinしたエンジニアさんにある日尋ねられた。
「あのー公式サイト（さくらのレンタルサーバー）のDBのパスワードなんですか？」
はて、サービスのブログにwordpressを使っているのは知っていたが、デザイン会社さんに制作をお任せしていたので自分ではまったく触ったことがなかった。
しかもどうやらパスワードを設定した（らしい）当時の担当者はもういない..
もちろん、さくらのコントロールパネルでDBのパスワードは変更することができるけど、そんなことしたらwordpressが動かなくなっちゃう。
そんなわけで捜索がはじまりました

#意外に簡単に見つかる

wordpressが使ってるんだから、多分ワードプレスが知ってるだろう..とあたりをつけて探してみたらやっぱり持ってました。（こうやって平文で持っているのもなんだなあと思いますが）

```bash:wp-config.php
% cat wp-config.php | grep DB
define('DB_NAME', 'hoge_db');
define('DB_USER', 'ore');
define('DB_PASSWORD', 'OREORE123');
define('DB_HOST', 'mysql506.db.sakura.ne.jp');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

```

このDB_PASSWORDの「OREORE123」がDBのパスワードです。もちろん仮名です。
いろんなことを設定しているんだなあと思いました。
ちなみに**DB_HOST**はさくら側で割り当てられているようで、mysql__506__.db.sakura.ne.jpの部分はご自分のDB管理画面で確認してくださいね。
![スクリーンショット 2015-10-09 11.51.46.png](https://qiita-image-store.s3.amazonaws.com/0/79606/0bc3fc9f-ba06-c789-3b12-e865266c874d.png)

#自動的にバックアップを取る

これでmysqlに接続できるようになったのでとりあえず管理画面>データベースの設定>管理ツール>phpMyAdminにログインできるようになりました。
ここでGUIを使ってdumpを取ることはできるわけですが、こんなことを定期的にやるのは ~~めんどくさい~~ 非効率的なのでcronでバックアップを取ることにしましょう。

グーグル先生に聞いたらQiitaのこの方のページが見つかったので、スクリプトをありがたくパクらせていただきました。


http://qiita.com/UedaTakeyuki/items/2fa1ab453632edf92bb3

```bash:mybackup.sh
#! /bin/sh
mv dump.sql dump.old.sql
/usr/local/bin/mysqldump -Q -h mysql506.db.sakura.ne.jp -u ore -pOREORE123 (データベース名） > dump.sql 2>dump.error.txt
```
ここで気をつけるのは「mysql506」の部分を自分に割り当てられたdbに変更しないとmysqldumpがこけることです。
あとなぜかパスワードを「-p パスワード」と入れるとうまくいかず、空白を開けず「-pパスワード」と打つとうまくいきました（常識？）

一度 ./bash mybackup.sh で正しく動作することを確認してcronに登録します。
あわててcronに登録すると実行権限を与えるのを忘れてバックアップが取られてないという悲しいお知らせを受け取ることになるので気をつけましょう。

![スクリーンショット 2015-10-09 15.24.17.png](https://qiita-image-store.s3.amazonaws.com/0/79606/b5408ff2-345e-f2d5-cb7a-3da0cb0d099a.png)

cronもちろんコマンドで登録してもいいですが、ヘタレな私はGUIで登録しました。毎時0分にバックアップを取るように設定します。

ああ、よかった。これで万が一の時にまた投入する心配がなくなりました。
それにしても教訓は

***パスワードはちゃんと引き継げ*** ですね。
Play2.4、nginxを使ったファイルアップロードでのファイルサイズ上限設定

Playframework2.4のファイルアップロードで、
10MB以上の大きいサイズのファイルを上げようとしたら下記のエラーがでたので、
その解決方法をメモ。

413 Request Entity Too Large

解決するためには以下を設定。

##  nginx側
```/etc/nginx/nginx.conf
client_max_body_size 50m; // ex. 50MBの場合
```

## Playframework側
```application.conf
play.http.parser.maxDiskBuffer=50MB // ex. 50MBの場合
```
※デフォルトが10MBとなっているようです。
そしてPlay2.3までは`parsers.MultipartFormData.maxLength=50MB`だったようです。


# 参考
https://www.playframework.com/documentation/2.4.x/JavaBodyParsers
Rubyのループ中，とある条件では，処理を行わないには

ループ処理中に，ある条件のときだけは処理を行わず
次のデータを処理したい．

Rubyの前によく使っていたVBAでだっら
（gotoは使ってはいけないと習ったが）
ラベルと go to を使って　

```vbnet
For i = 1 To 10
    if cht = "A" then goto skip
    ...
    skip:
Next
```
としていたが，Rubyでは

```rb
for i in 1..10 # next はここにジャンプ
  next if i==5
  ...
end
```
としたら，iが5のときのみ処理を飛ばせると知った．

たとえば，コメント行を読み飛ばしたいときに使える．

「Rubyレシピブック」にも書いてあるのだが，かなりの間
気がつかないでいた．
悪用厳禁 nmapでポートスキャン

# 悪用厳禁 nmapでポートスキャン

## ポートスキャンとは

ネットワークを通じてサーバに連続してアクセスし、保安上の弱点(セキュリティホール)を探す行為。[e-wordsより](http://e-words.jp/w/%E3%83%9D%E3%83%BC%E3%83%88%E3%82%B9%E3%82%AD%E3%83%A3%E3%83%B3.html)

## 使い方

いいか、絶対悪用するなよ!!
絶対だからな!!

### 一番シンプルな使い方

```shell
$ nmap www.hogehoge.co.jp

Starting Nmap 6.47 ( http://nmap.org ) at 2015-04-23 17:46 JST
Nmap scan report for www.hogehoge.co.jp (xxx.xxx.xxx.xxx)
Host is up (0.030s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE
80/tcp   open  http
2222/tcp open  EtherNet/IP-1

Nmap done: 1 IP address (1 host up) scanned in 5.70 seconds
```

80番と2222番が開いているようですね。

## もっと詳細なの

-A オプションをつける
ポートで使っているアプリとか色々わかったりするが、ログに記録される可能性あり

```shell
$ nmap -A www.hogehoge.co.jp

Starting Nmap 6.47 ( http://nmap.org ) at 2015-04-23 17:50 JST
Nmap scan report for www.hogehoge.co.jp (xxx.xxx.xxx.xxx)
Host is up (0.037s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.7 ((Ubuntu))
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
| http-robots.txt: 4 disallowed entries
|_/support/h24/ /support/denso/ /support/netsupo/ /*?
|_http-title: \xE9\x9B\xBB\xE5\xAD\x90\xE3\x82\xAB\xE3\x83\xAB\xE3\x83\x86\xE3\x83\xBB\xE4\xBB\x8B\xE8\xAD\xB7\xE3\x82\xBD\xE3\x83\x95\xE3\x83\x88\xE3\x81\xAE\xE9\x96\x8B\xE7\x99\xBA\xE3\x83\xBB\xE8\xB2\xA9\xE5\xA3\xB2 | \xE3\x83\xAF\xE3\x82\xA4\xE3\x82...
2222/tcp open  ssh     (protocol 2.0)
| ssh-hostkey:
|   1024 e4:b0:24:34:87:e7:2d:fc:aa:62:14:18:4c:fa:68:7a (DSA)
|   2048 97:10:a3:1b:f6:72:f7:ed:fc:06:3c:17:9e:dd:80:90 (RSA)
|_  256 7a:ae:51:33:80:df:4e:c4:f5:25:5a:86:3f:7f:12:3b (ECDSA)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port2222-TCP:V=6.47%I=7%D=4/23%Time=5538B254%P=x86_64-apple-darwin14.1.
SF:0%r(NULL,29,"SSH-2\.0-OpenSSH_6\.6\.1p1\x20Ubuntu-2ubuntu2\r\n");

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.81 seconds
```

### 各内容解説

| STATE | 説明 | 
| --- | --- |
| open | ポートが開いている |
| closed | ポートが閉じられている |
| filtered | そのポートに対しパケットフィルタが適用されている |
| unfiltered | ポートへのアクセスは可能 |
| open\|filtered |ポートは開いている、もしくはパケットフィルタが適用されている |
| closed\|filtered | ポートは閉じられている、もしくはパケットフィルタが適用されている |

### pオプション

-pをつけると普通は1-1024までのポートスキャンを別ポートでスキャンできる。

```shell
$ nmap xxx.xxx.xxx.xxx -p 1-10

Starting Nmap 6.47 ( http://nmap.org ) at 2015-04-23 18:35 JST
Nmap scan report for www.hogehoe.co.jp (xxx.xxx.xxx.xxx)
Host is up (0.029s latency).
PORT   STATE    SERVICE
1/tcp  filtered tcpmux
2/tcp  filtered compressnet
3/tcp  filtered compressnet
4/tcp  filtered unknown
5/tcp  filtered unknown
6/tcp  filtered unknown
7/tcp  filtered echo
8/tcp  filtered unknown
9/tcp  filtered discard
10/tcp filtered unknown

Nmap done: 1 IP address (1 host up) scanned in 2.70 seconds
```


## 最後に

これやると、サーバの方でFWのログに記録されたり、攻撃とみなされてアクセスできなくなる可能性があるのでやたらめったらに撃ちまくらないこと。
[PHP] file_get_contentsを使ってPOSTするときに「Content-type not specified assuming application/x-www-form-urlencoded」エラーになる

PHPから直接リクエストをPOSTする際に、file_get_contentsを使うと「Content-type not specified assuming application/x-www-form-urlencoded」エラーになる場合の対処

以下の記述だと上記エラーが表示されます。

```php
$url = 'http://test.co.jp';
$data =array();
   
$data = http_build_query($data, "", "&");

$options =array(
   'http' =>array(
      'method' => 'POST',
      'content' => $data
   )
);

$contents =file_get_contents($url, false, stream_context_create($options));

```


どうも、ヘッダー情報がない旨のエラーのようなので、ヘッダー指定を追加。

```php
$url = 'http://test.co.jp';
$data =array();

$data = http_build_query($data, "", "&");

$header = array(
"Content-Type: application/x-www-form-urlencoded",
"Content-Length: ".strlen($data)
);

$options =array(
   'http' =>array(
      'method' => 'POST',
      'header' => implode("\r\n", $header),
      'content' => $data
   )
);

$contents =file_get_contents($url, false, stream_context_create($options));
```

これで、正常にリクエストできました。

以上
vmware > 無線LANをゲストOSで使用する

```txt:動作確認
vmware workstation on Windows 7 pro (64bit)
```

ゲストOSで無線LANを使うのは以下が参考になる。
http://studiot.jp/blog/?p=110

401HWで使用してみて、gitリポジトリへのプッシュやQiitaの閲覧などに使っている。
サブネットワークから欲しいIPアドレスを抽出

commons-netの[SubnetUtils](https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/util/SubnetUtils.html)を使って、サブネットワークから欲しいIPアドレスを抽出するやり方。

例えば、「サブネットワークの先頭5個」「サブネットワークのうち、まだ使用されていないものの先頭1個」というケースを想定。

### 0. CIDR表記からインスタンス生成

[javadoc](https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/util/SubnetUtils.html#SubnetUtils(java.lang.String))が下記の通り、丁寧に書いてあります。

```
public SubnetUtils(String cidrNotation)
Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"

Parameters:
cidrNotation - A CIDR-notation string, e.g. "192.168.0.1/16"

Throws:
IllegalArgumentException - if the parameter is invalid, i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-3 decimal digits in range 1-32
```

つまり、下記のようにしてインスタンスが生成できるということ。

```
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
```

`subnet.getInfo()` の戻り値の[SubnetUtils.SubnetInfo](https://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/util/SubnetUtils.SubnetInfo.html) から、ネットワークの情報を引き出せます。



### 1. ネットワークアドレス

`getNetworkAddress()`で取得できます。

```
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String networkAddress = subnet.getInfo().getNetworkAddress();
System.out.println(networkAddress);
```
```
192.168.0.0
```

### 2. ブロードキャストアドレス

`getBroadcastAddress()`で取得できます。

```
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String broadcastAddress= subnet.getInfo().getBroadcastAddress();
System.out.println(broadcastAddress);
```
```
192.168.0.255
```

### 3. その他のアドレス

`getAllAddresses()`で、使用できるアドレスを配列で取得できます。

```
SubnetUtils subnet = new SubnetUtils("192.168.0.0/30");
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());
System.out.println(addAddresses);
```
```
[192.168.0.1,192.168.0.2]
```
### 4. アドレスの抽出

#### 例1  サブネットワークの先頭5個

getAllAddresses()とsubListを組み合わせます。

```
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
List<String> addresses= Arrays.asList(subnet.getInfo().getAllAddresses()).subList(0, 5);
System.out.println(addresses);
```

#### 例2 サブネットワークのうち、まだ使用されていないものの先頭1個

使用済みのIPアドレスはDBから取得できるものとします。
コレクション操作のために[Guava](https://github.com/google/guava) を使います。（java7の仕事のときに編み出したので）

```
final List<String> usedAddresses = ...; //DBなどから取得
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());

Predicate<String> isUnused = new Predicate<String>() {
   public boolean apply(String address) {
          return !usedAddresses.contains(address);
   }
};

String unusedAddress = Iterables.find(allAddresses, isUnused, "");

```

### まとめ

サブネットのアドレス全体を配列で取得できるので、除外したいものをリストで取得できれば、大抵の抽出はできそう。
車輪の再発明する気がないなら、このあたりを使うと楽。

java8なら、streamとlambda式でもう少しすっきり書けるはず。
Gitのコミットメッセージ ～ fit-commitを参考に

# Gitのコミットメッセージ ～ fit-commitを参考に

これまであまりメッセージの書き方を意識していなかったので、メッセージをチェックしてくれるfit-commitを参考に記事にしてみる。

## fit-commit
[m1foley/fit-commit](https://github.com/m1foley/fit-commit)
> A Git hook to validate your commit messages based on community standards.

## チェック内容

以下、ファイル単位で内容を記載。

### capitalize_subject.rb
```rb
if lineno == 1 && text[0] =~ /[[:lower:]]/
  add_error(lineno, "Begin all subject lines with a capital letter.")
end
```
- 1行目は大文字で始める。

### frathouse.rb
```rb
if Swearjar.default.profane?(text)
  add_error(lineno, "No frat house commit messages in shared branches.")
end
```

- 汚い言葉を使わない。

[joshbuddy/swearjar](https://github.com/joshbuddy/swearjar)

### line_length.rb
```rb
if lineno == 1 && text.empty?
  add_error(lineno, "Subject line cannot be blank.")
elsif lineno == 2 && !text.empty?
  add_error(lineno, "Second line must be blank.")
elsif line_too_long?(text)
  add_error(lineno, format("Lines should be <= %i chars. (%i)",
    max_line_length, text.length))
elsif lineno == 1 && text.length > subject_warn_length
  add_warning(lineno, format("Subject line should be <= %i chars. (%i)",
    subject_warn_length, text.length))
end
```

- 1行目は空行にしない。
- 2行目は空行にする。
- 一つの行を長くしない。(デフォルト:72文字)
- 1行目を長くしない。(デフォルト:50文字)

### subject_period.rb
```rb
if lineno == 1 && text.end_with?(".")
  add_error(lineno, "Do not end your subject line with a period.")
end
```
- 1行目は「.」(ピリオド)で終わる。

### tense.rb
```rb
VERB_BLACKLIST = %w(
  adds       adding       added
  # (以下省略)
  )

def validate_line(lineno, text)
  if lineno == 1 && starts_with_blacklisted_verb?(text)
    add_error(lineno, "Message must use imperative present tense.")
  end
end

def starts_with_blacklisted_verb?(text)
  first_word = text.split.first(2).detect { |w| w =~ /\A\w/ }
  first_word && VERB_BLACKLIST.include?(first_word.downcase)
end
```
- メッセージには現在時制を使わなければならない。

> 現在時制（げんざいじせい）とは、言語で現在の行為、現象、状態等を表現する時制。用いられる範囲は言語により異なる。一般には過去時制および未来時制と対立するが、この区別も言語によって大きく異なる。

### wip.rb
```rb
if lineno == 1 && text.split.any? { |word| word == "WIP" }
  add_error(lineno, "Do not commit WIPs to shared branches.")
end
```
- 作業中(Work in Progress:WIP)のものを共有リポジトリにコミットしない。(デフォルト:master)

## fit-commit活用
これに「[Gitのコミットメッセージの書き方](http://qiita.com/itosho/items/9565c6ad2ffc24c09364)」の内容やプロジェクトごとのルールを追加していけば自然ときれいなメッセージが身につきそう。
最小構成CentOS5.11にX-windowとXfceを入れる

PHPの開発で、xdebugを使いたくなった。色々検討した結果、最小構成CentOSにNetbeans+xdebugを入れることにした。GNOMEなど立地なX-Windowは比較的重たいのでそれ以外を入れる。

```bash:groupinstallを実行し、X-Windowに必要なパッケージを一括インストール
$sudo yum groupinstall "X Window System"
```

続いてXfceインストールするが、32bit環境の場合、下記の依存性エラーが発生する。[こちら](http://fliedonion.case-of-t.net/2013/08/01/cent-os-5-6%E3%81%ABxfce%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E3%80%82/)を参考にさせていただいた。
>file /usr/share/applications/xfce-settings-manager.desktop conflicts between attempted install s of xfce4-settings-4.6.5-3.el5.i386 and xfce-mcs-manager-4.4.2-1.el5.centos.i386

```bash:依存性エラーを解消する
$wget ftp://fr2.rpmfind.net/linux/epel/5/i386/xfce4-settings-4.6.5-3.el5.i386.rpm
$sudo yum install xfce4-settings-4.6.5-3.el5.i386.rpm
$sudo rpm -ivh --force --nodeps http://mirror.centos.org/centos/5/extras/i386/RPMS/xfce-mcs-manager-4.4.2-1.el5.centos.i386.rpm
```

```bash:XFceをインストールする
$sudo yum groupinstall "XFCE4"
```

```bash:X-Windowを起動してみる
$startx
```

netbeansとxdebug編に続く……
Indirect modification of overloaded element って言われる時

PHP で配列の値を変更しようとした時、

`Indirect modification of overloaded element`

と言われれ、変更できない場合があります。
こういう時は、一旦別の変数に代入して変更すると、うまくいきます。

```php
$config = $app['config'];
$config['block_realdir'] = 'block_dir';
$app['config'] = $config;

var_dump($app['config']['block_realdir']);
// => string(9) "block_dir"
```

See Also
----------

<http://stackoverflow.com/questions/20053269/indirect-modification-of-overloaded-element-of-splfixedarray-has-no-effect>
ActionMailer で envelope_from を指定する方法

昔は sendmail を利用している場合、sendmail_settings で envelope_from を指定できた。

```rb:config/application.rb
config.action_mailer.sendmail_settings[:arguments] = '-f hogehoge@example.com'
```

いまは出来ないご様子。
https://github.com/mikel/mail/commit/4875bc2ba1670289a34a155569af2f51abddc316

envelope_from がどこで確定するのか調べると `Mail::Message#smtp_envelope_from` にたどり着く。

```rb:mail-x.x.x/lib/mail/message.rb
    # Returns the SMTP Envelope From value of the mail object, as a single
    # string of an address spec.
    #
    # Defaults to Return-Path, Sender, or the first From address.
    #
    # Example:
    #
    #  mail.smtp_envelope_from = 'Mikel <mikel@test.lindsaar.net>'
    def smtp_envelope_from( val = nil )
      if val
        self.smtp_envelope_from = val
      else
        @smtp_envelope_from || return_path || sender || from_addrs.first
      end
    end
```

ActionMailerの公式ドキュメントには `return_path` や `sender` を指定すると envelope_from を指定できると記載されているが、envelope_from だけを指定したい時は次のようにすればよい。

```rb:app/mailers/application_mailer.rb
  after_action :set_envelope_from

  private
  # envelope-from を設定する
  #
  def set_envelope_from
    mail.smtp_envelope_from = 'hogehoge@example.com'
  end
end
```
【追記あり】Milkcocoaでの簡易アクセス制御について

## 2015年11月５日に追記
MilkcocoaにAPI Key認証が加わったので、そちらを使うことをお勧めします。

https://mlkcca.com/document/authentication.html

## 本文

以下のブログにClientIdを用いたアクセス制御が書いてありますが、これと同じレベルのアクセス制御ならTopicを使ってできる気がしたので書いておきます。

http://blog.mlkcca.com/iot/access-control-by-client-id/

この方法は、開発時には簡単に使えて有効ですが、ちゃんと認証するときは[Milkcocoaでの認証方法について](http://blog.mlkcca.com/frontend/update-milkcocoa-security-rule/#update3)をご覧ください。


MilkcocoaのNode.JS SDKを利用したコード

```
var ds = milkcocoa.dataStore('foo/abcdefghijklmnopqrstu');
ds.push({});
```

Milkcocoa管理画面でのセキュリティルール

```
memo/abcdefghijklmnopqrstu {
  permit : all;
  rule : true;
}
```

これで、'foo/abcdefghijklmnopqrstu'トピック以外では、APIを受け付けません。
ClientIdでアクセス制御するよりも、文字列が重複しても良い分使い易いかもしれません。しかしこれだとコネクションは張り放題ですので気をつけて下さい。
rtmpdumpの安定性を向上させる


# 概要
gitで開発版(master)の最新をとってきてビルドしましょう


# 背景
自分は↓のようなツールをつくっていてインターネットラジオだったりニコ生だったりをrtmpdumpで録ったりしているのですが。

https://github.com/yayugu/net-radio-archive

rtmpdumpがすごく不安定でCPU100%の暴走状態になったりものすごくメモリを消費したりといったことが多くて困っていた。

# 対策
https://rtmpdump.mplayerhq.hu/

ここのgitをcloneしてみたら最近は開発止まってるんですけど、それでも2.4をリリースしたあとにもかなりの量commitがあったことがわかりました。メモリリーク修正commitもあります。

ということでそれをbuildして入れます。

```
# Linuxの場合

$ git clone git://git.ffmpeg.org/rtmpdump
$ cd rtmpdump
$ make SYS=posix
$ sudo make install
$ sudo ldconfig
```


# 結果
かなり安定しました。3日くらい運用してますが暴走したり、ゾンビ化したりするやつが今のところなくなりました。


# その他役にたちそうなworkaround
以前から使ってる、一定時間以上起動してるrtmpdumpを殺すやつ

```ruby
def kill_zombie_process
  send_signal_to_zombie_processes(:TERM)
  sleep 5
  send_signal_to_zombie_processes(:KILL)
end

def send_signal_to_zombie_processes(signal)
  pids = (`pgrep 'rtmpdump'`).split("\n").map(&:to_i)
  pids.each do |pid|
    elapsed_sec = Time.now.to_i - Time.parse(`ps -o lstart --noheader -p #{pid}`).to_i
    if (60 * 60 * 25) < elapsed_sec # 24 + 1(margin) hours
      Process.kill(signal, pid)
      puts "kill pid:#{pid} elapsed_sec:#{elapsed_sec}"
    end
  end
end
```
MacOS X El Capitanをクリーンインストールする方法


## はじめに
新しいもの好きの自分は、新OSがリリースされるとすぐにアップデートしたくなります。
その時に過去の遺産を残さないよう、毎回クリーンインストールを行うようにしています。
今回はそのクリーンインストールをする方法をメモしておきます。

### ※注意事項
失敗した場合、復旧出来なくなることがあります。
自己責任が取れない方は試さないでください。
一切の責任を負いません。自己責任でお願いします。

## 1.データをバックアップ
**必ずデータをバックアップしてください**
クリーンインストールは一度PC上のデータをすべて削除し、クリーンな状態でOSをインストールする作業です。
ローカルに保存しているデータもすべて削除するため、任意の方法でバックアップを取ってください。

ちなみに自分はTime Capsuleでバックアップをしています。

## 2.App Storeより新OSにアップデート
まずは普通に新OSにアップデートします。
App Storeからアプリをアップデートするように、新OSもアップデートしましょう。

![IMG_0651.jpg](https://qiita-image-store.s3.amazonaws.com/0/75257/0b6e962d-1112-280a-316f-202ee4c2289d.jpeg "IMG_0651.jpg")

## 3.OS X ユーティリティを起動
一度システムを終了し、Command⌘ + Rを押しながら電源ボタンから起動してください。
OS X ユーティリティが起動したら、ディスクユーティリティを選択します。

![IMG_0646.jpg](https://qiita-image-store.s3.amazonaws.com/0/75257/ba926a21-c6dd-9f12-26d0-4d792cc5e6d0.jpeg "IMG_0646.jpg")

## 4.ディスク内のデータを削除
ディスクユーティリティからMacintosh HD > 消去から消去選択してください。
フォーマットは「OS X 拡張（ジャーナリング）」にします。
消去が完了したら左上の「☓ボタン」でOS X ユーティリティに戻ります。

![IMG_0648.jpg](https://qiita-image-store.s3.amazonaws.com/0/75257/966bfa2b-8141-89a8-2ef7-3d897f9cdaff.jpeg "IMG_0648.jpg")

## 5.新OSのインストール
ディスクが空っぽでクリーンな状態になったので、ここから新OSをインストールしていきます。
OS X ユーティリティの「OS X を再インストール」を選択します。
選択すると次のような画面が出るので指示にしたがって進めていきます。
※ここでWi-Fiに接続しておいてください

![IMG_0644.jpg](https://qiita-image-store.s3.amazonaws.com/0/75257/1e4082b6-cc1c-7813-1770-a0f22f81311a.jpeg "IMG_0644.jpg")

インストール中。。。
![IMG_0653.jpg](https://qiita-image-store.s3.amazonaws.com/0/75257/34569b26-3ca1-f52f-2069-5f02700e2087.jpeg "IMG_0653.jpg")

## 6.あとはいつものように設定
位置情報やApple ID、iCloudの設定などを経て、無事クリーンインストールは完了です。
お疲れ様でした！

## おわりに
問題が起きても責任がとれて、時間があればクリーンインストールすることをおすすめします。
普通にアップデートするよりも明らかに不具合が少ないので。
Rubyでコンフィグファイルの書き換えをする

# Rubyでconfigファイルの書き換え
複数行の書き換えをしたいだけの処理
ハマってしまったのでメモとして残しておく

## 目的
/tmp/hoge.confからAAAAとBBBBのコメントアウトを消したい

```file:/tmp/hoge.conf
#config file
#$AAAA
#$BBBB
$CCCC

```

## 失敗例


```file:rewrite_failed.rb
path = "/tmp/hoge.conf"
content = File.read path
lines = {
         "\#$AAAA" => "\$AAAA",
         "\#$BBBB" => "\$BBBB"
        }

lines.each do |line, rewrite|
  File.open path, "w" do |file|
    file.write content.gsub("#{line}") {"#{rewrite}"}
  end
end
```
結果

```file:/tmp/hoge.conf
#config file
#$AAAA
$BBBB
$CCCC
```

##  成功例 

```file:rewrite_success.rb

 path = "/tmp/hoge.conf"
 content = File.read path
 lines = {
           "\#$AAAA" => "$AAAA",
           "\#$BBBB" => "$BBBB"
         }

lines.each do |line, rewrite|
  content = content.gsub("#{line}", "#{rewrite}")
  # 下記でも同様の結果を取れる
  # content.gsub!("#{line}", "#{rewrite}")
end

File.open path, "w" do |file|
  file.write content
end
```

下記でも同じ

```lang:rewrite処理の部分
File.open path, "w" do |file|
  lines.each do |line, rewrite|
    file.write  content.gsub!("#{line}", "#{rewrite}")
  end
end
``` 
結果

```file:/tmp/hoge.conf
#config file
$AAAA
$BBBB
$CCCC
```

## Memo

失敗例では読み込んだcontentには書き込まれていない
その為最後の処理しかFile.openで書き込まれていない
今回のケースのような複数回の処理をするなら破壊的メソッドで置き換える(gsub!)
またはcontent = content.gsubのようにcontent自体を更新していく
JAVA掛け算の九九の答えが全部表示されるようにしなさい

▪️問1 掛け算の九九の答えが全部表示されるようにしなさい
▪️方法①

```java
public static void test13() {
		for(int i = 1; i < 10; i++) {
		    for(int j = 1; j < 10; j++) {
		    int k = i * j;
			System.out.print(i + "×" + j + "=" + k);
			System.out.println("");
			
		}
			System.out.println("");
		}
	}
```

▪️方法②

```java
public static void test12() {
		for(int i = 1; i < 10; i++) {
		    for(int j = 1; j < 10; j++) {
			System.out.print(i + "×" + j + "=" + i * j);
			System.out.println("");
			
		}
			System.out.println("");
		}
	}
```

▪️方法①実行結果
Marimo-no-MacBook-Air:JAVA marimo$ java test21
1×1=1
1×2=2
1×3=3
1×4=4
1×5=5
1×6=6
1×7=7
1×8=8
1×9=9

2×1=2
2×2=4
2×3=6
2×4=8
2×5=10
2×6=12
2×7=14
2×8=16
2×9=18

3×1=3
3×2=6
3×3=9
3×4=12
3×5=15
3×6=18
3×7=21
3×8=24
3×9=27

4×1=4
4×2=8
4×3=12
4×4=16
4×5=20
4×6=24
4×7=28
4×8=32
4×9=36

5×1=5
5×2=10
5×3=15
5×4=20
5×5=25
5×6=30
5×7=35
5×8=40
5×9=45

6×1=6
6×2=12
6×3=18
6×4=24
6×5=30
6×6=36
6×7=42
6×8=48
6×9=54

7×1=7
7×2=14
7×3=21
7×4=28
7×5=35
7×6=42
7×7=49
7×8=56
7×9=63

8×1=8
8×2=16
8×3=24
8×4=32
8×5=40
8×6=48
8×7=56
8×8=64
8×9=72

9×1=9
9×2=18
9×3=27
9×4=36
9×5=45
9×6=54
9×7=63
9×8=72
9×9=81
iOS 9 で UIAlertController を表示時に「UIAlertController:supportedInterfaceOrientations was invoked recursively!」

# 事象
題名の通り、UIAlertController を -presentViewController:animated:completion: しようとすると UIAlertController:supportedInterfaceOrientations was invoked recursively! のログを吐きつつクラッシュする。

# 対応
以下のサブクラスを作成し、使用するように変更。

```objc:OSAlertController.h
#import <UIKit/UIKit.h>

@interface OSAlertController : UIAlertController

- (instancetype)initWithOrientationMask:(UIInterfaceOrientationMask)orientationMask;

@end
```

```objc:OSAlertController.m
#import "OSAlertController.h"

@interface OSAlertController ()

@property (nonatomic) UIInterfaceOrientationMask orientationMask;

@end


@implementation OSAlertController

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setOrientationMask:UIInterfaceOrientationMaskAllButUpsideDown];
    }
    return self;
}

- (instancetype)initWithOrientationMask:(UIInterfaceOrientationMask)orientationMask {
    self = [super init];
    if (self) {
        [self setOrientationMask:orientationMask];
    }
    return self;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return _orientationMask;
}

@end
```
Xcode7でアプリ申請時に発生するInvalid Swift Supportの対処法


## Invalid Swift Supportとは

古いCocoapods(0.39.0.beta.4以前)を利用していて且つEnable bitcodeをfalseにしていると発生する問題っぽい。

具体的にはアーカイブしたApp.xcarchive以下の```SwiftSupport/iphoneos```ディレクトリ内に入っている```*.dylib```群と```Products/Applications/AppName.app/Frameworks```ディレクトリ内の```*.dylib```の整合性が取れない事で発生する問題らしい。

対処法としては

* 手動で```SwiftSupport/iphoneos```と```Products/Applications/AppName.app/Frameworks```の```*.dylib```を一致させる方法
* Cocoapodsをbeta版に上げる方法

がある。

##手動で *.dylibを一致させる方法

こちらは至って単純で、

1. archiveしたbuildをorganizer上で右クリック
2. Show in Finderを選択
3. terminal等でAppName.xcarchiveに移動
4. ```open SwiftSupport/iphoneos```でFinderを開く
5. ```open Products/Applications/AppName.app/Frameworks```でFinderを開く **※ "AppName"は適宜置き換えて下さい**
6. ```SwiftSupport/iphoneos```内の*.dylibを **全て** 選択し、```Products/Applications/AppName.app/Frameworks```に **コピー** (勿論terminal等でコピーを行ってもOKです。)
7. ↑の操作を行ったうえで、Validate & Upload to AppStoreを行う

##Cocoapodsのバージョンを上げる方法

こちらに関してはチーム開発を行っている場合などは相談をしてからやったほうが良いかもしれないです.

ただやり方は簡単で

```zsh
$ gem install cocoapods --pre
```

をするだけです。

また、この投稿を行った際は```--pre```となっていますが、```0.39.0```が正式リリースされているのであれば、普通にバージョン上げればいいと思います。

##参考
* ['Invalid Swift Support' email from iTunes when submitting with Xcode 7 GM & Cocoapods](https://github.com/CocoaPods/CocoaPods/issues/4188)
* [Invalid Swift Support - Files don’t match](http://stackoverflow.com/questions/32526526/invalid-swift-support-files-don-t-match)
Androidアプリのログ収集をどうしよう

今開発中のAndroidアプリの行動ログ収集をしようと思います。

# 経緯
別システムですが開発中の段階から(エラーログはもちろん)、行動ログ収集しておくと社内でも不具合の状況共有、把握、調査が簡単になりました。
なので今開発中のAndroidアプリもそのあたりが簡単になるかもしれないと思い、クラッシュと行動両方のログ収集サービス導入を検討しています。
簡単に調べたものと何を選ぶべきかの整理のメモです。


# 構成候補
* **自由** かつ **無料** かつ **簡単** なものを選びたい
* 構築の技術が他のサービスでも使えたり、Web, Android, iOS 関わらず一元的に見れたり、ツールの使い方を自分たちや運用の方に毎回覚えてもらう必要を無くしたいので できれば技術的・使用感的な意味で汎用的なもの
* そのまま本番でも使いたい
* 弱い希望で、オープンソースかつプラガブルでエコシステムが充実してる(途中でもいい)ものをつかいたいなぁ

◎○△✕で表現。

| 構成 | 説明 | 自由 | 無料 | 簡単 | 汎用的 | オープン |
|:---:|:----:|:---:|:---:|:----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| Fluentd + elasticsearchかそのあたり(自前) |  | ◎ | サーバー代 | ✕ | ◎ | ◎ |
| Fluentd + Google Cloud Logging |  [わかりやすい説明] (http://www.slideshare.net/Zaki_XL/log-collect-with-google-fluentd) | ○ | 有料だしサーバーも必要 | ✕ | ◎ | ○ |
| 外部サービス系 |  | ✕ | △わりと無料 | ◎ | ✕ | ✕ |


### Fluentd + elasticsearchかそのあたり(自前)

#### いいところ
* なんでもあり
* 外部にログを置けないプロジェクトでもok
* どこにでも使える。いろいろな所で使えば技術的にも運用時の学習コスト的にも良い

#### 悪いところ
* fluentd の オフィシャル の 単体 の android の sdk なさそう
* サーバーの構築運用必要。

### Fluentd + Google Cloud Logging

#### いいところ
* 情報がある [わかりやすい説明] (http://www.slideshare.net/Zaki_XL/log-collect-with-google-fluentd)
* BigQuery 検索早い

#### 悪いところ
* 安いけど有料かな
* BigQuery使うのに 別でfluentdの受け口用のサーバーが必要
* sdk ない
* [まだベータ版](https://cloud.google.com/logging/docs/)


### 外部サービス

#### いいところ
* 導入がすごく簡単
* 負荷を気にしなくていい
* ロガーのバグを疑わずにすむ(ことが多いと思う)
* サーバー不要

#### 悪いところ
* そのうち有料化されそう
* 用意された範囲でしか使えない
* Webまでは考えられてない
* 外部にデータを預けるのがNGな案件では使えない
* クラッシュログと行動ログ分かれているものもある
* 横断的なログを見たい時大変かも
* いろいろなサービスを使っていると導入、学習コストがかかる

# 外部サービス
## クラッシュレポート
| Service |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| [Crashlitics](https://try.crashlytics.com/) |
| [splunk](https://mint.splunk.com/) |


## 行動ログ
| Service |  |
|:---:|:---:|:---:| 
| [Segment](https://segment.com/) | [わかりやすい説明](http://www.slideshare.net/tomoakiimai2/presentation-log-managementinandroid) |
| Puree | [わかりやすい説明](http://techlife.cookpad.com/entry/2014/11/25/132008) |


# 今なら
「Fluentd + elasticsearchかそのあたり(自前)」 

* aws の kibana セットの elasticsearch が良さげと教えてもらった
* もう aws から逃げられなくなってきた ...
vimでのコロンとセミコロンの強調表示

最近はかなりSASS/SCSSが使われるケースが増えていますが(俺調べ)、自分の周囲ではSASSガリガリ君より「CSSの延長でSCSS」という人が非常に多く(俺調べ)、というか自分です。

そうなると避けて通れないのがコロンとセミコロン、右手の小指があまりちゃんと動いてくれない人なので結構押し間違えるんですよこの2つ[^1]。なので vim のハイライトで見分けられるようにこういう風に書きました。

[^1]: そういう人間がvim使うって冷静に考えると選択ミスでは。

```vim:.vimrc
function! StyleHighlight()
	highlight colon ctermbg=0 ctermfg=45
	highlight endSemicolon ctermbg=54 ctermfg=122
endfunction
if has('syntax')
	augroup AddHighlights
		au!
		autocmd ColorScheme * call StyleHighlight()
		autocmd VimEnter,WinEnter,BufRead * let w:m1=matchadd('colon',':')
		autocmd VimEnter,WinEnter,BufRead * let w:m2=matchadd('endSemicolon',';\{1}$')
	augroup END
	call StyleHighlight()
endif
```

* matchでやると最後の一つしか適用されないのでmatchaddで複数登録した。
* セミコロンは行末の一個だけに適用した。切った貼ったしてるウチに複数並んでたりするのは特にチェックとかしない。しないったら。
* 色は自分のカラースキーマに合わせて変えて下さい、自分の場合は「とりあえず目立たせる」が目的なので結構変な色です。
* gvimは使ってないのでそれ関連の指定はゴニョゴニョして下さい。

「行末の空白を強調表示」ってサンプルは沢山あるんだけど「コロンとセミコロンを別の色に、.vimrcがとっ散らからないように一箇所で指定」というケースがなかなか見つけられなかったのでココに残しておこうという程度の内容です。

vimscript をバリバリ書ける哲人でもなんでもない素人がアチコチ調べながら書いた物なので、「もっとシンプルに書けるやん」「ココこう書くと問題が出るかも知らんから○○使ったほうがええで」みたいな話がありましたらご教示頂けると幸いです。

おわり。