OmniAICreator/Qiita-1.07M huggingface dataset:
gitコマンドやブランチ名の入力時補完を出来るようにする

# はじめに
gitコマンドやブランチ名の補完が出来たら便利じゃないか、と思っていたところ
git-completionを使うと実現出来ると知ったので、導入方法をまとめておく。
正直Git使うなら使わない手はない。

公式はこちら。
https://github.com/git/git/tree/master/contrib/completion
（zsh, tcshにも対応している。）

# 前提
- bash
- Git 2.18以降[^1]
- OS: Mac, Debian, CentOSなど

# 手順
以下の3ステップで完了です。
1. git-completion.bashを取得する
2. git-completion.bashを.bashrcで読み込むように書き加える
3. .bashrcの設定を反映する

以下は導入の一例。

```
$ curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/.git-completion.bash
$ echo "source ~/.git-completion.bash" >> ~/.bashrc
$ source ~/.bashrc
```

# 使い方
gitコマンドやブランチ名を打ちかけているところでタブキーを叩きます。
`git che`とタイプしてタブキーを叩くと`git checkout`,`git cherry`,`git cherry-pick`が補完候補として表示され、`git chec`とタイプしてタブキーを叩くと`git checkout`が補完されます。
シェルによるコマンドやファイル名の補完と一緒ですね。

ここで以下のようなエラーが出る人は、Gitのバージョンが古い（git-completion.bashの記述に対応していない）可能性があります。
Gitのバージョンを2.18以上にすると解消するかと。

```bash:bash
$git checko #ここまで打ちかけてタブキーを叩いて以下のようなエラーが出る場合
Unknown option: --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
```
（筆者はDebianでも使おうとしたところ、aptでGitのv2.11がインストールされていたのでこのエラーに出会いました。）

# おわりに
筆者は普段はMacでTerminalにてbashを使う事が多いが、DebianやCentOSでも勿論git-completionは使える。
`yum`や`apt`でインストール出来るGitのバージョンはやや古いので、留意すべし。
よく使うコマンドはエイリアスを使い、トピックブランチの入力補完は本機能を使う、のがよくある手だろうか？

[^1]: 投稿時点（2018/9/17）では、git v2.18から加わった`--list-cmds` に対応している事が必要なようです。https://apple.stackexchange.com/questions/327817/git-completion-bash-producing-error-on-macos-sierra-10-12-6
配列内から特定の要素を探す方法(array_key_exist, in_array, array_search)

配列内から特定の要素をとりだしたり、真偽判定をする際に用いることのできる手法。
#array_key_exist()
特定の**キー**を持つ要素を探すことができる。
発見できた場合trueを返す。
因みに近しい関数でisset関数があるが、**キーに紐づいている値がNULLの場合、issetはfalseを返すがarray_key_exist関数はtrueを返す**という違いがある。

```php:ex.)
$array = ['breakfast' => 'TKG',
          'lunch'     => 'Sushi',
          'Dinner'    => 'Ramen'
         ];

if(array_key_exists('breakfast', $array)){
    echo "今朝は".$array['breakfast']."を食べました。";
}

//今朝はTKGを食べました。
```

連想配列でなく通常の配列でもキーを第一引数に入れてあげればarray_key_exists関数は使用できる。

```php:ex.)
$array = ['apple', 'banana', 'lemon'];

if(array_key_exists('2', $array)){
    echo "3つの果物を感じる....";
}

//3つの果物を感じる....
```

また多次元配列の場合、一次元に関しては問題なく関数の実行ができるが、**それ以上の次元に関数を当てる場合、展開の必要がある。**

```php:ex.)
//一次元に対して関数を実行
$array = ['breakfast' => ['rice', 'grilled salmon', 'salad'],
          'lunch'     => ['ramen', 'gyoza'],
          'dinner'    => ['rice', 'nikuzyaga', 'salad']
         ];

var_dump(array_key_exists('lunch', $array));
//bool(true)

//二次元に対して関数を実行
var_dump(array_key_exists('lunch[0]', $array));
//bool(false)

//展開後実行
foreach($array as $meal){
    var_dump(array_key_exists('0', $meal));
}
//bool(true) bool(true) bool(true)
```

#in_array#
特定の**値**を持つ要素を探すことができる。
発見できた場合trueを返す。
こちらも対応できる範囲が一次元までなのでそれ以上追うならば展開の必要がある。

```php:ex.)
$array = ['breakfast' => 'TKG',
          'lunch'     => 'Sushi',
          'Dinner'    => 'Ramen'
         ];

var_dump(in_array('TKG', $array));
//bool(true)
```
#array_search#
in_array関数と同様に特定の値を持つ要素を探す関数だが、**真偽値を返すのではなく、紐づいているキーを返す。**
こちらも対応は一次元までになる。

```php:ex.)
$array = ['breakfast' => 'TKG',
          'lunch'     => 'Sushi',
          'Dinner'    => 'Ramen'
         ];

var_dump(array_search('TKG', $array));
//string(9) "breakfast"
```
ROS (Robot Operating System) を勉強し始めた

# ROS(Robot Operation System)とは
ROS (Robot Operating System)は、ソフトウェア開発者のロボット・アプリケーション作成を支援するライブラリとツールのこと

# なぜ勉強するのか？
**私はロボットに関しては門外漢です。**私の場合は、ロボットにセンサーを搭載して測定をしたいと考えていて、ロボットの位置や姿勢の情報とセンサーの情報を組み合わせて画像を撮りたいので、ロボット屋さんにそこらへんを聞こうとしたら、話が通じない。曰く「ROSを勉強したらわかる」とのことなので、ROSを勉強して、どうやったらロボットの位置や姿勢情報を自分が欲しいデータとして入手できるかを調べてみたというわけです。

# 参考URL

[ROSについて学ぼう](https://kazuyamashi.github.io/ros_lecture/)
このサイトがしっかりと書かれていて、最も分かりやすかったです。まず最初に見るのをお勧めします。

[(公式)ROSのチュートリアル](http://wiki.ros.org/ja/ROS/Tutorials)
こちらはチュートリアル。こちらもしっかりと書かれているので、上のサイトで得た知識をおさらいしつつ、チュートリアルで実践できます。（まだ自分はやっていませんが...）

[ROSではじめるロボティックス](http://bril-tech.blogspot.com/2016/10/ros2-ros.html)
こちらも良いチュートリアルです。実際にROSを動かすことができます。

# まとめ

まだ勉強途中なので、上のサイトで勉強して、また更新していきます。
間違っているところがあれば、ご教示ください。
【swift】delegateを継承して利用する

delegateを継承して利用する場合は、継承先のクラスでキャストして利用すれば複数の継承を行っても問題なく利用できます。

```swift
import UIKit

class ViewController: UIViewController, DDDDelegate {
    
    let ddd = DDD()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        ddd.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func printAAA() {
        print("AAA")
    }
    func printBBB() {
        print("BBB")
    }
    func printCCC() {
        print("CCC")
    }
    func printDDD() {
        print("DDD")
    }
    
    @IBAction func TouchAAA(_ sender: Any) {
        ddd.startAAA()
    }
    @IBAction func TouchBBB(_ sender: Any) {
        ddd.startBBB()
    }
    @IBAction func TouchCCC(_ sender: Any) {
        ddd.startCCC()
    }
    @IBAction func TouchDDD(_ sender: Any) {
        ddd.startDDD()
    }
}
```

```swift
import UIKit

// プロトコル
protocol AAADelegate: class {
    func printAAA()
}

class AAA: NSObject {
    weak var delegate: AAADelegate?
    
    func startAAA() {
        self.delegate?.printAAA();
    }
}
```

```swift
import UIKit

// プロトコル
protocol BBBDelegate: AAADelegate {
    func printBBB()
}

class BBB: AAA {
    
    func getDelegate() -> BBBDelegate? {
        return self.delegate as? BBBDelegate
    }
    
    func startBBB() {
        self.getDelegate()?.printBBB()
    }
}
```

```swift
import UIKit

// プロトコル
protocol CCCDelegate: BBBDelegate {
    func printCCC()
}

class CCC: BBB {
    
    func getDelegate() -> CCCDelegate? {
        return self.delegate as? CCCDelegate
    }
    
    func startCCC() {
        getDelegate()?.printCCC();
    }
}
```

```swift
import UIKit

// プロトコル
protocol DDDDelegate: CCCDelegate {
    func printDDD()
}

class DDD: CCC {
    
    func getDelegate() -> DDDDelegate? {
        return self.delegate as? DDDDelegate
    }
    
    func startDDD() {
        getDelegate()?.printDDD()
    }
}
```
Pythonで競プロに挑む日誌 vol.11 ~for 文中の "_"~

# 現在の目標
* 今年の10月内に茶色を取得する
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の A, B 問題を全部解く**←イマココ**
* 年内に緑色を取得する
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) の C, D 問題を全部解く
* [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

#今日の問題
ABC004B - 回転 
https://beta.atcoder.jp/contests/abc004/tasks/abc004_2


# 結果

```answer1.py
#coding: utf-8
c = (input() + input() + input() + input())[::-1]
print(c[0:7])
print(c[7:14])
print(c[14:21])
print(c[21:28])

# 実行時間：17 ms
# メモリ　：2940 KB
# コード長：132 Byte
# 得点　　：100/100
```
やることはすぐにわかりました.

```math
C_{i,j} → C_{3-i, 3-j} 
```
とすればよいので, 文字を連結して, 単純に逆から表示しました.  ただ, やっぱりもっと短く書く方法はあるのですね.

```answer2.py
#coding: utf-8
print("\n".join(input() for _ in range(4))[::-1])

# 実行時間：17 ms
# メモリ　：2940 KB
# コード長：65 Byte
# 得点　　：100/100
```
たしかに, join で改行連結すればよいですね.
あと, for を回したいけど値を使わないときは, _ で代用できるんですね.

# 今回学んだこと
* [文字列の反転方法](http://d.hatena.ne.jp/redcat_prog/20111104/1320395840)
* [python におけるアンダースコア "_" の役割](https://qiita.com/ikki8412/items/ab482690170a3eac8c76)


#明日やること
 * [ABC](
https://kenkoooo.com/atcoder/?user=&rivals=&kind=category) を解き続ける.
はじめてなElixir(5) / を整数演算にする

ちょっぴりマクロで遊んだので備忘録。

[はじめてなElixir(4)](https://qiita.com/kikuyuta/items/5a9c1177d2b3b025a7cf)で div 演算子を Kernel.div じゃなく自分の定義した div 関数を呼ぶようにしたので、いい気になって / 演算子を置き換えます。

# どうにも気になる / 演算子

代数としては一つの台集合上に演算が定義されててほしいじゃないですか。なので Elixir で（というか Erlang がそもそもなんでしょうが） / 演算子に整数突っ込んだ結果が浮動小数になるのは残念です。

```
iex(1)> 1
1
iex(2)> 1 * 1
1
iex(3)> 1 / 1
1.0
```

ってなんかヘンじゃありませんか？ 同じ整数の台の上に居てほしいですよね、

## マクロを使ってみる
ということで演算子を自分で定義してみました。
** これは大変危険な匂いがします。未来の自分を混乱させます **

```
defmodule Overload do
  defmacro m / n do
    quote do
      Kernel.div(unquote(m), unquote(n))
    end
  end
end
```

これ、そのまま使っても何も起こりません。

```
iex(2)> 1/2
0.5
```

もともとの演算子を黙らせてから使います。

```
iex(3)> import Kernel, except: [/: 2]
Kernel
iex(4)> 1/2
** (CompileError) iex:4: undefined function //2
```

黙らせてしまったので / の演算自体ができなくなります。

```
iex(4)> import Overload
Overload
iex(5)> 1/2
0
iex(6)> 1/1
1
```

さっき定義したマクロを import するとそっちが有効になります。

マクロまで使ってプログラムすることはそんなにないだろうと思います。Scheme/Lisp は、quote を ' unquote を ` を使って積極的に使いたくなる文法にする、ってことをしてますが、Elixir はそうじゃないですし、こういうこともできるんだぐらいで。

# 参考文献
プログラミングElixir 本の 20.7 節を参照してます。
多形状3次元ボクセルレンダリング編集環境を作る

はじめまして。

これまで様々なWebの資料に助けて頂きました。
その恩を返せるかはわかりませんが、興味を持って
調べていた内容をGoogleスライド上にまとめましたので、
共有したいと思います。今回が初投稿となります。
何か意見や訂正すべき箇所がありましたらコメントを頂ければと思います。

https://docs.google.com/presentation/d/e/2PACX-1vRMvP_wTiXbixyajiSDdiLWXNd6ZMVL6LkSDUFtPN1_kw5HFnAK56PRRbsiGEIBBTsuChyxkrf6U9aG/pub?start=false&loop=false&delayms=3000
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0. に対応する

Gradle のバージョン上げると、以下のような警告が表示される事がある。

```
Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/4.10.1/userguide/command_line_interface.html#sec:command_line_warnings
```

まぁ中身はその通りで、非推奨の機能を使っていて、5.0 では無くなるよ、という警告です。

実際に何が非推奨かを具体的に教えて欲しかったら、以下のファイルを作っておくとよい。

```shell:gradle.properties
org.gradle.warning.mode=all
```

（コマンドラインから一時的に指定することもできるけど、warn は常に ON にしておくべきなのだ。。。たぶん）

# 自分の場合

自分の場合、以下のように `ConfigurableReport.setDestination` が悪いと言われた。

```
The ConfigurableReport.setDestination(Object) method has been deprecated. This is scheduled to be removed in Gradle 5.0. Please use the method ConfigurableReport.setDestination(File) instead.
        at build_7lmo6x5yy25habfnsnz0lhhh2$_run_closure3$_closure25.doCall(~/build.gradle:191)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
```

実際に gradle は明示的に書いていなくても method 呼び出しになったりするので、行数を見るのが言い

```gradle:build.gradle#該当の行
        xml.destination "${buildDir}/reports/jacoco/report.xml"
```

`buildDir` というところにビルドディレクトリが入るので、この書き方で full path が取得できて実際動くのですが、もう少し現代的に　 `file('ビルドディレクトリからの相対パス')` で `File` 型で該当ファイルのパスがとれます

```gradle:build.gradle#TOBE
        xml.destination file('reports/jacoco/report.xml')
```
OPENVPNでError Loading extension section serverエラーが出る

忘備録がてら

環境:Ubuntu Server 18.04 LTS

openvpnでVPNサーバー証明書を作ろうとしたら以下のエラーが出た

```
Error Loading extension section server
140377123566016:error:2207507C:X509 V3 routines:v2i_GENERAL_NAME_ex:missing value:../crypto/x509v3/v3_alt.c:496:
140377123566016:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:../crypto/x509v3/v3_conf.c:47:name=subjectAltName, value=CommonName
```

解決策:[StackOverflow](https://superuser.com/questions/897437/openssl-error-error-loading-extension-section-server)

pkitoolの中の
```
KEY_ALTNAMES="$KEY_CN"
```
を
```
KEY_ALTNAMES="DNS:${KEY_CN}"
```
にしたら上手くいった
PHP HTMLを用いてformを作成し、POSTで値の送受信を行う

##HTMLを用いた入力フォームの作成##

```form.php

<html>
<body>
入力フォーム

<form action="sample.php" method="post"> 

<!--formタグによってデータの受け渡しを行う。action属性で指定したファイルにデータを渡す。method属性でデータを送る際の送信方法を指定する。-->

      <td>テキスト</td>
      <td><input type="text" name="name"></td> 

<!--inputタグのtypeオプションではtextを指定してtextフィールドを表示している。nameオプションでは指定した名前で入力データが送られる-->

        <input type="submit" value="送信">

<!--typeオプションでsubmitを指定し送信ボタンを表示している。valueにはボタンに表示する名前を入力できる-->

</form>
</body>
</html>
```

ブラウザで開くとこんな感じです。
![スクリーンショット 2018-09-17 20.28.49.png](https://qiita-image-store.s3.amazonaws.com/0/290560/606665b1-5f5d-28c7-fa8f-e70426b13fbc.png)



##入力フォームから送られた値を$_POST()で受け取り表示する##
```sample.php

<?php
    $name = $_POST['name']; 
/*入力フォームでmethodをpostに指定しているため＄＿POSTによって受け取る。入力したテキストはnameという名前で送信されているので＄_POST['name']となる*/

    print ("次のデータを受け取りました<br />");
    print ("$name<br />");
    ?>
```
先ほどの入力フォームに　こんにちは　と入力し送信ボタンを押すと、以下のように表示される。
![スクリーンショット 2018-09-17 20.39.24.png](https://qiita-image-store.s3.amazonaws.com/0/290560/5fb43b01-13d0-b9bf-16bd-641792ee5a09.png)
Zabbix API の利用例


### テンプレートが所属するグループ、そのテンプレートを適用しているホストを含め取得する。

request:

```
{
    "jsonrpc": "2.0",
    "method": "template.get",
    "params": {
        "output": [
            "templateid",
            "host"
        ],
        "selectGroups": [],
        "selectHosts": [],
        "search": {
            "host": [
                "Linux"
            ]
        }
    },
    "auth": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "id": 2
}
```

respons:

```
{
    "jsonrpc": "2.0",
    "result": [
        {
            "templateid": "10001",
            "host": "Template OS Linux",
            "groups": [
                {
                    "groupid": "10"
                }
            ],
            "hosts": [
                {
                    "hostid": "10084"
                }
            ]
        },
        {
            "templateid": "10248",
            "host": "Template OS Linux SNMPv2",
            "groups": [
                {
                    "groupid": "10"
                }
            ],
            "hosts": []
        }
    ],
    "id": 2
}
```
[jQuery] onメソッドの使い方

jQueryを使って動的な要素にイベントを付けるときによく使うメソッド。


jQueryは動的な言語なので、書いた構文がドキュメントに存在しないことになってしまう。
つまり、ある構文の下にその構文に対してイベントを与えたい構文を書いても、上にある構文は存在していないので影響を与えられない。

$("button").click(function(){
  var p = $('<p>').text('ok!').addClass('ok');
  $(this).before(p);
});

$(".ok").click(function(){
  $(this).remove();
});

↑このような感じでok!の文字を消そうとしても、消すことができない


そのような際に、onメソッドを使えば、構文に対してイベントを与えられる。

$("button").click(function(){
  var p = $('<p>').text('ok!').addClass('ok');
  $(this).before(p);
});

$('body').on('click', '.ok', function() {
   $(this).remove();
});

↑こうすれば、ok!の文字を消すことができる
Raspberry Piでkubernetesクラスタを組んでみる②

# RaspberryPi（共通）の初期設定
## ログインする
初期パスワードは`pi/raspberry`でログイン出来ます。

## rootパスワードを設定する
通常のLinuxと同じです。

```
$ sudo passwd root
Enter new UNIX password: 新しいパスワード
Retype new UNIX password: もう1回
```
## vimを最低限使えるようにする
キーボードがUSキーボードの設定になっており、
vimでこの先のネットワークの設定を行うのにカーソル移動（矢印キー）を打鍵するとABCDが入力されたりと少々難儀なのでカーソル移動くらいはできるようにしておきます。
ネットワークに繋がるようになれば別のPCからssh接続すればいいのでそんなにはいじりません。

```
$ sudo vi /root/.vimrc
# で、下の一行を記述してください
set nocompatible
```


## ホスト名を変更する
ホスト名はクラスタを構成する各ノードごとで全てユニークなものにしてやらないといけません。
私の場合は以下のようにしました。（`/etc/hostname`を編集）

| node    | hostname     |
|:-------:|:------------:|
| master  | raspberrypi0 |
| worker1 | raspberrypi1 |
| worker2 | raspberrypi2 |


## ネットワークに繋がるようにする
`sudo vi /etc/network/interfaces`

以下の記述を追加しましょう
ちなみにこれはmasterの設定です。

```
auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid SSID
wpa-psk PASSWORD
```

workerは以下のように設定します。

```
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp
```
rebootすればネットワークに繋がると思います。
# rootでsshログインできるようにする
```
sudo vi /etc/ssh/sshd_config

# PermitRootLogin の項目のコメントアウトを解除して設定値をyesに
```
# Docker のインストール
ここからはrootでログインして行いました。

```
# 必要なパッケージのインストール
$ apt-get install apt-transport-https ca-certificates curl software-properties-common

# リポジトリの追加
$ curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | sudo apt-key add -
$ echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
     $(lsb_release -cs) stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list

# インストール
$ apt-get update
$ apt-get install docker-ce
```

# kubeadm, kubelet, kubectlのインストール

```
# swapを無効に
$ dphys-swapfile swapoff
$ dphys-swapfile uninstall
$ update-rc.d dphys-swapfile remove

# リポジトリ追加
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo apt-key add -
$ echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kube.list

# インストール
$ apt-get update
$ apt-get install kubelet kubeadm kubectl
```
WebExtensionsによるアドオン開発でつまづいたこと

# はじめに

WEBサイト閲覧の効率化のためにFirefoxアドオンを自作しました。そのときに、躓いたことをいくつかまとめてみました。同じようなことで困っている人がいたときの参考になればと思います。

※[初めての拡張機能](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension)を読んでいる前提で話を進めます。
※憶測で書いている部分があるので、間違いがあればご指摘ください。

# 注意すべきことたち
## console.logではTypeErrorなどの例外がみえない
普段どおり`console.log`を使ってデバッグをしながら開発をされるかと思いますが、通常のJavaScriptの仕様であれば、次のような挙動を示すはずです。

```JS
var a = [];
console.log(a[0]);    // undefined
console.log(a[0][0]); // TypeError: a[0] is undefined
```

しかし、アドオンのコンテンツスクリプトで動かしているとなぜかTypeErrorが隠蔽されてしまうため、バグの発見が困難になります。
実際、もう少し技術的な問題なのかと思っていましたが、上記のような挙動を知らずのうちにやってしまいデバッグに時間がかかってしまいました。

### 解決手段
@chromia さんよりコメントにて解決方法を教えていただきました。

[コンテンツスクリプト](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Content_scripts)（manifest.jsonでcontent_scriptsで指定しているスクリプトのこと）上でのType Error等の例外は、Ctrl+Shift+Jを押下で出現する[ブラウザーコンソール](https://developer.mozilla.org/ja/docs/Tools/Browser_Console)を使うと見えるようになります。

アドオン開発でデバッグするときはCtrl+Shift+I押下で出現する開発者ツールのコンソール**ではなく**、Ctrl+Shift+Jを押下で出現するブラウザーコンソールを使用するべきです。

## browser.menus is undefined が出てしまう

```JSON:manifest.json
{
  "content_scripts": {
    "matches": ["*"],
    "js": ["target.js"]
  }
}
```
のように`content_scripts`で指定しているスクリプトからは呼べません。

```JSON:manifest.json
{
  "background": {
    "scripts": ["target.js"]
  }
}
```
このように`background`で指定して呼びます。ちなみに、`content_scripts`と`background`で両方指定してる場合も動かなくなるので注意してください。


## XMLHttpRequestが使えない（なぜかステータスコードxhr.statusで0が返ってくる）
対象のサイトが持つAPIを通して情報を取得したい場合、セキュリティの問題上閲覧中のウェブページとAPIのドメインが違うとき（クロスドメインと呼ばれる）にブラウザで実行しないように設定されています。

これを解除するためにはmanifest.jsonの[permission](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#host_%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3)をいじる必要があります。

## 拡張機能用のAPIが使えない

上記と同じ通り、[permission](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3)をいじる必要があります。

# 編集後記

Qiitaで調べてみると同じような記事が多かったのですが、例外が見えない件はパット見では見当たらなかったので一応投稿しておきます。
MとVとVMをこんな風に考えていた時期がありました(アンチパターン)



# はじめに
ぽえむ。
こんな風に考えていた時期が、私にありました系アンチパターン。
鵜呑みにするとひどい目に合う(一敗)。
Windows FormsのVBを例にとってる。

# MとVとVM

- M：Modelの事。ロジックとか。
- V：Viewの事。入出力系。I/Oをひとまとめにしたもの。
    - Input：モニターに映る入力項目とか、洗濯機にあるボタンとか、冷蔵庫の温度センサとか。人間の耳とか。
    - Output：モニターに映るGUIとかCUIとか。あとはLEDとかタイヤへのトルクとか。音とか。
- VM：Viewを持つModelの事。つまり特殊なModel。Viewの概念モデル。ヘッドレスビューと言ってもいいかも。

# 昔のMとVとVMのファイルの関係
昔はデザインなんか凝れなかったのでVMの`Form.vb`を、Vが奪う必要が無かった。
使う人も限られていたのでデザインよりシステム優先だった。
- V：`Form.resx`の事。
- VM：`Form.Designer.vb`と`Form.vb`の事(今だと違う。Vに取られた為)。
- M：上記以外の`Hoge.vb`とかの事。

# 今のMとVとVMのファイルの関係
PCのパワーに余裕が出てきた。ソフトもデザインがモノをいうようになった。
一般人もソフトウェア産業経済に入り、ソフトウェアの差別化もありデザイン優先になった。
- V：`Form.resx`と`Form.Designer.vb`と`Form.vb`の事。
- VM：`FormViewModel.vb`の事(名前はテキトー)。
- M：上記以外の`Hoge.vb`とかの事。

# 昔のMとVとVMの関係
もともとVMはVのモデルなので、VはVMの振る舞いに追従するように設計されていた。
VMがCloseと言えばVは消えるし、VMがHideと言えばVは非表示になる。
VMがShowと言えば表示されるし、Vから来たCloseイベントも、VMの意思によってそのままCloseさせたり、させなかったりしてきた。
デカい処理はMに投げ、結果を受け取ったVMはDesignerに反映することでVがその通りにふるまった。
VMの振る舞い、状態を、VがPCのモニターに表示していた。
ヘッドレスにテストするときも、単にVを表示しなければ良い為、Vが結合した状態でも何ら問題はなかった。

当たり前のようにVMはVを知っており、Vには処理的権限がなかった。

# 今のMとVとVMの関係
デザイナーが跋扈した。
デザイナーはまずVMの場所(`Form.Designer.vb`と`Form.vb`)を奪った。
プログラマがVMとして使うと、Vが動かないからだ。
VMの場所でVの制御をしない場合でも、デザイン確認(動作確認)のため、完全にVMからプログラマを追いやった。

かつてのVMを奪われたプログラマは、仕方なく別の場所にVM（`FormViewModel.vb`）を作ることにした。
Vとの結合時はbindすることで対応することにした。
もともと大半がヘッドレスなテストだった為、VMだけでもテストはできた。
ダミーのVを用意すればVありのテストもできた。

# もっと今のMとVとVMの関係
そのソフトの性質が許す限り、Mをサーバーに置くことで、Mを分離した。
様々なViewの基底となるものが増えてきた。
従来のOSと入出力機器はもちろん、タッチ操作がメインのスマホ、web、API、IOT機器。
これらViewが（データリンク層の）イーサネットと、TCP/IP(あとUDPとか)を通して、
当たり前のように高速かつ大容量の通信をするようになった。
ソフトをマルチプラットフォームに展開でMをAPI化することで、
ある程度再利用しつつ追従できるようになった。
~~そんなことしなくてもweb一本化が一番再利用性高いと思います。~~
~~なぜかクライアントのネイティブアプリへのこだわりが凄い。~~

サーバー側にViewの統一的なモデルを用意した。
これにクライアント側にあるVMを1:1でくっ付けるようにすることで、
クライアント側のVMは必要最低限なVへのコンバートだけで済むようになった。
VとVMは各プラットフォームに合わせて設計し、VMはMをAPIとして呼ぶようになった。

サーバーを通したマルチプラットフォーム上のソフトの開発では、
統一的なViewの登場により、MVVMが2層から3層になった。
V ← VM ← M(統合的ViewのModel+他のModel) 

# おわりに
これはアンチパターン。
このような情報はささっと捨てましょう。
鵜呑みにするとひどい目に合う。
heroku-18 stack でimagemagick buildpack が動かない

*9/17 時点の情報です

herokuでImageMagickを使おうと、このbuildpackをinstallしました。

https://github.com/ello/heroku-buildpack-imagemagick

```shell-session
$ heroku run buildpacks:add https://github.com/ello/heroku-buildpack-imagemagick.git -a アプリ名
```

ちゃんとinstallされてるか確かめたところ、どうやらうまくinstallできていないみたい

```sh
$ heroku run convert --version -a アプリ名
Running convert --version on ⬢ アプリ名... up, run.3737 (Hobby)
convert: error while loading shared libraries: libpng16.so.16: cannot open shared object file: No such file or directory
```

1ヶ月くらい前は普通に使えたのでなにか変更があったのかと思って調べてみたら、herokuのdefaultのstacksが`heroku-18`にupdateされていました。

https://devcenter.heroku.com/articles/stack

stackを一つ前野バージョン`heroku-16`に戻し、buildpackもinstallし直して解決しました。

```sh
# stackの設定
$ heroku stack:set heroku-16 -a アプリ名

# cache削除
$ heroku plugins:add https://github.com/heroku/heroku-repo.git -a アプリ名
$ heroku repo:purge_cache -a アプリ名
```

デプロイすると設定が反映され、その後再インストールされます。

```sh
$ heroku run convert --version -a アプリ名
Running convert --version on ⬢ アプリ名... up, run.5943 (Hobby)
Version: ImageMagick 6.9.5-10 Q16 x86_64 2018-09-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2016 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC OpenMP
Delegates (built-in): bzlib djvu fontconfig freetype jbig jng jpeg lcms lqr lzma openexr png tiff wmf x xml zlib
```
流行りのECSを使ってみてはまったところとか

#ECSとは
docker imageを使ってコンテナを起動する、AWSのサービスの一つ
よく、fargateとECSという区別のされ方がされているが、正しくはECSというサービスがあり、そのサービスを起動するコンテナの種類にEC2とfargateという2種類がある。
また、EC2ではWindowsかLinuxを選択することができる。
動的ポートマッピングができない
###Fargate起動イメージ
ネットワークのみを使用する
設定項目は
・クラスター
・VPC (オプション)
・サブネット (オプション)

###EC2起動イメージ
・EC2 WindowsまたはEC2 Linux
・ネットワーク
を使用する
設定項目は
・クラスター
・VPC
・サブネット
・Linux AMIまたはWindows AMIを持つAuto Scalingグループ

#だいたいの手順
1. ローカルでdocker imageを作成
2. そのイメージをrunしてローカルで動作確認
3. AWSコンソールにてECRのレポジトリ作成
4. docker imageの名前を先ほど作成したレポジトリ名に変更
5. docker imageをプッシュ
6. クラスタの作成（ここでタスクをサービスの作成を同時に行う）

#はまったところなど
###Fargateについて
・ECSの管理コンソール上で「クラスターの作成」（青いボタン）と「今すぐ始める」（グレーのボタン）があるが、「クラスターの作成」から始めるとVPCの設定でつまづく（VPCからネットワークに接続できるかどうかを確認する必要があるので面倒、初心者は「今すぐ始める」からやったほうがいい）
「今すぐ始める」からやれば設定項目めちゃくちゃ少ないので楽に管理できます。
###EC2 Linuxについて

```:docker-composeでのデプロイコマンド
$ ecs-cli compose service up
```
・EC2インスタンスをわざわざ設定しないといけないので面倒
・docker-composeを使用する際に、buildで作成して実行のようなことができないので使用するイメージをbuildでできないのでdockerhub等にアップロードしてimageで指定する必要あり
・docker-composeを使用する際にlink, depends_onが使えない

#まとめ
めちゃくちゃ便利なサービスなのに情報が少なくてもったいないなと思いました。
使用した感じですが、docker imageを使ったサービス管理がしたいならfargate、スケーリングやインスタンスの細かい設定など、設定項目をたくさんやりたいならEC2を使うのが良いかなと思います。
fargateを使う際はグレーのボタンからクラスタ作成するのが良いと思います。
細かいところなどはまた別記事に書きたいと思います。
pip3 install したらSSLエラーになった（MacOS環境)

# 概要
OpenStreetMapからネットワークデータを取得するためのPythonライブラリである「OSMnx」が必要となりました．そのため`pip3 -install`をMacOS上で実行したところ以下のようなエラーが生じました．

```
Could not fetch URL https://pypi.python.org/simple/osmnx/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645) - skipping
  Could not find a version that satisfies the requirement osmnx (from versions: )
No matching distribution found for osmnx
```
# 解決方法
## 結論
結論から言うと[「Macでpip install -U pipがSSLエラーになる(Lean Engineer)」](https://engineer.kasajei.com/entry/2018/07/28/pip_upgrade)より以下のコマンドを実行したところエラーが表示されなくなりました．

```
curl https://bootstrap.pypa.io/get-pip.py | python3
```

##理由（推測）
エラーコードの中に「There was a problem confirming the ssl certificate:」つまりSSL証明書の確認に問題があると記載されています．
SSL証明書が古く上記コマンドでpipをアップデートしたことにより新しくなったためエラーが出なくなったと考えられます．
CapybaraでPixelを指定してドラッグ&ドロップ

CapybaraにはElementに[drag_to](https://www.rubydoc.info/github/jnicklas/capybara/Capybara/Node/Element#drag_to-instance_method)というメソッドがあり簡単にドラッグ&ドロップできるのですが、これはドロップ先のElementを指定し、その真ん中にドロップします。

もう少し細かい制御をしたかったのですが、そういうメソッドはないっぽいです（詳しく読んでませんが[ISSUE](https://github.com/teamcapybara/capybara/issues/119)が立ってクローズされてるので実装しない方向で話がまとまってるようです）。

そこでSeleniumDriverのAPIに直接アクセスし実現してみました。

```rb
# sessionはCapybara::Session
driver = session.driver.browser

driver.action.drag_and_drop_by(
  # targetはCapybara::Node::Elementでドラッグするエレメント
  target.native,
  # toもCapybara::Node::Elementでドロップする対象
  to.native.location.x - target.native.location.x,
  to.native.location.y - target.native.location.y
).perform
```

`Capybara::Session.driver.browser`で`Selenium::WebDriver::[YouBrowser]::Driver`に、`Capybara::Node::Element.native`で`Selenium::WebDriver::Element`にアクセス可能です。

drag_and_drop_byはオフセットを指定してドラッグ&ドロップします。SeleniumWebDriverのメソッドは[SeleniumWebDriverのドキュメント](https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver.html)でどうぞ。
PHP 基本的なコードのメモ

##文字列の表示##

```
<?php
echo '文字列';
?>
```

##変数の表示##

```
<?php
echo $a;
?>
```

##文字列をテキストファイルに保存する##

```
<?php
file_put_contents("sample.txt", "文字列");
?>
```
※ファイルが存在しない場合は自動的に作成される。

##テキストファイルを読み込んで表示させる##

```
<?php
        //fopen でファイルを開く。"r"は読み込みモード。
        $fp = fopen("sample.txt", "r");

　　　　　//whileで行末までループ処理。
        while (!feof($fp)) { 

　　　　　　　//fgetでファイルを読み込み、変数に格納。
            $txt = fget($fp);

　　　　　　　//読み込んだ変数を出力。"<br />"で改行。
            echo $txt."<br />"; 
        }

　　　　　//fcloseでファイルを閉じる。
        fclose($fp);
?>
```
簡単に ページトップに移動するだけの Chrome 拡張機能を作る

#概要
何番煎じかってくらいですが「Chrome拡張機能を作ってみたいけどどうすれば」という方に
「拡張機能アイコンをクリックするとページトップに移動する」という簡単に作れる拡張機能を作ってみようという記事です。
初投稿ということもあり説明下手だと思いますがよろしくお願いしますm(_ _)m
※ショートカットキーで行けるだろというツッコミはなしでお願いします（）
![これを作ります](https://qiita-image-store.s3.amazonaws.com/0/231839/cfd0f0d6-4a33-8f82-7441-ab9e67a4477e.gif)

---

#準備
`page_top_moving`ディレクトリを作成し、その中に

- manifest.json
- contents.js
- background.js
- jquery.min.js
- jquery.easing.js

を作成しましょう。

##manifest.json
名の通り拡張機能を定義するためのファイルです。

```javascript:manifest.json
{
  "manifest_version": 2,
  "author": "souchan2000",
  "version": "1.0.0",
  "icons": {
    "32": "icon32.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "name": "Go to Page Top",
  "description": "ページトップに移動するだけ",
  "background": {
    "scripts": ["background.js"]
  },
  "browser_action": {
    "default_icon": "icon.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery.min.js", "jquery.easing.js", "contents.js"]
    }
  ]
}
```

- `manifest_version` : このファイルのバージョンです。必ず`2`にしましょう。
- `name` : 今回作る拡張機能の名前です。
- `version` : 拡張機能のバージョンです。
- `matches` : 動作対象となるURLを指定します。（今回は全てのページにて動作するように設定しています。）

その他の項目について詳しく知りたい方は
[Chrome 拡張機能のマニフェストファイルの書き方](https://qiita.com/mdstoy/items/9866544e37987337dc79) をご覧ください。

##background.js
バックグラウンドで常時実行しているスクリプトです。

```javascript:background.js
chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.tabs.sendMessage(tab.id, "Action");
});
```

上記のスクリプトは、拡張機能アイコンがクリックされたら`Action`をcontents.jsにsendします。

##jquery.min.js
今回はjQueryを利用するので、[jQuery公式ページ](http://jquery.com/download/)からダウンロードします。

##jquery.easing.js
こちらも同じくjQuery Easing Pulginを利用するので、[jQuery Easing Pulgin公式ページ](http://gsgd.co.uk/sandbox/jquery/easing/)からダウンロードします。

##content.js

```javascript:contents.js
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	if (request == "Action") {
		scrolling();
	}
});

function scrolling() {
  $(function() {
    $('html, body').scrollTop(500).stop().animate({
      scrollTop: 0
    }, 500, 'easeOutExpo');
  });
}
```

background.jsから`Action`を受け取った場合、scrolling関数が開始されるというものです。

---
#自分のChromeに拡張機能を追加してみよう

Chromeの点が3つあるアレ＞その他のツール＞拡張機能に行き、
![拡張機能ページ](https://qiita-image-store.s3.amazonaws.com/0/231839/921a902a-a64f-ef8f-92cd-2f4e94972a10.png)
デベロッパーモードをオンにしてから「パッケージ化されていない拡張機能を読み込む」を選択し、`page_top_moving`ディレクトリをアップロードすれば…
![やったぜ。](https://qiita-image-store.s3.amazonaws.com/0/231839/de96affb-5806-01da-fa2d-0b3c91f6efad.png)
ついに追加されました！！！！

Chrome再起動またはページをリロードして実際に動かしてみましょう！
[warning] Illegal offset type

# 概要

エラーTipsその１。

# エラー内容

配列またはオブジェクトをキーとして使用することはできません。 
これを行なうと、warning: Illegal offset type が発生します。

# 前提

1. PHPの配列に関するエラー
2. 配列のキーには「文字列」か「整数」しか指定できない

# よくある原因

foreach と for 文の勘違い


# 実際にあったミス

## なんか変なの配列のキーにつけちゃった→キーが配列扱い

```php:間違い１
// 間違い
$sample = array(
  ['test'] => 'test' // 配列扱い
);

// 本来
$sample = array(
  'test' => 'test'
);
```

これは単純にキーを配列に指定してしまっているというミスなので、大体の場合はキーの文字列「test」を囲んでいる「[」と「]」を取れば良い。

## 配列のキーに配列を指定してしまった→これも同じくキーが配列扱い

```php:間違い２
$data = array(
    array('foo') => 'bar'
);
```

これも間違い１と同様、キーを配列にしてしまっているミスなので、大体の場合はキーを文字列「foo」にしてあげれば良い。

## 配列のキーにオブジェクトを指定してしまった→キーがオブジェクト扱い

```php:間違い3
$this->tableToModel[$this->table] = $this->alias;
```

cakePHPとかでありそうな間違いで「$this->table」がオブジェクトとなる。
オブジェクトではなく、この場合だとテーブル名を取得して入れてあげれば良い。
LDAPクライアント＆NFSマウント

debian 系のディストリビューションで LDAP のクライアントをインストールし，NFS サーバからディレクトリをマウントする。

## LDAP クライアント

必要なパッケージをインストール:

```bash
$ sudo apt install nscd libnss-ldap libpam-ldap ldap-utils
```

インストール中に以下のようにウィザードが表示されるので設定を入れていく。

1. LDAP サーバの URI を入力 (ホスト名やIPアドレス，ポート番号など)。![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/85b401af-b806-cbae-1460-59c72bed1565.png)
2. LDAP search base を入力。![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/09d42979-6b27-40ad-978c-fd0329601a3a.png)
3. LDAP プロトコルバージョンを選択。![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/89145737-7723-2ea3-9841-dfa6472e405b.png)
4. ![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/5c236bfe-e56c-ed06-769a-51f67423f51a.png)
5. ![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/485db96e-791a-ce13-22f5-9eebb1b56b9a.png)
6. 撮り忘れ
7. 撮り忘れ
8. ![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/461bb762-4728-d937-3f7d-87d4cb0b9b78.png)
9. ![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/0565a86d-0292-d78b-16ae-1eaf3ae8a09a.png)
10. ![image.png](https://qiita-image-store.s3.amazonaws.com/0/59163/01ed811a-9c2f-c4a1-0dbb-a10652428f0e.png)

```bash
$ sudo nano /etc/nsswitch.conf
```

```diff:/etc/nsswitch.conf
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

- passwd:         compat
+ passwd:         compat ldap
- group:          compat
+ group:          compat ldap
- shadow:         compat
+ shadow:         compat ldap
gshadow:        files

hosts:          files mdns4_minimal [NOTFOUND=return] dns
networks:       files

protocols:      db files
services:       db files
ethers:         db files
rpc:            db files

netgroup:       nis
```

```bash
$ getent passwd
```

うまくいけば，ユーザ一覧が出てくる．

```bash
$ sudo nano /etc/pam.d/sshd
```

```diff:/etc/pam.d/sshd
+ session    required     pam_mkhomedir.so skel=/etc/skel/ umask=0022
```

```bash
$ sudo reboot
```

LDAPユーザでログイン→成功

## NFS マウント

```bash
$ sudo apt install nfs-common
$ sudo nano /etc/fstab
```

```diff:/etc/fstab
+ xxx.xxx.xxx.xxx:/volume/hoge /mnt nfs defaults 0 0
```

```bash
$ sudo mount -a
```

設定にミスがなければ，上手くマウントできるはずです．

以上！！！
pgAdmin4 v3.3 の 地図表示機能（ Geometry Viewer ）のコツ

# PostGISの空間情報がpgadmin4で表示可能に
[pgAdmin4 v3.3＋PostGISがすごい！](https://qiita.com/U_ikki/items/f64815da23dc3771ba18)　@U_ikki 様のエントリーでPgAdmin4による地図表示の紹介がありました。すごい進化です。

# 今回の結論！ 地図表示のコツ
 pgAdmin4 v3.3 では<b>geography型</b>か<b>geometry型かつSRID=4326</b>を指定しないと背景地図は表示されないよ！

## うまく表示でた場合
背景に地図と、SQLで実行した地物が青色で表示されています。
<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/014602ce-919b-06e7-4661-ddc3289ba472.png" width=400px />

## うまく表示できない場合
背景地図が無く、地物だけが表示されています。
<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/fcac5248-ebc2-683b-887e-ef6525d33b93.png" width=400px />

# 実験
何が背景地図が表示できて何が駄目なのか、とりあえず調べてみました。（もしかしてドキュメントに明記されているかもしれないけど。。。。）

## 結果

|SRID|型|地物表示|背景地図|総合|
|:-:|:-:|:-:|:-:|:-:|
|指定なし|<font color="red">geography</font>|○|○|○|
|指定なし|geometry|○|-|-|
|4326|geometry|○|○|○|
|-1|geometry|○|-|-|
|4612|geometry|○|-|-|
|4301|geometry|○|-|-|
|3857|geometry|○|-|-|

# まとめ
　今回の地図表示の機能はpgAdmin4にとって大きな一歩だと思います。PostGISのユーザとしてはSQLを書きながら空間形状の目視確認するということが必要なので、BIツールではなくエディタの進化として大変嬉しく思います。
Windows 10 で PATH 環境変数を設定する方法

Windows でプログラミングをするには PATH 環境変数を設定する必要がある場面が度々あります。
新人のプログラマからよく「××ができないんですが」という質問に「ああ、PATHが通ってないね」「それってどうやるんですか？」というやりとりがあるのですが、最近の Windows はやり方が変わっているので困ります。
かつての Windows ではシステムの詳細設定や、コントロールパネルから設定していましたが、~~Windows 10 のバージョンが上がるにつれて、仕様変更によりそれらの方法にワンタッチでアクセスすることが難しくなってきました。~~ 
現在の Windows 10 では、スタートメニューの検索窓から一発で開くことができます。

## 環境変数設定を開く
スタートメニューの検索窓に「環境変数を編集」と入力すると、ショートカットが一発で出てきます。
![環境変数を編集.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235904/9c2bc6a0-3795-44be-8059-c272bf56ee3a.png)

なお、「システム環境変数の編集」というショートカットもありますが、こちらは環境変数設定ダイアログを直接開くのではなく、「システムのプロパティ」ダイアログを開きますので、1手数多いです。また、管理者権限が必要です。

## PATH を編集する

ユーザー環境変数の一覧の中から ```PATH``` （小文字かもしれません）を選び、「編集」を押すと編集ダイアログが開きます。好きに編集してください。

ちなみに、Windows 10 では ```PATH``` 変数だけ特殊なダイアログが用意されており、以前の Windows に比べると飛躍的に編集しやすくなりました。



# ~~現状の方法をまとめます。~~ 以下は、他の方法です

## コントロールパネルを開く

コントロールパネルからアクセスする場合、「システムの詳細設定」から設定する方法と、「ユーザーアカウント」から設定する方法とがあります。
かつては「システムの詳細設定」から設定する方法がよく紹介されていましたが、この方法は管理者権限が必要であり、現在は「ユーザーアカウント」から設定する方法のほうがおすすめです。

### 方法1. スタートメニュー

- スタートメニューから W→「Windowsシステムツール」→「コントロールパネル」を選ぶ

なお、頻繁に使う人は「スタートにピン留めする」でピン留めしておくこともできます。

### 方法2. デスクトップアイコン

頻繁に使う人は、この方法がおすすめです。

- デスクトップを右クリックし、「個人用設定」を開く
- 「テーマ」の「デスクトップアイコンの設定」を開く
- 「コントロールパネル」にチェックを入れる

### 方法3. コマンド

- Windowsキー+Rキー を押して「ファイル名を指定して実行」アプレットを開く
- ```control``` と入力し、OKする

※ただし、コマンドを使うなら「ユーザーアカウント」画面を直接開いたほうが早い

## ユーザーアカウント設定を開く

### 方法1. コントロールパネルから

「ユーザーアカウント」アイコンを開く

### 方法2. コマンド

- Windowsキー+Rキー を押して「ファイル名を指定して実行」アプレットを開く
- ```control userpasswords``` と入力し、OKする

※ただし、コマンドを使うなら「環境変数」画面を直接開いたほうが早い

## 環境変数設定を開く

### 方法1. ユーザーアカウントから

左の列の一番下「環境変数の変更」を開く

### 方法2. コマンド

- Windowsキー+Rキー を押して「ファイル名を指定して実行」アプレットを開く
- ```rundll32 sysdm.cpl,EditEnvironmentVariables``` と入力し、OKする

※要するにこの方法が一番早いのですが、とても暗記できないので、応用を利かせるために他の方法も紹介しました
Go でレベル付きのログ出力に hashicorp/logutils を使ってみる

自分の作っているアプリで、レベル付きのログ出力をしたくなった。残念ながら、標準の `log` パッケージでは、レベルに対応していない。どのようにするべきか？

# 要件

* Debug モードの時のみ詳細をダンプするようにしたい。
* Debug モード以外の時は、余計な物を出して欲しくない
* コマンドラインアプリケーション

という至ってシンプルなもの。出来るだけ公式の仕組みを使いたい。今回は、HashiCorp のlogutils を使ってみた。

* [hashicorp / logutils](https://github.com/hashicorp/logutils)

こちらは、基本的な仕組みは`log` パッケージに乗っ取って最小の変更でレベルロギングを実現するというシンプルなもので、これでいい気がしてきた。しかも、[terraform でも使っている](https://github.com/hashicorp/terraform/blob/d4ac68423c4998279f33404db46809d27a5c2362/helper/logging/logging.go)ので安心感があります。

# 環境変数の取得

最初にログレベルを取得するために、環境変数を取得する。

```go
func Getenv(key string) string
```

* [func Getenv](https://golang.org/pkg/os/#Getenv)

これで一撃で環境変数が取れる

# logutils の仕様

`logutils` のトップページに従って、ロギングのセットアップを行う。とても簡単な仕組みで、`log.SetOutput` に対して、`io.Writer` である `logutils.LevelFilter` をセットしているだけだ。とてもシンプル。それらを渡してあげると、ログにフィルターがかかる。下記の例では、`ST_LOG` 環境変数に、`DEUBG`, `INFO`, `ERROR` をセットできるようになっている。

```go
const (
	EnvLog     = "ST_LOG"
	EnvLogFile = "ST_LOG_PATH"
)

func main() {
	filter := &logutils.LevelFilter{
		Levels:   []logutils.LogLevel{"DEBUG", "INFO", "ERROR"},
		MinLevel: logutils.LogLevel(os.Getenv(EnvLog)),
		Writer:   os.Stderr,
	}
	log.SetOutput(filter)
	log.Println("[DEBUG] Now debugging...")
	log.Println("[INFO] Echo useful information...")
	log.Println("[ERROR] Error happens!...")
	log.Println("Normal logging")
	log.Fatalln("[DEBUG] Fatail!")
}

```

環境変数で、`INFO` を設定した時の出力は次の通り。レベルが低いののみ出力される。

```
$ go run main.go
2018/09/17 19:17:40 [INFO] Echo useful information...
2018/09/17 19:17:40 [ERROR] Error happens!...
2018/09/17 19:17:40 Normal logging
exit status 1
```

`log.Fataln` でも有効になるようだ。環境変数に、`DEBUG` を設定して再度実行

``` 
$ go run main.go
2018/09/17 19:23:36 [DEBUG] Now debugging...
2018/09/17 19:23:36 [INFO] Echo useful information...
2018/09/17 19:23:36 [ERROR] Error happens!...
2018/09/17 19:23:36 Normal logging
2018/09/17 19:23:36 [DEBUG] Fatail!
exit status 1
```

これは簡単だ。先ほどの `LevelFilter` には、`Writer` という属性もあるので、こちらにファイルを設定するとファイルに書かれるようになるだろう。これは単純だけど、これで十分だ。レベルフィルターの実装はこちらから見れる。

* [LevelFilter](https://github.com/hashicorp/logutils/blob/master/level.go)

次から便利な `log` の関数について説明したい。

* [log.SetOutput](https://golang.org/pkg/log/#SetOutput)

## SetOutput

io.SetOutput はどのような関数かというと、めっちゃシンプル log の出力先を指定するためのもの。

```go 
func SetOutput(w io.Writer)
```

## SetPrefix

これはプレフィックスを付けれる。かっこ良くなるかな。

```go
log.SetPrefix("[Strikes] ")
```

を追加して実行。

```
$ go run main.go
[Strikes] 2018/09/17 19:29:29 [DEBUG] Now debugging...
[Strikes] 2018/09/17 19:29:29 [INFO] Echo useful information...
[Strikes] 2018/09/17 19:29:29 [ERROR] Error happens!...
[Strikes] 2018/09/17 19:29:29 Normal logging
[Strikes] 2018/09/17 19:29:29 [DEBUG] Fatail!
```

ん。ちょっとかっこ良くなった。

# まとめ

というわけで、`hashicorp/logutil` は今回の目的にぴったりでシンプル！最高！
テストコードを書くための基礎知識

# これは何？
本番のアプリケーションを開発していくにあたり、
テストコードがかけないと自分の書いたコードが本当に問題ないのか確認が大変。
そこで、テストコード周りの情報をこのQiitaに集めて行く。

# 概要
[伊藤先生の記事](https://qiita.com/jnchito/items/2a5d3e15761fd413657a)を読むことで概要を掴むことは問題なくできるかと思いますのでそちらを読んでください。

この記事で初心者ながらなるほどーと思ったのは二点。

- 「テストコードのテスト」が必要になるのは本末転倒。
    - そのため、DRY意識しすぎず1画面に収まるように簡潔に書く。
- 「テストコードがない → リファクタリングできない→ コードレビューしても意味がない」
    - 確かにって思いました。

他にもたくさんテストコードを書く上での参考になるチップスが入ってるので定期的に読みたいと思います。

# Minitest
Railsがデフォルトでサポートしているテストフレームワークです。

システムが計画通りに動作していることを実際に確認するのはアサーション（assert）となります。
※assertの意味は「断言する」なので、この条件では「○○と断言する」と宣言したテストを書くような感じです。

### ▼ テスト実行コマンド

`bundle exec rails test`
=> 全てのテストを一括実行（システムテスト以外）

`bundle exec rails test test/models/user.rb`
=> 特定のファイルのみテスト実行

`bundle exec rails test test/models/user.rb:6`
=> 特定のファイルの特定の行だけテスト実行

`bundle exec rails test test/models`
=> 特定のディレクトリ内のファイルを全てテスト実行

`bundle exec rails test -h`
=> テスト実行できるオプションのヘルプ

`bundle exec rails test:system`
=> システムテストの実行

### ▼ テストファイルの中身
| 名称 | 役割 |
|:--|:--|
| controllers  | コントローラ/ルーティング/ビュー用のテスト  |
| fixtures  | テストデータを編成する  |
| helpers  | ビューヘルパーのテスト  |
| integration  | コントローラ同士のやりとり用のテスト  |
| mailers  | メイラーのテスト  |
| models  | モデル用のテスト  |
| system  | UXに沿ったアプリのテストを行うシステムテスト  |
| application_system_test_case.rb  | システムテストのデフォルト設定  |
| test_helper.rb  | テスティングのデフォルト設定  |
| jobs | ジョブに関するテスト |



### ▼ テストデータベースについて
テストコマンドを実行するタイミングで、最新のスキームに合わせてマイグレーションされます。
また、テストデータベース内のデータに関してはフィクスチャでYAML形式で定義します。

### ▼ テストファイル作成
テスト用のコントローラーとモデルに関してはアプリケーション用のコントローラーとモデルに一対一で対応するため、
`rails g`で生成したタイミングで作成されます。

`bundle exec rails g system_test users`
=> システムテスト用のファイル作成コマンド

`bundle exec rails g integration_test user_flows`
=> 統合テスト用のファイル作成コマンド

### ▼ setup/teardownメソッド
フィクスチャからデータを取得する関数などはDRYにした方が便利。

```ruby:test/controllers/users_controller.rb
#各テストの実行前に呼ばれる
setup do
 @user = User(:one)
end

#各テストの実行後に呼ばれる
teardown do
 Rails.cache.clear
end
```

これ以上の内容は[こちらを参考](https://railsguides.jp/testing.html)にしてもらえるとよりわかると思います。

# RSpec
WIP
Webスクレイピングでデータ分析とインテリジェンスを向上する

「インターネットからのデータは使えますか？」という疑問がある人もいるかもしれません。今、インターネットが信じられないほどの情報を提供し、それがどれほど価値があるかを掘り下げることができることは間違いありません。これはWebデータのスクレイピングが出た原因です。自動コピペのプロセスであるWebデータのスクレイピングは、成長している分野であり、データ分析とインテリジェンスをサポートする強力な洞察力を提供することができます。

 
このブログでは、Webデータの収集によく出る活用例とデータマイニングツールについて説明します。さあ始めましょう。

 

#どのようWebスクレイピングを活用しますか？

ビッグデータが多くの分野で役に立つことを知っている人がいますが、Webスクレイピングをどのように活用できるかを分からない人もいます。ここでは、実際の例をいくつか紹介します。

 

##1. コンテンツ集約

ほとんどのメディアサイトでは、Web上の最新トレンド情報に継続的に把握し、ニュースを迅速に生成することが重要です。Webスクレイピングにより、人気のあるニュースポータルやソーシャルメディアを監視し、キーワードやトピックの傾向を把握して最新情報を取得することができます。Webスクレイピングの力を借りて、更新頻度を非常に上げられます。先日の記事にも[Webスクレイピングを活用して、コンテンツマーケティングを進める方法](https://qiita.com/Octoparse_Japan/items/1ee4d0b51a0c3d62569b)を紹介しました。興味がある方は是非ご覧ください。

 

##2. 競合他社の監視

オンラインスビジネスの競争が激化したため、Eコマースは、通常、競合他社のリアルタイムデータを入手し、競争戦略を微調整する必要があります。Webスクレイピングにより、競合他社のプロモーション活動や更新された製品情報にかかわらず、競合他社の活動を深く監視することができます。これらの情報をスクレイピングして、分析した上で、製品の詳細や価格を適当に修正することができます。

 

##3. 感情分析

ユーザーが作成したコンテンツ（UGC）は、感情分析プロジェクトの基本です。通常、このようなデータには、製品、サービス、音楽、映画、書籍、イベントまたはその他の消費者重視のサービスやイベントに関するレビュー、意見、苦情が含まれます。これらの情報はすべてWebクローラーを導入することで簡単に取得できます。

 

##4. 市場調査

ほぼすべての企業が市場調査を行います。市場調査を行うには、Webから製品情報、タグ、ソーシャルメディアのコメント、レビュー、ニュースなどさまざまなデータを入手する必要があります。従来のデータ取得方法を使うなら、特に時間がかかります。い今まで、Webデータのスクレイピングは、市場調査に使う膨大な量の関連データを収集する最も簡単な方法です。

 

##5. 機械学習

感情分析のように、利用可能なWebデータは機械学習の良い資料です。メタデータのフィールドや値から抽出したタグ付きのコンテンツは、自然言語処理のソースになるかもしれません。タグの統計とクラスタリングシステムは、カテゴリとタグ情報を用いて行うことができます。Webスクレイピングは、データのより効率的かつ正確に取得するのに役立ちます。

 

#Webスクレイピングを行う方法

Webからデータを抽出する最も良い方法は、データスクレイピングプロジェクトをDaaS企業に委託することです。DaaS企業は、データ抽出に必要な専門知識とクローリングシステムを持つため、ご要望のデータを完壁に取得できます。でもDaaS企業に委託するのはかなりお金がかかるので、予算が少ない会社にとっては多分難しいです。

中小企業の多くは、大企業のように多くの予算を使えるわけではないことがほとんどです。その予算が少ないまたは限られている場合、Webスクレイピングのは、自分でWebスクレイパーを構築することはいい方法です。WebスクレイパーのほとんどはPythonで書かれていて、データ収集のプロセスを簡単します。しかし、ほとんどの人にとってそれは容易ではありません。プログラミングの知識が必要だし、スクレイパーを構築するときには、色々な複雑のことを処理する必要があります。

 

実は、もうひとつのより便利な方法があります----Webスクレイピングツール使う！以前のブログにはたくさんのWebスクレイピングツールを紹介しました。例えば、「[デキる人は知っている！Webスクレイピング用のソフト30選](https://qiita.com/Octoparse_Japan/items/2f80077a1594c9bb01ec)」です。しかし、すべてのツールに長所と短所があり、完璧なツールはありませんので、自分の必要に応じて、適当なツールを選択します。非プログラマ向けに作成された[Octoparse](https://www.octoparse.jp/)とMozendaは、他のスクレイピングツールよりも使いやすいです。いくつかのチュートリアルを参考することで使えるようになります。

 

 

#まとめ

ビッグデータが重要視されている今、データ分析とインテリジェンスのニーズはビジネスやマーケティング分野で高まりを見せています。Webデータのスクレイピングなどのテクノロジーを活用して多様なデータから知見を引き出し、業務改善に活用しましょう！
【多分随時更新】クリーンアーキテクチャと事業の意識

# 概要

プログラミングはあくまで手段であるということを意識した方が良いよねという話。事業を成り立たせることの方が優先。もちろんクリーンアーキテクチャとすることは、未来に向けてかなり重要ではあるが、場合によっては事業のために諦めることもあるよ！という自戒。

# 対象読者

- クリーンアーキテクチャが神！となっている
- なんか思ったより実装に時間がかかりすぎていると感じている新卒〜２年目とか
- 今まで個人開発しかしていないし、それが事業にもなったことがない
- 長期インターンとかやってたけど、そのあたりあんまり意識したことのない自分

# そもそものお話

1. あなたがコードを書いている時間にも事業のお金は使われている。
2. ユーザが求めているものをまず提供することが大事。
3. クリーンアーキテクチャは結構だが、ユーザは早く機能とかUIが良くなってほしいと願っている。

# 先人に対する尊敬

1. コードが汚くても、それが事業として成り立っているのであれば、汚くてもそのコードを書いた人に尊敬を持つ。
2. ただ、事実として汚いので、改善はする。事業に影響がない範囲内における努力で。
3. 大事なのは早く失敗すること。文句を言っている時間で手は動かす。

# 放っておくというの選択肢もあるよ

1. 一つ直すと、全部直したくなってくるが、必要がある箇所のみ直すこと。
2. コードレビューの際に先輩にどうするのが良いのかを聞き、やることリストに積んでおく→これがFIXMEとかTODOとなっていると、他の人もわかりやすいので、コメントで残しておく。
各.gitignoreが持つ関心について

# 前置き

.gitignoreを正しく運用していますか？
プロジェクトの立ち上がり時にはきちんと考えられて作成をすると思いますが、開発が進んで行くと思いつきで対象リポジトリに存在する.gitignoreに要素を肉付けのように足して行く運用を良く目にする気がします。
当記事で.gitgnore毎が持つべき関心を考え、美しい状態とは何かを考えたいと思います。

# .gitignoreは複数あるという考え

一般的にはリポジトリ毎に作られるものと各環境毎に作る.gitignore_globalの二つを元に考えられていると思います。
この2つの.gitignoreで運用することは十分可能ですが、さらに細分化させることが可能だと考えています。

## 細分化した.gitignore

チームで開発している場合以下のように細分することができるかと思います。

- application.gitignore
- repository.gitignore
- team.gitignore
- global.gitignore

### それぞれが持つ関心

#### application.gitignore

リポジトリ内に複数のアプリケーションが作成される場合作られると考えています。
内容についてはそのアプリケーションで無視したい内容になります。
[github/gitignore](https://github.com/github/gitignore)の内容が一般的かと考えています。

#### repository.gitignore

リポジトリ内に一つのアプリケーションの場合はapplication.gitignoreの内容も足されます。
また、設定ファイルなども場合によってはここに追加されると思います。

#### team.gitignore

各メンバーに配布されるための共通.gitignoreになります。
チームの決まりとしてvscodeを利用する事が確定されているならこれに追加されるべきだと考えます。
ただし、この開発環境はリポジトリ毎に変わる場合ならそのリポジトリに収めるべきですし、逆に各個人に委ねている場合は個人でglobal.gitignoreとして管理するべきだと思います。

#### global.gitignore

各個人が管理するgitignoreです。チーム以下のスコープで確定されていない要素は個人で管理すると考えています。

# まとめ

現実的な話、運用するのは全てリポジトリの.gitginoreに書き足すのが楽で確実です。
ですが、抽象的な話でしたがこの記事をきっかけに美しい.gitignoreについて検討し運用が出来ることになれれば幸いです。
~~自分もこういった運用ができるようになりたい。~~
【Rails5/RSpec】OmniAuthの試験を自動化する

# やること
- RSpec実行時のGoogle認証をテストモードに設定
- スタブユーザーのデータを設定

## RSpec実行時のGoogle認証をテストモードに設定
rails_helper.rbに以下の設定を追加

```rb:spec/rails_helper.rb
OmniAuth.configure do |c|
  c.test_mode = true
end
```

## スタブユーザーのデータを設定
先ほどrails_helper.rbに追記したOmniAuth.configureに追加

```rb:spec/rails_helper.rb
OmniAuth.configure do |c|
  c.test_mode = true
  c.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
    provider: "google_oauth2",
    uid:      "111111111111111111111"
  })
end
```

# テストを書く
Google認証ボタンをクリックする動作を入れると勝手に設定したユーザーでログインしてくれます。

```erb:app/views/before_login.html.erb
<h1>Pages#before_login</h1>
<p>Find me in app/views/pages/before_login.html.erb</p>
<% unless user_signed_in? %>
  <%= link_to user_google_oauth2_omniauth_authorize_path do %>
    <%= image_tag "btn_google_signin_dark_normal_web.png", id: "google_signin_button" %>
  <% end %>
<% end %>
```

```rb:spec/features/login_spec.rb
require "rails_helper"

feature "login" do
  scenario "Google認証できること" do
    visit root_path
    find("#google_signin_button").click
    sleep 1
    expect(current_path).to eq auths_after_login_path
  end
end
```
認証処理完了前にパスのチェックが実行されてしまうようでFailureになってしまうのでfindとexpectの間にsleep 1を入れてます。

# Reference
- [Integration Testing · omniauth/omniauth Wiki · GitHub](https://github.com/omniauth/omniauth/wiki/Integration-Testing)
Re:VIEWで特定箇所だけtextlintを無効にする

Re:VIEWで特定の箇所だけtextlintを無効にしたかった。

```hoge.re
#@# textlint-disable
囲んだところが無効になる
#@# textlint-enable
```

https://efcl.info/2016/06/30/textlint7.0/ にある通りコメント記法を使えばよい。
Visual Studio2015 MySQL接続方法の忘備考

仕事にて、Visual Studio 2015環境でMySQLを使用する事になったので、忘備考として投稿。
また、以下方法はMVCテンプレートでEntityFrameworkを使用しての方法。
EntityFramework不使用な場合は後日別途記載予定
※下図画像はVisual Studio 2017のものなので、2015と少し異なるので注意

###【環境】
Visual Studio 2015 Community
MySQL
###【手順】
１．「MySQL Connector Net」、「MySQL for Visual Studio」をインストールする。
　　　◆MySQL Connector Net
　　　　バージョン：8.0,6.10,6.9,6.8
　　　　URL：https://dev.mysql.com/downloads/connector/net/6.10.html
　　　◆MySQL for Visual Studio
　　　　バージョン：2.0,1.2
　　　　URL：https://dev.mysql.com/downloads/windows/visualstudio/1.2.html
２．プロジェクトを作成（ここではテンプレートをMVCとする）
３．ソリューション エクスプローラーにある「参照」を右クリック
　　「NuGetパッケージの管理」を押下
４．NuGetパッケージマネージャーにて、「MySQL.Data」、「MySQL.Data.Entity」をインストール
　　※「MySQL.Data.Entity」をインストールすると「EntityFrameWork」もインストールされる？
![WS001146.JPG](https://qiita-image-store.s3.amazonaws.com/0/254650/88fba635-ccf7-177a-2530-663f7ae1c68e.jpeg)
５．ソリューションエクスプローラーから「追加」⇒「新しい項目」を選択
　　[Visual C#]の「ADO.NET Entity Data Model」を選択
![WS001147.JPG](https://qiita-image-store.s3.amazonaws.com/0/254650/d2503957-b345-4c2d-4a18-2a56f8bc0548.jpeg)
６．ウィザードが表示されるので、「データベースからEF Designer」を選択し、「次へ」ボタンを押下
７．「アプリケーションがデータベースへの接続に使用するデータ接続」項目で「新しい接続」ボタンを押下
![WS001149.JPG](https://qiita-image-store.s3.amazonaws.com/0/254650/29bae987-8c0d-5a32-4e79-929fa8e515cf.jpeg)
８．データソースは「MySQL Database」を選択し、「続行」ボタンを押下
![WS001150.JPG](https://qiita-image-store.s3.amazonaws.com/0/254650/eb6c86b0-bbd8-6b60-a45a-7d1fd73c1f70.jpeg)
９．接続プロパティが表示されるので、それぞれMySQLのDB情報を設定
　　Dtabase name以外を入力し終えたら「テスト接続」ボタンを押下し、正常に接続できているか確認を行う
　　正常に接続できていれば接続大将のDtabase nameを選択し、「OK」ボタンを押下
![WS001151.JPG](https://qiita-image-store.s3.amazonaws.com/0/254650/c5c52e46-f546-aaf2-39fa-829cc50ce076.jpeg)
１０．データ接続の選択画面に戻るので、「はい、重要情報を接続文字列に含めます。」と「接続設定に名前を付けてWeb.Configに保存」にチェックを入れ「次へ」ボタンを押下
１１．データベースオブジェクト選択画面にて、必要なテーブルやビューを選択し、「完了」ボタンを押下
VSCodeで仕事してわかったこと

いつの間にやらEclipseからVSCodeに乗り換えて4ヶ月が経っていたので、ちょっと思ったところを。

# 落ちないって素晴らしい
**当たり前だろ！！**って言われそうだけど、でもいいたい。「**落ちないのはほんとに素晴らしいぞ！！**」

ひょっとすると他の環境ではそうでもないのかもしれませんが、少なくとも私の現場で、私の開発機で、私の使い方（必要なプロジェクトを全部まとめて開いておく）をすると、最悪で日に6-7回落ちていました。なんだアレ。
そうでなくても昼頃には再起動が必要になります。だいたい重くなってきて、エディタ周りがまるごと固まっていたのです。~~Pleiadesでもないのにね~~

VSCodeに変えてから今まで、少なくともエディタ部分が落ちたことはありません (Javaの言語サーバが落ちたことは一度あったかな？) 。固まることは1度ありましたが、数秒で復帰してくれて安心したのは記憶に新しいことです。

VSCodeはエディタであり、エディタにIDEっぽい機能を山盛りにできる存在です。それ故か、周りが死んでも**エディタ部分は生き残ります**。
言葉を変えれば、**なにか死んでも保存して再起動するだけの余裕がある**のです。

# だいたいなんでも対応できる
主にJavaでしたが、Ruby、Python、HTML/CSS/JavaScript、Node.js、Shellといろいろ併用しています。

嬉しいことに、VSCodeはこれらの全てに対応できます。
……もちろん、対応できないほうが珍しいといえばそうなのですけどね。なにせ究極的にはテキストエディタとターミナルがあれば対応できないほうが珍しい。

しかし、地味に重要なのは……

# 統合ターミナル、強い
最初「いや別ウィンドウでいいだろ」と思ってましたが、これが予想以上に便利でした。ウィンドウ切り替えって意外とストレスになってたんだな、と思い知る次第です。

私個人はシングルディスプレイ派なので結局単一画面に大量のウィンドウで戦うのですが、マルチ派の方々は特に重宝することでしょう。
なにしろ、大窓で一つVSCodeを開き、もう一つの画面でブラウザを開いておけば、大画面を骨までしゃぶる勢いでコーディングしながらチケットを確認したり、チャットで相談したり、~~私はしませんが~~Twitterしたりできます~~しませんが~~。

もっとも、微妙に描画が遅い、という評は未だ良く聞きます (私は実感できませんが……) 。
Instantiate前のGameObjectへのAddComponentしてみる

## 概要
Instantiateする前のGameObject
(例えばResourcesフォルダ以下にあるPrefabをResources.Loadした状態)
にAddComponentしてみる

## やってみる
Resources以下に空のTest.prefabを配置し、以下のコードでやってみる

```csharp
using UnityEngine;

public class Hoge : MonoBehaviour
{
	void Start ()
	{
		var go = Resources.Load("Test") as GameObject;
		go.AddComponent<Fuga>();
	}
}
```

## 結果
元のプレハブにAddComponentされた
<img width="481" alt="スクリーンショット 2018-09-17 19.06.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/46278/decae575-81f3-dab1-99d8-93a423ede03c.png">
多分、やってはいけない

## 補足 - 2021/12/11
ここではRuntime上でAddComponentしているので、まあよろしくないと思いますが、
Editorコードとして書く分には有用な場合もあるので、必ずしもやってはいけない。ということも無い。
Go 1.11の「go get ~」でGo言語製のツールがインストールできなくなってた話

# 「go get」が使えない!

自分で作ったテキストの色付けなどを行うツール https://github.com/x-color/mkr をGitHubで公開した後、インストールのチェックをするために、いつも通り以下のコマンドを叩いた。

```bash
$ go get -u github.com/x-color/mkr
```

そしたら...

```
go: cannot find main module; see 'go help modules'
```

いつもならインストールが開始したはずなのに、エラーが帰ってきてしまった...

# 原因

エラーメッセージを見るとバージョン1.11から追加されてた「[Modules](https://github.com/golang/go/wiki/Modules)」関連の影響っぽい
ってことで、ドキュメントを軽く読んでみると

> Day-to-day adding, removing, upgrading, and downgrading of dependencies should be done using 'go get', which will automatically update the go.mod file.

https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies

「「go get」は、依存関係にあるパッケージの追加、削除、アップグレードやダウングレードを行う」って感じのことが書いてあるみたい。

「go get」の仕様が変わってたのか..確かに、開発中にパッケージの管理で使ってたな..と振り返りつつ、じゃあツールのインストールの手段はどうなってるんだと調査続行。

# 解決策

ドキュメント読むより、実際に有名なGo言語製のツールはどうしてるのか見たほうが早そうだと「[Hugo](https://github.com/gohugoio/hugo)」のインストール方法を読んでみることに。

そしたら、このような感じになっていた。

```bash
$ git clone https://github.com/gohugoio/hugo.git
$ cd hugo
$ go install
```

以前の「go get」が内部で行っていた`git clone`と`go install`を自分で行うようになっていた。

この方法をGo言語製の自作ツールのインストールで試してみると

```bash
$ git clone https://github.com/x-color/mkr.git
$ cd mkr
$ go install
```

無事にインストールすることができた。

# まとめ

Go言語のバージョン1.11で、Go言語製のツールをインストールする際には、

```bash
$ go get -u github.com/XXX/xxx
```

ではなく

```bash
$ git clone https://github.com/XXX/xxx
$ cd xxx
$ go install
```

でできる！