OmniAICreator/Qiita-1.07M huggingface dataset:
rbenvでMacのRubyのバージョンを切り替える

ローカルのRuby をバージョンアップする必要があったので備忘録です

# 0. 環境

- macOS Mojave 10.14.6

- Homebrew 2.1.15

# 1. 全体の流れ

macにデフォルトで入っている 2.3.7 から 2.4.1 に変更します 

1. Homebrew インストール (省きます)
2. Homebrew でrbenv インストール
3. rbenv で新しいruby をインストール
4. ruby のバージョンを切り替える

# 2. 使用するツール

## Homebrew

macOS用パッケージマネージャー

https://qiita.com/omega999/items/6f65217b81ad3fffe7e6

## rbenv

Ruby 用バージョン管理ツール

https://qiita.com/souichirou/items/d4196faa0df9e4bacf17


# 3. 実際にやってみる

Homebrewがインストールされているか確認

```
brew -v
Homebrew 2.1.15
Homebrew/homebrew-core (git revision 584e3; last commit 2019-10-17)
```

Homebrewを使用しrbenv をインストール, 確認

```
$ brew update
$ brew install rbenv ruby-build
$ brew upgrade rbenv
$ rbenv -v
1.1.2
```

rbenv を使用し新しいバージョンのRuby(今回は2.4.1) をインストール, globalでバージョン指定

```
$ rbenv install --list
.
$ rbenv install 2.4.1
.
$ rbenv global 2.4.1
.
```

Ruby バージョン確認

```
$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
```

バージョンが変わっていないので設定を確認, 修正します


```
$ which ruby
/usr/bin/ruby
```

rbenv を使いバージョンを切り替える為には```/Users/user_name/.rbenv/shims/ruby```じゃないとダメなので設定します

```
$ rbenv init
# Load rbenv automatically by appending
# the following to ~/.zshrc:

eval "$(rbenv init -)"
```

`eval "$(rbenv init -)"`  を使用しているシェルの設定ファイルに追記します

- bash > .bash_profile
- zsh > .zshrc

vimで設定ファイルを開きます(シェルはzshを使用しているので.zshrcを開きます)

bashを使用している場合は.bash_profileを開いてください

```
$ vim .zshrc
```

設定ファイルに下記を追記

```:.zshrc
# rbenv init
`eval "$(rbenv init -)"
```

保存した設定を反映

```
$ source ~/.zshrc
```

バージョンを確認

```
$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin18]
```

無事バージョンが切り替わりました

rbenv を使った一番シンプルな方法でバージョンアップしましたが、環境によってはエラーが出る場合があるかもしれません

rbenv を使用したバージョンアップは多くの情報がありますので他の方の記事も参考にしてみてください
yum updateで[Errono12] Timeoutのエラー

# やりたいこと
他の環境からインポートしたVMWare上のCentOS7で、yum updateを実行するとエラーになる為、解消したい。

# 経緯
開発環境を構築する（CentOS上でLaravelを動かす）にあたり、他の環境（VMware vSphereだったはず）からエクスポートされた仮想マシンを、開発PCのVMWarePlayerでインポートして調整していました。
その中でyum updateを実行したところ、以下のエラーが発生しました。

```bash
http://mirro.centos.org/centos/7/os/x87_64/repodata/repomd.xml: [Errno 12] Timeout on http://mirro.centos.org/centos/7/os/x87_64/repodata/repomd.xml: (28, 'Connection timed out after 30004 milliseconds')
他のミラーを試します
・・・（以降、同様のエラー）
```

# 環境
- VMWare WorkStation 15 Player
- ゲストOS：CentOS7（他端末からインポート）
- ホストOS：Windows10

# 対応
## 1.ipv6を無効化してみる => ダメでした※
　参考：https://wiki.centos.org/FAQ/CentOS6#head-d47139912868bcb9d754441ecb6a8a10d41781df

## 2.baseurlに、日本のリポジトリを設定 => ダメでした※
　参考：https://qiita.com/sksmnagisa/items/fb78f2cc4f5ca85a639e#タイムアウトを長くする

## 3.移行元のプロキシ設定があった！ => コメントアウト => 解消しました
　「/etc/yum.conf」に、移行元環境のプロキシ設定が残っていました。
　「proxy=」と「http_proxy=」の行をコメントアウトしたところ、エラーが解消できました。

```bash:/etc/yum.conf
# Proxy Setting(yum,wget)
#proxy=http://xxx.xxx.xxx.xxx
#http_proxy=http://xxx.xxx.xxx.xxx
```

※あくまでも今回のケースで解消されなかっただけです。とても参考になりましたし、解決のヒントを得られました。

# まとめ
yumのエラー対処法については多くの情報がありましたが、移行してきた環境だったからか、ズバリの情報が見つからなかったので、残しました。
[macOS]Zip解凍で「エラー22」が発生したらunzipを試してみて！

#macOSでZip解凍時以下のエラーが発生
環境：macOS Catalina バージョン10.15.1

<img width="380" alt="スクリーンショット 2019-11-14 05.26.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487744/45c8c2b6-06d2-d4ff-de9a-c8f46c397cb9.png">


# 解決：ターミナルコマンドunzipで解凍

ターミナルを開いたら　unzip 
Zipファイルをドラッグアンドドロップして　Enter
<img width="445" alt="スクリーンショット 2019-11-14 05.41.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487744/087f94e3-8998-0eab-ce05-66538404c2c1.png">

これで解凍できました。（2019年11月14日時点）

外部アプリなど入れたくない方はお試しあれ！!
Oracle 同一キーを削除して一意にしたい(正しいROWIDの使い方)

```:SQL
-- 準備
CREATE TABLE TABLE_NAME1
    (
    NUM1 NUMBER(6)
    )  ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(10) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(10) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(10) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(20) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(20) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(30) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(30) ;
INSERT INTO TABLE_NAME1(NUM1) VALUES(40) ;
COMMIT ;

-- テーブルの内容を確認する。
SELECT T1.NUM1
FROM TABLE_NAME1 T1
ORDER BY T1.NUM1 ;

         NUM1
-------------
           10
           10
           10
           20
           20
           30
           30
           40

8行が選択されました。
```
```:SQL
-- このデータで NUM1 について同じ値が複数行あるものについて1行だけ残して、重複するデータをDELETEするSQLの書き方。
DELETE FROM TABLE_NAME1
WHERE ROWID NOT IN
    (
    SELECT MIN(ROWID) FROM TABLE_NAME1 T1 GROUP BY T1.NUM1
               -----
    ) ; 

4行が削除されました。

COMMIT ;

-- もう一度、テーブルの内容を確認する。
SELECT T1.NUM1
FROM TABLE_NAME1 T1
ORDER BY T1.NUM1 ;

      NUM1
----------
        10
        20
        30
        40
```

時々未熟なプログラマーがROWIDをPRIMARY KEYに使っているのを見かけるが、UPDATEを実行して行移行(元のROWIDとは変わってしまう)が起きたり、
exp/imp or expdp/impdp で当然ROWIDが変わってしまい、破綻するのを何度みたことか。
JavaScriptのimport文を使ってみた

JavaScriptのimport文は、いままでHTMLで`<script>`タグを追加するなりしないと使えなかった外部のJavaScriptファイルを、JavaScriptファイル上で読み込むことができます。

# 注意点
注意点は以下

* `export`されたクラス・メソッドしか`import`することはできない
* `import`文を使うときは、HTMLの`<script>`タグに`type="module"`属性を付与する
* ローカル環境(`file://`なURL)では動作しない

## `export`されたクラス・メソッドしか`import`することはできない

インポートしたいJavaScriptのメソッドおよびクラスは、必ず`export`句で「そのクラス・メソッドがエクスポート対象である」ということを明示する必要があります。

例えば以下のように`A`クラスをインポートできるようにしたいときは…

```js:importable.js
export class A {
  constructor() {
    this.current = new B();
  }
}

class B {
}
```

`class A`の前に`export`と書いて、そのクラスがエクスポート対象であることを明示する必要があります。その中で使われているメソッドやクラスなどには`export`句をつける必要はありません。

上記のようなスクリプトは、以下のようにしてインポートできます。

```js:index.js
import {A} from './importable.js';

let a = new A();
```

## `import`文を使うときは、HTMLの`<script>`タグに`type="module"`属性を付与する

`import`文を使うときは、`import`文を使いたいJavaScriptファイルまたは、JavaScriptコードをHTMLから呼び出すときに、`<script type="module">`というように、`type="module"`属性を付与する必要があります。

```html:index.html
<!DOCTYPE html>
<html>
<body>
  <!-- ... -->
  <script src="index.js" type="module"></script>
</body>
</html>
```

という感じ。または

```html:index.html
<!DOCTYPE html>
<html>
<body>
  <!-- ... -->
  <script type="module">
  import {A} from './importable.js';

  let a = new A();
  </script>
</body>
</html>
```

こんな感じ。

## ローカル環境(`file://`なURL)では動作しない

こちらが軽くハマったのですが、`import`文はローカル環境に配置したHTML上では動作せず、「Cannot use import statement outside a module」というエラーが出ます。

ですので、オフライン環境で動作チェックをするときも、適当なサーバを立てて、そこからHTMLを表示する必要があります。

個人的に一番気楽なのは、PHPのビルトインサーバ機能

* [PHP: ビルトインウェブサーバー \- Manual](https://www.php.net/manual/ja/features.commandline.webserver.php)

とりあえずプロジェクトのフォルダでおもむろに`php -S 127.0.0.1:8080`などとすると、とりあえずそのフォルダをドキュメントルートとした簡易サーバが立ち上がるので、非常に便利です。PHPコードなんか一行も書いてないのですが。

なお、参考文献にもあるとおりですが、`import`文で呼び出されたモジュールおよび、`type="module"`属性を指定したスクリプトは、強制的にstrictモードになり、変数の宣言が強制となります。

うっかり変数宣言を忘れた変数などがあるとその時点でエラーになりますので、気をつけましょう。

# 参考文献

* [import \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import)
* [ES Modules（import/export）ことはじめ](https://sbfl.net/blog/2017/07/26/es-modules-basics/)
* [JavaScript \- JavaScript 別ファイルからクラスをインポートしたい｜teratail](https://teratail.com/questions/history-questions/216443)
* [JavaScript のスクリプトインポートを正しく使い分けようという話](https://nhiroki.jp/2018/09/07/javascript-import)
Node.jsでFirestoreにDate型を渡すとエラーになる

Firebaseのクラウドデータベースである[Cloud Firestore](https://firebase.google.com/docs/firestore?hl=ja)は、Timestamp形式での日付・時刻の保存に対応しており、その日付順にソートすることができます。

```typescript
    const db = firebase.firestore()
    const data = await db.collection('messages')
      .orderBy('date', 'asc')
      .limit(limit)
      .get()
      .then(querySnapshot => {
        return querySnapshot.docs.map(doc => doc.data())
      })
```

また、`startAt`や`endBefore`といった特定の期間で区切ることもできます。

```typescript
    const db = firebase.firestore()
    const startDate = new Date(`2019/01/01 00:00:00`)
    const endDate = new Date(`2020/01/01 00:00:00`)
    const data = await db.collection('messages')
      .orderBy('date', 'asc')
      .startAt(startDate)
      .endBefore(endDate)
      .limit(limit)
      .get()
      .then(querySnapshot => {
        return querySnapshot.docs.map(doc => doc.data())
      })
```

ところが、**上記のコードをNode.jsで動かすとエラーになります**。クライアントサイドで動かす分には問題ありません。

私はNuxt.jsを使っていて、`mounted`で呼び出す時は問題ないのに`asyncData`や`fetch`にすると突然エラーになったのでかなり困りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321625/4048c6ee-44d7-0f9a-6472-50978f605d7f.png)

このcustom Date objectが何なのかわからなかったのですが、とりあえずstartDateを出力してみると、

```console:chrome
{
  startDate: Mon Apr 01 2019 00:00:00 GMT+0900 (日本標準時)
}
```

```console:node.js
{
  startDate: 2019-03-31T15:00:00.000Z
}
```

表記が違う……？

Firestoreは前者の形なら正しく受け取ってくれますが、後者だとエラーになるようです。

唯一の救いは、両方に対応したTimestamp変換ツールがFirebaseのパッケージに含まれていること。

```typescript
    const startDate = firebase.firestore.Timestamp.fromDate(new Date(`2019/01/01 00:00:00`))
    const endDate = firebase.firestore.Timestamp.fromDate(new Date(`2020/01/01 00:00:00`))
```

これなら動きます。

上記のコンソール表示では3/31 15:00になっていましたが、これはタイムゾーンの変換時の違いなので、Timestampに変換するとどちらも全く同じ時刻として扱われ、Firestoreから取ってくるだけなら何の問題もありません。

Node.jsの時刻の形式について直接問題視するような記事をあまり見かけなかったので、ひょっとすると片方でのみエラーを返すFirestoreの実装がおかしいのかもしれませが、解決したので深く考えるのは止めました。
[mac] 新OS Catalina にアップデート後、Atomが突然強制終了する

## 現象

Catalina にアップデート後、 Atomが何度も強制終了する。（Atomのバージョンは`1.41.0`）
`フォルダ内を検索した時`や `ファイル名を変更した時` によく発生します。

## 解決策

Atomのissueを参考にしました。しかし、まだ具体的な解決には至っていないようです。
今回は参考になりそうな解決策をお伝えします。
https://github.com/atom/atom/issues/20034


## 手順

Atom > Install Shell Commands でターミナルからAtomのコマンドを叩けるようにする
<img width="212" alt="スクリーンショット 2019-11-14 2.11.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/901638fc-b4b5-4e6f-2de2-cee7f8db9ca4.png">

以下のメッセージを確認したらOK
<img width="420" alt="スクリーンショット 2019-11-14 2.11.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/178baa42-e2fd-9cbf-d8f9-41c635048f41.png">


ターミナルから一旦セーフモードで起動

```
atom --safe
```

その後、セーフモードを終了し、ノーマルモードで再起動した後パッケージを最新にする

<img width="487" alt="スクリーンショット 2019-11-14 2.27.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/c515690b-3d2c-1e46-8e76-28a5a6d970f0.png">

以下のコマンドでもパッケージを最新版にすることができます。

```
apm update
```

その後、さらにノーマルモードで再起動する。


## 追記

再度クラッシュが発生してしまいました。。。

そこで、githubのissueを拝見してみると、一部クラッシュが直ったとの報告があったので、その解決策も紹介します。

https://github.com/atom/atom/issues/20034#issuecomment-559058027

### com.github.atom のplistファイルを削除する

ターミナルで

```
cd ~/Library/Preferences/
```
またはfinderで com.github.atom のplistファイルを検索し、削除するというやり方です。下記の画面だと、両端の２ファイルが該当します。

まだ、自分の方では実証できていないので、一旦、desktopにこの２ファイルを移すことにしました。クラッシュが発生しない場合は、削除する予定です。

<img width="613" alt="スクリーンショット 2019-12-02 0.38.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/bfa381f0-4e86-fb48-f9ba-a9a97633b88e.png">

<img width="367" alt="スクリーンショット 2019-12-02 0.39.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142616/51229f80-5ed3-3c81-72a9-cbe90be61088.png">



## 参考
https://github.com/atom/atom/issues/20034
【初学者】「sudo」ってなんなの？と思ったのでちょっと調べてみた。 

#意味はわからないけど使ってるコマンドってありませんか？
いろんなエラーの解決法をググるなかで、コマンドをコピペすることは多いと思います。

僕はよく`sudo`というコマンドを意味もわからずコピペしていました。

今日`docker-compose-v`というコマンドを打った際に`Permission denied（≒実行する権限がないよ〜）`とターミナル先生に怒られてしまったことから、少しだけ調べてみたので記事に残します。

##sudoって？
有名なプログラマーである須藤さんが作ったコマンド
ではありません。



「su」は「スーパーユーザー（rootユーザー）」のことらしいです！！
**s**uper **u**ser → **su**　ですね。


ようはあらゆる権限を持ったユーザー。
コマンドを打つときは、「どのユーザーとして打つのか」って重要らしく
スーパーユーザーはその頂点に立ちし者。まさに**キング・オブ・ユーザー**だそうです。
~~僕的にはku=king userの方が好みです~~


じゃあ「**do**」はなに？ここはよく分かりません（誰か教えて）
(「Just **do** it !」 の doですかね・・・？)

`su`だけでもスーパーサイヤ人状態の力を発揮できるようですが、`exit`でノーマル状態に戻らないといけない（必要な時に必要な権限を取得すべきだそうですわ・・・）

`sudo`の場合はコマンド実行後、勝手にノーマル状態に戻ってくれます。
※他にもsudoはいろんな設定ができるそうですが、難しいから勘弁。


#Permission（＝許可）という単語がエラー文に入ってたら
まずはユーザーの権限を疑ってみるのが良いのかなと思いました。

実行権限を与える`chmod`コマンドもあり、そのあたりを調べれば解決できると思います。
`chmod`についてはまた別に記事を書こうかと思います。
#　
※ただその`chmod`で実行するコマンドもまた、`sudo`さんでなければ実行できないんですね〜！
いや〜すごいよ須藤さん！！
letsencrypt: cerbot-auto renew でバーチャルホスト環境の証明書更新が失敗するケースの対応例（再発）

備忘として記載しておきます。

[以前](https://qiita.com/tbtbt/items/8e7c7c6a9e26d7e9e482)こちらで `cert-bot renew` の失敗事例について書きましたが、今回再発してしまいました。ログを見ると同じエラーログが吐かれていて、それにより何回実行しても証明書の更新が完了できない。（`cert-bot` のバージョンは `0.40.1` です）

どうやら、前回引っかかった「confファイルをファイル名によって優先順位付け」するロジックが変更されている様子。。
前回同様、backendのconfが書き換えられてしまっていました。

いったん暫定的な対応として、バックエンド用のconfファイル名を以下のとおり変更。

- 旧：***subdomain.backend.conf***
- 新：backend.***subdomain***.conf

ファイルマッチの条件が変わり、フロント用の設定ファイル `subdomain.domain.conf` が設定ファイルとみなされるようになり、証明書が更新できました。
Mac OS Xアプリ開発でマイク音声入力の設定

#はじめに
 macOSアプリでマイクを使った音声入力の設定です。

#環境
Mac OS X 10.15.1
Xcode 11.1

#設定

## Xcodeのマイクアクセス許可
システム環境設定 -> セキュリティーとプライバシー -> プライバシーのXcodeにチェックします。

## App Sandboxの設定
Xcodeで作成しているmacOSアプリのTARGETS -> Signing & Capabilities -> App SandboxのAudio inputにチェックします。
占いを写経

コマンドプロンプト？初めて聞いたし
やり方も知らん。
pychamもやっとこさやのに黒い画面をどこから持ってきたらいいのか・・
そんなレベルで目標時間は大幅に超えたけどできた。

rangeで大吉から末吉までをランダムで表示してくれる。

https://aiacademy.jp/texts/show/?id=193

今までほんとちょっとずつ学んでる気はするけどもう講義はついてけない。
写経から学ぶことにした。
そしたら毎日が楽しくなった。
WindowsにTomcat8をインストールして簡単な動作確認まで

タイトル通りwindowsにtomcatをインストールして、webサーバーを起動してアクセスするところまで実施したいと思います。とっても簡単です。
動作環境など、今回使うのそれぞれのバージョンなどは以下です。

OS：windows 8 Pro
Tomcat version：8.5.47

#1. Tomcatをインストールする
まずは、tomcatをインストールします。tomcatはjavaのアプリケーションサーバーです。簡易なwebサーバーの機能も付いていて、無料で使えるので、javaのサーバーサイド開発にはとても便利です。

##1-1. tomcatをダウンロードする
まずは、tomcatをインストールするために公式サイトの以下ページへ遷移します。
https://tomcat.apache.org/download-80.cgi

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/940dcb78-c34e-2ab3-0671-100f8e998152.png)
サイトの下部にスクロールすると、たくさんリンクあります。どれがいいんだろう？となると思うので、パッケージ情報のREADMEを読んでみます（リンクは上記、画面キャプチャの上部にあります）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/b4d9bf92-9fb9-c907-4bee-f23e08e4b166.png)
読んでもまたよくわからなかったので、今回は一番簡易なTomcatのインストールということにして、「apache-tomcat-[version].zip or .tar.gz」にしようと思います。
※一番上にあったので、簡易なのかなと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/b59d5a4d-60d6-59ae-3521-4952fd3975fe.png)
では、上記赤枠のリンク"zip"をクリックします。すると、zipファイルがダウンロードされます。

##1-2. インストールしたzipを解凍する
zipファイルを右クリックして、「すべてを展開」を選択して解凍します。
※今回は、Cドライブ直下に展開しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/3f1e5bcd-3ff0-acef-7480-29882ec79514.png)

これで終わりです。意外と簡単ですね。

#2. Tomcatの起動
では、インストール完了したのでまずは簡易の動作確認をしてみます。

##2-1. Tomcat起動バッチの実行
Tomcatの起動もインストール同様にとても簡単です。先ほどインストールしたTomcatディレクトリの配下の`bin`ディレクトリに`startup.bat`があります。これがTomcat起動バッチです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/33fb3123-50e4-eba1-2c8e-ca8bea0074ea.png)
ダブルクリックしてみましょう。
一瞬黒いコマンドプロンプト窓が表示して消えました。こういうときは何が起きたかよくわからないので、ダブルクリックではなくコマンドプロンプトから実行するのが良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/255f2b15-ba35-72f4-fa2b-bbdda8f2e0ea.png)
むむ・・・Tomcatの実行には、`JAVA_HOME` or `JRE_HOME`のどちらかの環境変数の設定が必要のようです。今回は、`JAVA_HOME`を設定して再度実行してみます。
（環境変数の設定方法は割愛します。調べればすぐ出てきます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/15255f07-3ad1-f91f-aeb1-dbb83a988441.png)
なにやら標準出力にいい感じのログが出力されました。あと、もうひとつJavaの窓が開きました。
文字化けがすごいですが、一番下のログにTomat起動時のお決まりの`Server startup`の文言が出力されているのでどうやら成功のようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/749242e8-cde3-e163-1ee8-a925782fb7b9.png)

#3. Tomcatにアクセスする
では、インストールと起動も完了したようですのでブラウザでアクセスしてみましょう。
デフォルトでは、以下のURLでTomcatのTOPページにアクセスできます。
`http://localhost:8080/`

以下の画面が表示されれば、正常にTomcatが起動しているということです。お疲れ様でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148996/e77c7566-4508-b006-f9d2-c59df3d4c4be.png)

#4. おわりに
windowsでのTomcatインストールを簡単に確認してみました。これは簡易なインストール方法ですけどwindowsではインストーラも用意されているのでそっちのほうが優しくインストールできそうですね（必要な設定などは全部設定したりだとか、プラスαで何かインストールできたり）。

今回はインストールのみですが、別の機会にTomcatの機能なども確認していきたと思っています。
※ちなみにTomcatの停止は、`startup.bat`と同じディレクトリにある`shutdown.bat`を実行すればOKです
BigQueryへGCS上のCSVファイルをEmbulkで取り込む際のポイント

# 前提
- outputには、[embulk/embulk-output-bigquery](https://github.com/embulk/embulk-output-bigquery)を利用します。
    - ここに書いてあることはだいたい[README](https://github.com/embulk/embulk-output-bigquery/blob/master/README.md)に書いています。
- 取り込み先はパーティショニングテーブル(`timePartitioning:DAY`)
- データ取り込みは日時で行い、日付パーティショニングするものとします。
- embulk 0.9.17でテストした。

# サンプル(.yml.liquid)

- input部分については、本記事では触れません

```yaml
in:
  type: gcs
  project: foobar_project
  bucket: foobar_bucket
  path_prefix: /path/to/{{ env.EXECUTE_DATE }}/{{ env.LOGNAME }}.csv.gz
  auth_method: compute_engine
  application_name: foobar_app
  decoders:
    - {type: gzip}
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    skip_header_lines: 1
    stop_on_invalid_record: true

out:
  type: bigquery
  project: foobar_project
  mode: delete_in_advance
  auth_method: compute_engine
  location: asia-northeast1
  auto_create_table: true
  time_partitioning:
    type: 'DAY'
    require_partition_filter: true
  dataset: foobar_dataset
  table: foobar_table${{ env.EXECUTE_DATE }}
  compression: GZIP
  source_format: CSV
  schema_update_options: ['ALLOW_FIELD_ADDITION']
  stop_on_invalid_record: true
  columns:
    - {name: c0, type: string}
    - {name: c1, type: long}
    - {name: c2, type: string}
```

# Output部分の解説

- mode
    - （追記ではなく）冪等を実現するためには、modeは `replace` `replace_backup` `delete_in_advance` などがあります。テンポラリテーブルを利用している、 `replace` は早いのですが、勝手にカラム追加してほしいので、 `delete_in_advance` を使っています（後述）。
- schema_update_options
    -  BigQueryのJobパラメータに `schemaUpdateOptions` というのがあり、side effectとして、カラムの追加をしてくれます（ `ALLOW_FIELD_ADDITION` は NULLABLEのカラムを追加します。ほか詳細は[公式ドキュメント](https://cloud.google.com/bigquery/docs/reference/rest/v2/Job)へ）
    -  `schemaUpdateOptions` は残念ながらCopy Jobでは使えないので、 テンポラリテーブルをcopyする `mode: replace` では使えず、 `mode: delete_in_advance` にしています。
    -  このサンプルで、元ファイル(input)にカラムが増えた場合は、outputの `columns:` に、カラムを追記すれば、BigQuery側で別途スキーマ追加の作業なしに、Embulkでのデータ取り込み時にカラム追加してくれます。
- stop_on_invalid_record
    - invalidなレコード（typeが違うとか）の場合に、該当レコードをskipさせずに処理全体を止めるパラメータです（デフォルトはfalseでskipしてしまう）
    - データの不整合の原因になるので、あえて明示的にtrueにしています。

こんな感じでやってます。
Windows10にcurlあるじゃん！という話

#昨日
昨日、curl、wgetそしてInvoke-WebRequestについてというタイトルで記事を書きました。
https://qiita.com/tatsuki1112/items/dec473f93ca1bda239fb

そこで、windows内でcurlはInvoke-WebRequestのaliasの一つであり、本来のcurlとはだいぶ異なるものであると書きました。
しかし、よく調べるとWindows10にはcurlそのものが実装されているというのです!!!!

#やってみた
PowerShellにおいては、curlはInvoke-WebRequestのaliasの一つであり、単にcurlコマンドをPowerShell上でたたいても、Invoke-WebRequestが実行されるのみです。ではPowerShellでcurlを実行するにはどうしたらよいのでしょうか、方法は以下の通りです。
今日取得するのは最高裁判所から、マクリーン事件の判例pdfです。

http://www.courts.go.jp/app/hanrei_jp/detail2?id=53255

http://www.courts.go.jp/app/files/hanrei_jp/255/053255_hanrei.pdf

```PowerShell
>cmd
Microsoft Windows [Version 10.0.18362.418]
(c) 2019 Microsoft Corporation. All rights reserved.
>curl http://www.courts.go.jp/app/files/hanrei_jp/255/053255_hanrei.pdf
```

☝こちらはコマンドプロンプトをPowershell上で実行する方法

```PowerShell
>cmd /c curl http://www.courts.go.jp/app/files/hanrei_jp/255/053255_hanrei.pdf -O
```

☝こちらはコマンドで実行し、PowerShellに戻るというオプションです、/kにすると、PowerShellに戻りません。

```PowerShell
>curl.exe http://www.courts.go.jp/app/files/hanrei_jp/255/053255_hanrei.pdf -O
```

☝こちらはC:\Windows\System32にある、curl.exeを直接呼び出しています。

どれも無事にpdfファイルをダウンロードできました、オプションもcurlと同様のものが利用できるようです。

```PowerShell
>curl.exe http://www.courts.go.jp/app/files/hanrei_jp/255/053255_hanrei.pdf -o $env:USERPROFILE\Downloads\maclean_hanrei.pdf
```

__curl(本物)使えるじゃん!!!!__


#まとめ
windowsでcurlコマンドが使えることがわかりました。調べてみるとver1803から標準で使えるようになったようです。しかし、先にPowerShellのInvoke-WebRequestにaliasとしてcurlが割り当てられてしまったがために、なんとなく使いにくい現状になってしまっています。また、curlはオプションを指定しない場合htmlが返ってくるのですが、``chcp 65001``で文字エンコードをUTF-8にしたとしても文字化けしてまともに使えたものではありません。この辺もまだまだ発展途上な感じがありますね。

##追記
この記事は基本的にはWindows10に標準搭載されているPowerShellを基準に記述しています。しかし、最新版かつクロスプラットフォーム化したPowerShell coreではInvoke-WebRequestのaliasとしてのcurlやwgetは廃止されているようです。
java初級編 3

##インクリメントとデクリメント

プログラムの=は代入なので、自己代入ができます。
僕は（右辺を左辺に代入する。）と覚えてます！


```
int x = 5;
x = x + 1;
//xは6になる

```


++はインクリメント演算子と言います。変数の値に1を追加して代入する命令です。
x++;

```
x = + 1;
//どっちも同じ、　xに1追加される

--はデクリメントといい、1引きます。

```

##真理値
booleanと言う型があります。
booleanは、true(真)またはfalse(偽)を入れられます
。
真理値とも言います。

本当の事ならtrue　嘘ならfalseと覚えましょう。
あるいは、スイッチがオンならtrue,オフならfalse

```
boolean a = true;
```

##比較演算子

比較演算子は左辺と右辺を比較して、booleanを返します。

```
==　 //等しい(数学の=に近いのはコレ)
!=  //等しくない 
>   //左が右より大きい
<　 //左が右未満
>=  //左が右以上
<=  //左が右以下
```

##条件分岐のif

渡された式がtrueかfalseかでどちらを実行するか分岐させられます。
if(条件式){条件がtrueの時実行される処理}

elseを使うと、falseの時に実行される処理をかけます。
if（条件式）{条件がtrueの時}else{条件がfalseの時}

elseifを使うと、falseの時にさらに別な条件をつけられます。
if(条件1){条件1がtrueの時}elseif(条件2){条件1がfalseで条件2がtrueの時}else{条件1も2もfalseの時}

##論理演算子

論理演算子を使う事で複数の条件を組み合わせる事ができる

!(NOT)否定
　例　aがtrueの時、　!aはfalse

&&(AND) 左辺かつ右辺がtrue(両方同じの場合)
　例　(a==5 && b==3) aが5、かつbが3の時true

|| (OR)左辺か右辺がtrue(どちらかがtureならok)
 例 (a<5 || b>=3) aが5未満か、　bが3以上の時true

かっこがない場合NOT AND OR の順に計算

##for文

for文を使うと繰り返しができます。

```
for(int i = 0; i < 5; i++) {
System.out.println(i);
}
```

```
System.out.println(0);
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
```

両方とも同じです。
for(薫太に使う変数; 繰り返す条件; １回終わったらどうするか)
波カッコの中が繰り返されます。
カウンタの変数は中で使う事ができます。

##for文の入れ子

for文の中にfor文を入れる事もできます。

```
for (int i = 0; i < 5; i++) {
 for (int j = 0; j < 5; i++) {
  //中が5回繰り返されて
}
   //ここにきたら外が１回終わり
}
```

カウンタは同じにしないように注意！　（この例だとiとjになります。）

##九九を表示してみよう！

1,2,3,4,5,6,7,8,9,
2,4,6,8,10,12,14,16
,,,続く

と九九の表を出すプログラムを書いてみよう！

```
public class hello {
	public static void main(String[] args) {
		for (int i = 1; i < 10; i++) {
			String a = "";
			for (int j = 1; j < 10; j++) {
				a += i * j + ",";
			}
			System.out.println(a);
		}
		}
	}
```

```
1,2,3,4,5,6,7,8,9,
2,4,6,8,10,12,14,16,18,
3,6,9,12,15,18,21,24,27,
4,8,12,16,20,24,28,32,36,
5,10,15,20,25,30,35,40,45,
6,12,18,24,30,36,42,48,54,
7,14,21,28,35,42,49,56,63,
8,16,24,32,40,48,56,64,72,
9,18,27,36,45,54,63,72,81,
```

って感じですね^^

他にもやり方はあると思うので自分にあった方法で♪

##他の繰り返し

while(条件）{}

```
while (x < y) {
//xがy未満の限りずっと繰り返される
}

```

最初から条件がfalseなら一度も実行されない

do{}while(条件)
条件がfalseでもとりあえず一回は実行される


#宿題！

##じゃんけんを作ってみよう　

グーが1 ちょきが2 パーが3 とする
1人目が出す手の数字をキーボード入力する
2人目が出す手の数字をキーボード入力する
どちらが勝ったか、あいこかを画面に表示する

プログラムを書いてみよう！
AWS Well-Architected 5本の柱を要約する（運用上の優秀性）

不明点もまだありますが、5本の柱ごとに自分なりの解釈を書いていきたいと思います。
今回は運用上の優秀性についてです。

～～～は原文引用

# 運用上の優秀性とは
～～～ビジネス価値を実現するためのシステムを実行してモニタリングし、それらをサポートするプロセスと手順を継続的に改善する機能が含まれています。～～～

運用とは完成したシステムやサービスを稼働させるために必要な日々の業務のこと。
次の2つの作業に大別される。
　定型業務：バックアップ、監視、バッチ処理など
　非定型業務：システムの増強、プログラムリリース、障害対応など

運用の優秀性の柱は運用を効率的にする（非定型業務も含め自動化する）ことと
運用手順などを継続的に改善する旨が記載されている。

## 設計の原則
クラウドにおける運用上の優秀性には、6 つの設計の原則があります。
・運用をコード化する
　⇒手作業ではミスをする可能性がある。スクリプト化などを行うことで手動作業を無くしていく。

・ドキュメントに注釈を付ける　
　⇒自動的に注釈が付くという運用が可能なのか。具体的な方法が不明。

・頻繁に、小さく、可逆的な変更を行う
　⇒小さいリリースの方が切り戻し手順が単純になり、障害時の原因調査も容易になる。
　　小さいリリースを行うためには多数のリリースが必要になるので、
　　リリースの自動化が必須になる。

・運用手順を頻繁に見直す
　⇒定期的に見直す運用ができているかどうか。
　　ゲームデーで運用手順がすべて有効か確認する。

・発生しうる障害を予想する
　⇒障害の事前排除や影響軽減を行う。
　　ゲームデーで障害シナリオを仕込む。
　　　　
・運用上の失敗を改善に役立てる
　⇒PDCA回せているか。

## ベストプラクティス
準備、運用、進化に分けて対応方針を記載している。

### 準備
～～～システムや変更が本番環境に移行する準備ができており、運用によりサポートされることを検証するメカニズムを構築します。～～～

本番運用前の運用設計フェーズに関する記載。運用テストまで行うことが重要。
安全に運用試験を行い、結果をモニタリングできているかを確認する。

・関連するAWSサービス
　AWS Config および AWS Config ルール
　AWS CloudFormation、Amazon CloudWatch、AWS CloudTrail、VPC Flow Logs

### 運用
～～～期待される成果を定義して、どのように成果が測定されるかを決定し、正しく運用できているかどうかを判断するために使われるシステムと運用に関するメトリクスを特定します～～～

適切なモニタリングが行われ、効率的な対処が行えることが理想。

・関連するAWSサービス
　Amazon CloudWatch、AWS X-Ray、AWS CloudTrail、VPC Flow Logs

### 進化
～～～ビジネスの状況、ビジネス上の優先事項、顧客のニーズなど、あらゆる事柄が常に変化し続けています。～～～

コストとメリットを考慮し優先順位付けして、運用改善する。

・関連するAWSサービス
　Amazon Elasticsearch Service
　AWS TrustedAdvisor、AWS Inspector

## レビューシート実践

運用　項番５：運用中に発生するイベント(障害など)をどのように管理していますか？
☐ ビジネスインパクトにもとづいて、運用イベントの優先順位をつけている
　⇒お客様に言ってしまったからということが要因でビジネスインパクトが低くても優先度が上がることがある
☐ イベント、インシデント、問題に対応するためのプロセスがある
　⇒ITIL準拠で運用しているが形骸化している。
☐ 発生するアラートに対して対応者と対応手順が定められている
　⇒大体定められているが無駄なアラートが多すぎる。対応手順が陳腐化している
☐ 有事の際の意思決定者が決まっている
　⇒決まっている。
☐ エスカレーションのプロセスが定義されている
　⇒担当者の頭の中にはあるがドキュメント化されていない
☐ サービスに影響がある際には、顧客に知らせる仕組みがある（電子メール、SMS、Push通知など）
　⇒ある。が不要なアラートが飛んでしまうこともある。
☐ ダッシュボードによる状態確認が可能である(社内チーム、責任者、顧客などに対して)
　⇒
☐ 問題の根本的な原因を特定・分析し対応するRCA(Root Cause Analysis, 根本原因解析)プロセスがある

## 参考ドキュメント
〇AWS Well-Architected 
(英語 July 2019)
https://d1.awsstatic.com/whitepapers/architecture/AWS_Well-Architected_Framework.pdf
　
(日本語 201806) AWS_Well-Architected_Framework_2018
https://d1.awsstatic.com/International/ja_JP/Whitepapers/AWS_Well-Architected_Framework_2018_JA_final.pdf

(日本語 201907)
https://d1.awsstatic.com/whitepapers/ja_JP/architecture/AWS_Well-Architected_Framework.pdf?sc_icampaign=aware_well_architected_jp_wa_framework&sc_ichannel=ha&sc_icontent=awssm-3366&sc_iplace=content&trk=awssm-3366_aware_well_architected_jp_wa_framework


〇Well-Architected_review_sheet
https://d1.awsstatic.com/webinars/jp/pdf/services/Well-Architected%E3%83%92%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%B7%E3%83%BC%E3%83%88%E6%97%A5%E6%9C%AC%E8%AA%9E%E7%89%88.77c25d2afd0a69894be16b95aae6a423011f5a1f.xlsx
java初級

##画面に入力する命令

今回はScannerを使います。この行を１行目に書きます
import java.util.Scanner;

mainの中に準備をします。
Scanner sc = new Scanner(System.in);

入力を受け取りたいところで受け取って変数に代入します。
int x = sc.nextInt(); //整数を取りたい場合
String s = sc.next(); //文字列を取りたい場合
プロトコル内の関数で、引数は〇〇プロトコルに準拠したクラスなら何でもいい、の実装方法

タイトルがわかりづらいですね、すみません。
あるプロトコル（例：Animalプロトコル）に準拠したクラスを大量に作っていたとします（例：犬、猫、猿、象、シマウマ）。そして別のプロトコル（例：Humanプロトコル）を定義している時に、
「それらのクラスのどれでもいいから、さっきのプロトコルに準拠したクラスを引数に持つ関数（例：飼う）を作りたい」
と思ったとします。この実装に少し手間取ったので、備忘録的に残します。

# 実装
まずはAnimalプロトコルと、それに準拠したクラスを大量に定義します。プロトコルにAnyObjectの継承をつけることで、Animalプロトコルはクラスにしか準拠できないようにしています。

```swift
protocol Animal: AnyObject { }

class Dog: Animal { }
class Cat: Animal { }
class Monkey: Animal { }
class Elephant: Animal { }
class Zebra: Animal { }

```

そしてHumanプロトコルを定義します。プロトコル内で、飼う（keep）メソッドを実装しています。

```swift
protocol Human: AnyObject {
    associatedtype AnyAnimal: Animal
    func keep(_ animal: AnyAnimal)
}

```

プロトコル内でassociatedtypeを定義しています。これは、そのプロトコル内でのみ使えるクラスを定義しているイメージです。今は「Animalプロトコルに準拠していれば」何のクラスでも良い、と条件があるので、AnyAnimalにはAnimalプロトコルを準拠させています。そしてメソッドの引数には、AnyAnimalを指定すればOKです。

# 使用例

上のプロトコルの使い方を、以下に示します。

```swift
class DogLover: Human {
    typealias AnyAnimal = Dog
    func keep(_ animal: AnyAnimal) {
        print("I keep a " + String(describing: type(of: animal)))
    }
}

class CatLover: Human {
    typealias AnyAnimal = Cat
    func keep(_ animal: AnyAnimal) {
        print("I keep a " + String(describing: type(of: animal)))
    }
}

```

Humanプロトコルに準拠したクラスを定義するとき、その中でtypealiasを定義する必要があります。これは、Humanプロトコル内で使っていたassociatedtypeのクラスは〇〇である、というのを宣言するイメージです。
上の例では、犬好きな人クラスと猫好きな人クラスを定義しました。それぞれ、犬好きな人クラスは中身に犬を飼うメソッドが、猫好きな人クラスは中身に猫を飼うメソッドが実装されています。

実際にインスタンスを用いて使うと、

```swift

let sampleDog = Dog()
let sampleCat = Cat()

let taro = DogLover()
taro.keep(sampleDog) // I keep a Dog
taro.keep(sampleCat) // エラー

let hanako = CatLover()
hanako.keep(sampleDog) // エラー
hanako.keep(sampleCat) // I keep a Cat

```
のように、それぞれ同じプロトコルに準拠したクラスでありながら、別々のクラスを引数にもつ関数が定義できていることがわかります。

ちなみに、

```swift

class Fish { }

class FishLover: Human {
    typealias AnyAnimal = Fish // エラー
    func keep(_ animal: AnyAnimal) {
        print("I keep a " + String(describing: type(of: animal)))
    }
}

```
のように、typealiasでAnimalプロトコルに準拠していないクラスを入れようとするとエラーになります。これは上でも説明したように、associatedtypeでAnyAnimalをAnimalプロトコルに準拠するように定義したからですね。

# まとめ
正直、associatedtypeというものを知らなかったので色々時間がかかりましたが、associatedtypeで調べると記事はいろいろ出てきますね。次からはassociatedtypeという名前さえ覚えておけばなんとかなりそうです笑

# 追記(2019/11/14)
記事投稿後の関連記事に並んでるものを読みながら思ったのですが、ジェネリクスを使うともっと便利に書けましたね。

```swift
class AnimalLover<T: Animal>: Human {
    typealias AnyAnimal = T
    func keep(_ animal: AnyAnimal) {
        print("I keep a " + String(describing: type(of: animal)))
    }
}

let taro = AnimalLover<Dog>()
taro.keep(sampleDog) // I keep a Dog
taro.keep(sampleCat) // エラー

```

引数のクラスに関係なくメソッドがすべて共通の場合は、ジェネリクスを使ったほうが楽でした。
補数の役割と計算機

#1.　補数とは

「補数（complement）」には、「基数の補数」と「減基数の補数」がある。

基数の補数とは、「元の数」と「補数」を足した場合に桁上がりが発生する数のうち「最小」の数のこと。
減基数の補数とは、「元の数」と「補数」を足すと桁上がりが発生しない数のうち、「最大」の数のこと。

十進法においては、基数の補数は「10の補数」、減基数の補数は「9の補数」
二進法においては、基数の補数は「2の補数」、減基数の補数は「1の補数」
となる。

コンピュータが負の数を保持する際に「2の補数」を用いることが有名。

>参考
>https://proengineer.internous.co.jp/content/columnfeature/6254#section102
>https://qiita.com/satellitesat/items/340de8a946ddd2bac24e


#2.　なぜ補数が必要なのか
**補数を使うと、引き算を足し算(加算回路)で行えるようになるから**

補数を使うと引き算を加算用の回路で行うことができ、減算用の回路が不要になる。
計算機は、回路が多くなればなるほど構造が複雑になるため、回路を減らすことにメリットがある。
歯車式の計算機から現代のコンピュータにいたるまで、計算機に補数が利用されるのはそのためである。


#3.　具体例
###3.1.　パスカリーヌ
#####3.1.1.　最古の機械式計算機
17世紀初頭、フランスの数学者でもあり哲学者のブレーズ・パスカルが構想・設計・製作した計算機。徴税官であった父親の作業を軽減するために16歳のときに考案し製作したという。

歯車によって構成されたこの機械式計算機は、**9の補数**を用いることで、加算と減算を一つの機構で実現している。
パスカリーヌは現存する最古の機械式計算機である。

#####3.1.2.　パスカリーヌが応用した補数の原理
数値Aの9の補数(**CP(A)**と記載する)を定式化すると以下になる。

$$CP(A)=10^n-1-A$$

上記の式を応用して、数値Aから数値Bを引いた値の9補数(**CP(A-B)**)を考えると以下のように表せる。
$$CP(A-B)=10^n-1-(A-B)$$

この式は以下のように整理できる。

```math
\begin{align}
CP(A-B) &= 10^n-1-(A-B)\\
&= 10^n-1-A+B\\
&= CP(A)+B
\end{align}
```

つまり、数値Aから数値Bを引いた値の9の補数(**CP(A-B)**)は、数値Aの9の補数に数値Bを足すことで求めることができる。
数値Aから数値Bを引いた値の9の補数がわかれば、数値Aから数値Bを引いた値もわかる。

#####3.1.3.　パスカリーヌへの補数入力
パスカリーヌでは減算を行う際、利用者自身が引かれる数（上記では数値A）の9の補数を入力しなければならなかった。
つまり、数値A-数値Bを行う場合は、利用者は数値Aではなく、数値Aの9の補数を入力する。
そうすることで、上記の式で表される「CP(A)+B」を実現している。(数値Bはそのまま入力)

計算される結果も9の補数(上記の式でいうCP(A-B))であったが、求めたい値(A-B)への変換はパスカリーヌに表示された値で把握できた。

>参考
>https://en.wikipedia.org/wiki/Pascal%27s_calculator
>https://www.wizforest.com/gear/pascal/pascal2.html


###3.2.ノイマン型コンピュータ
#####3.2.1.　2の補数である負の値
コンピュータの父とも呼ばれるジョン・フォン・ノイマンは「First Draft of a Report on the EDVAC」(1945年)でノイマン型コンピュータを提唱する。その中で、コンピュータ内部の負の値は、**2の補数**で保持することとしている。
この考え方は現代のコンピュータにも引き継がれており、今でも負の値は**2の補数**で保持されている。

参考
>http://www.yamamo10.jp/yamamoto/lecture/2005/3E/3rd/html/node3.html

当時のコンピュータは、構成する部品数の多さから、構築、保守・メンテナンスに多大な労力を要することが問題であった。
そのため、減算を加算回路でおこなうことで構造を単純化し構成部品の削減を目指した。
学習記録＃8

#今日やったこと

- progate：RubyⅤの終わりまで
- paiza：スキルチェック入門編１
- paiza：スキルチェック

#####ひとこと
スキルチェック標準入力でちょっと癖があるけど知らないメソッドとかの勉強になる上に楽しい～～！Cランク問題も解いてみたけど意外になんとかなったのでちょっとずつ触っていくようにします。早くオリジナル組めるように頑張ろ～～！！

#####読んだものピックアップ

- [Ruby　標準入力から値を受け取る方法](https://qiita.com/Hayate_0807/items/2e9705091b181a104621)
- [Rubyのmap &:to_iとはなんなのか
](http://a-records.info/ruby-map-ampersand-colon-to_i/)
- [Ruby リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/doc/index.html)


##
nuxt-childでlayoutの量産を防ぐ

# はじめに

この度、`nuxt-child`というコンポーネントの存在を知り、戦慄しました。

> [API: <nuxt-child> コンポーネント - NuxtJS](https://ja.nuxtjs.org/api/components-nuxt-child/)

これまで、ページカテゴリの数だけレイアウトファイルを量産し、似通った初期化処理を何度も書いてしまっていました。
**が、それは本来、レイアウトファイルで行うべきことではなかったのです**。

この記事では`nuxt-child`コンポーネントの使い方をご紹介します。

# Nested Routes

Nuxtにはネストされたルート（Nested Routes）という機能が存在します。
これは、ページパスと同名のページコンポーネントをレイアウト相当として動作させる事ができる機能です。

> [ネストされたルート (ルーティング - NuxtJS)](https://ja.nuxtjs.org/guide/routing/#%E3%83%8D%E3%82%B9%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%83%AB%E3%83%BC%E3%83%88)

たとえば、以下のようなページ構成にするとします。

```
.
└── pages/
    ├── product/
    │   ├── index.vue
    │   ├── list.vue
    │   └── _id.vue
    └── product.vue
```

有効になるルートは`/product`、`/product/list`、`/product/_id`の３つです。

このとき、`pages/product.vue`に記述した内容は、`pages/product/`以下のすべてのページコンポーネントで有効になります。
つまり、`pages/product.vue`が`pages/product/`以下のページのレイアウトとして機能するようになります。

また、`pages/product.vue`には実際のページを表示させる領域に`nuxt-child`コンポーネントを配置する必要があります。

```html
<!-- /pages/product.vue -->
<template>
  <div class="page-container">
    <TheHeader class="header">
      <div class="contents">
        <TheBreadcrumbs />
        <!-- ここにページの内容が入る -->
        <nuxt-child />
      </div>
    </TheHeader>
  </div>
</template>
```

このようにすれば、`/pages/product/`以下のページで共通したヘッダーとパンくずリストを表示することができます。
同様に、マイページや注文関連のページもそれぞれ異なるレイアウトで表示することができます。

そして、レイアウトファイルはグローバルスタイルやレイアウトの定義のみとなり、量産を防ぐことができます。

# おわりに

Nuxtはディレクトリ階層ベースのルーティングシステムのため、かなりURL定義が重要になります。
Nested Routesもカテゴリごとにディレクトリ分けされて初めて機能します。

カテゴリごとにディレクトリ分けされていないようなケースではあまり有効ではありません。
そのときは諦めてレイアウトファイルを量産するなどしてください。

それ以外に良い方法があれば教えてほしい...。
UnityListの紹介



## UnityListとは...?
https://unitylist.com/
ソースコード版 Unity AssetStoreみたいなイメージでしょうか？
Editor拡張、設計、シェーダーコードなど様々なものが見れますのでぜひご活用ください。



`↓このようなトップページになっています`
![unitylist_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396277/4356c055-cd29-c87f-3930-0593a25ca46f.png)
[MaterialPropertyDrawer] [Unity] ShaderPropertyAttributeを自作した

CustomMaterialEditorを各シェーダーごとに作成するのは大変なので
簡単なデザインをできるようにいろいろと作ってみました。

# ShaderPropertyAttributeとは
シェーダーのプロパティに属性を付与できる機能のことです
マテリアルのインスペクタでの表示を変えることができます。
例：[Header(Hoge)], [NoScaleOffset]など

以下の記事で公式で用意されているものが紹介されています。
[【Unity】シェーダプロパティアトリビュートまとめ](https://qiita.com/luckin/items/96f0ce9e1ac86f9b51fc)
[【Unity】ShaderLabのプロパティ属性まとめ](https://qiita.com/r-ngtm/items/7ec3e3a9dfcc752cd02c)

# ShaderPropertyAttributeを自作する
この属性ですが, MaterialPropertyDrawerを継承することで自作できます。
[公式リファレンス](https://docs.unity3d.com/ja/current/ScriptReference/MaterialPropertyDrawer.html)に実装例が載っています

また、私が作成したプログラムもgistで公開しているので参考にどうぞ
https://gist.github.com/gatosyocora/9f506612a27a02e28e0be60d09535580

コード例です。

```csharp:SampleAttribute1.cs
internal class SingleLineTexDrawer : MaterialPropertyDrawer
{
    public SingleLineTexDrawer() { }

    public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
    {
        editor.TexturePropertySingleLine(label, prop);
    }
}
```

これはTexture2Dを1行で表示するようにするAttributeです。
こんな感じになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/37f30c34-1068-9023-750a-efbe06f05875.png)

このAttributeでは単にTexture2Dのプロパティの表示を
[MaterialEditor.TexturePropertySingleLine()](https://docs.unity3d.com/ja/2017.4/ScriptReference/MaterialEditor.html)で変えているだけです。

ここで注意する点は

* MaterialPropertyDrawerを継承する
* OnGUIをOverrideする
* クラス名を○○Drawerにする
* ファイル名とクラス名は一致していなくても良い
* Editorフォルダ以下に入れる

このattributeはシェーダーコードではこのように書きます
作成したクラスのクラス名からDrawerを除外した部分を記入することになります。

```hlsl:sample1.shaderの一部
Properties
{
    [SingleLineTex]
    _TestTex ("TestTex", 2D) = "while" {}
}
```

もう一例をあげます

```csharp:SampleAttribute2.cs
internal class LineDecorator : MaterialPropertyDrawer
{
    private float spaceSize;

    public LineDecorator()
    {
        spaceSize = 0;
    }

    public LineDecorator(float spaceSize)
    {
        this.spaceSize = spaceSize;
    }

    public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor)
    {
        GUILayout.Space(spaceSize);
        GUILayout.Box(string.Empty, GUILayout.ExpandWidth(true), GUILayout.Height(1));
        GUILayout.Space(spaceSize);
    }
}
```

これは区切り線を入れるAttributeでこんな感じの表示になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/979fd16e-29ea-6422-e2ee-4319c975899c.png)

区切り線の上下に空白を入れるようにしており、その高さを自分で設定できるようにしています。
シェーダーコードにはこのように書きます

```hlsl:sample2.shaderの一部
Properties
{
    [Line(10)]
    _Color ("Color", Color) = (1, 1, 1, 1)
}
```
ここで指定した10がLineDecorator(float spaceSize)の引数として入力されます。

## ShaderPropertyAttributeの種類
ShaderPropertyAttributeですが、実は2種類あります。

### Drawer
プロパティの表示自体に影響を与えるもの
プロパティにつき1つしかつけることができない
例: [HideInInspector] [Toggle] [Enum] [NoScaleOffset]
上記の例だとSingleLineTexDrawer

### Decorator
マテリアルのインスペクターに影響を与えるもの
プロパティにつきいくつでも設定できる
例: [Space] [Header]
上記の例だとLineDecorator

Drawerはプロパティの表示自体を変えるが、
Decoratorは余白やタイトルなどの装飾をつけるときに使います。

これらはクラス名でどちらの種類かが区別されているようです。
Attributeによって適切なほうを使うのが良いです。
また、内部処理的に各プロパティごとに
すべてのDecoratorのOnGUIの実行後にDrawerのOnGUIを実行しているようです。
[route] resourcesで書くとpathやURIは何になる？？


便利なresourcesだけどpath名やURI忘れちゃうのでメモ。
` Rails 5.1.7` です。

# resourcesを単数で使うとき
例えば

```ruby
resource :profile
```
とするとpathやURIは以下の通り。

![ 2019-11-14 1.03.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532695/07f23d6a-f53f-d239-745c-adac27065db2.png)


# resourcesを複数で使うとき
```ruby
resources :users
```
と複数形にするとpathやURIは以下の通り。

![ 2019-11-14 0.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532695/684f1f35-234f-99ea-cf4a-1522180a88ff.png)

# resourcesをネストして使うとき
```ruby
resources :users do
  resources:posts
end
```

とするとpathやURIは以下の通り。

![ 2019-11-14 0.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532695/c461a4b7-7c0e-313c-1910-2ef079351d21.png)

以上です！間違っていたらぜひ教えていただけると嬉しいです！
resouces以外にもscopeなどの書き方もあるので、状況に合ったものを使えるようになりたいです！
SalesForceの監査項目の値の設定に関する話

SalesForceには、各オブジェクトに「作成者」、「作成日」、「最終更新日」、「最終更新者」という監査項目が存在します。
これらの項目は、基本的には任意の値を設定することはできないのですが、実は組織の設定を変更することで作成時のみ任意の値を設定することができます。

#デフォルトの組織の設定時の動作確認
まずは組織で監査項目の設定を許可していない場合の動作を確認してみます。

###標準のページレイアウト上
<img width="934" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/0e62040c-eb9e-e4dd-8f06-50a8dc6aa69e.png">

標準のページレイアウト上では編集ができません。（鉛筆マークが出ていない）

###匿名ブロックから実行
<img width="576" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/63207a87-6bb2-afb6-8560-5d4e5d5f9103.png">

<img width="188" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/c1ced85d-e516-e217-6d7e-aa4a787054f7.png">

匿名ブロックから画像のように作成者を設定する処理を実行すると、エラーとなります。

###Apexクラス・Apexトリガー
<img width="913" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/179b8964-386a-2040-ca66-f67751c4b2bd.png">
<img width="913" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/fb3d5627-0e63-9c3b-da8b-d013dbcfd5e3.png">

クラスもトリガーもコンパイルエラーとなり、保存できません。

#設定の変更
監査項目を設定できるように、組織の設定を変更しましょう。
[設定] > [ユーザインターフェース] と進むと、[設定セクション]に
「「レコードの作成時に監査項目を設定」および「無効な所有者のレコードを更新」ユーザ権限を有効化 」というチェックボックスがあります。
こちらにチェックをつけると、監査項目に値を設定できます。
<img width="913" alt="6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/105d84ab-e1b9-3358-7b73-b32b7017fcc3.png">

#設定変更後の動作確認
設定の変更後も実は、ページレイアウト上から編集はできません。
匿名ブロックからの実行もエラーとなります。
これはユーザ（プロファイル）に監査項目の設定権限がないためです。
また、監査項目はレコード作成時のみ設定でき、作成後編集は出来ないためです。

ただし、先ほどのApexクラスとApexトリガーは、
コンパイルエラーとならずに保存できます。
また、その保存したApexクラスのメソッドを匿名ブロックから実行すると、
監査項目が設定できます。

<img width="388" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/5e8c5037-2712-3b21-2fcf-cfcbe8ac789d.png">

<img width="939" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/a809539f-878d-00d2-72b1-97bfef6a2ed9.png">

#まとめ
普通は値をいじれない監査項目を、組織のユーザインターフェース設定を変更することで、監査項目に任意の値を設定することが出来ました。
注意点としては
・レコード作成時のみ値を設定できる
・権限のないユーザは設定できない
・権限のないユーザでも、Apexクラス内のメソッドを呼び出す形で、匿名ブロックから任意の値を設定できる
・Apexトリガーも同様の動作となる

という点です。
監査項目は出来ればいじらない方がいいみたいですが、どうしても任意の値を設定したい要件があった際に役立てていただければ幸いです。

また、ここまでは調べればいくらか情報が出てきますが、
トリガーのbeforeとafterでどう違う動作となるのか、どういう要件でこのような処理を行う必要があるかなどについて、また投稿したいと思います。
Windows proxy環境下で Visual Staudio Codo の Remote Development で WSLに接続しようとした時エラーが出た話

# 目的

- proxy環境下でVisual Staudio Codo の Remote Development で WSLに接続したところエラーがでて接続できなかった時の筆者の解決方を書く。

# 解決法

1. 下記コマンドを実行して設定ファイルを開く。

    ```
    $ sudo vi /etc/apt/apt.conf
    ```
1. 最終行に下記の内容を追記する。

    ```
    Acquire::http::proxy "httpのプロキシアドレス";
    Acquire::https::proxy "httpsのプロキシアドレス";
    ```

1. 下記コマンドを実行してwget用の設定ファイルを開く

    ```
    sudo vi /etc/wgetrc
    ```

1. 最終行に下記の内容を追記する。

    ```
    https_proxy = プロキシアドレス
    http_proxy = プロキシアドレス
    ftp_proxy = プロキシアドレス
    use_proxy = on
    ```

1. 再度接続を試みたところ正常にRemote DevelopmentでWSLに接続することができた。
kaliパワーオフするたびに初期化する問題についての対処方

#kaliパワーオフするたび初期化する問題

###結論：boot menuでLive systemで起動していた。正しくは、Start installer。

めちゃくちゃ初歩的な問題すぎて、どこにも情報がなかったので恥を忍んで書きます。
駆け出しエンジニアの方の力になれれば幸いです。


VMware fusionをインストールし、kaliのパッケージファイルも入れいざ起動！
boot menuでとりあえず一番上のLive systemを選択！

<img width="960" alt="スクリーンショット 2019-11-14 0.30.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532552/ee9c2cd8-5db2-e938-537c-1e3a982dcaaa.png">


...てしてました。

Live systemはどうやら、ハードドライブにインストールしなくてもブートできるオペレーティングシステムみたい。

正しくは、Start installerして、初期設定して（これは他の誰かが画像付きで書いてくれてる）下記の画像の赤枠をクリックして
<img width="1017" alt="スクリーンショット 2019-11-14 0.41.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532552/47e2c66e-2b59-eafe-597b-1f22ad69b515.png">

起動ディスクを選んで
<img width="626" alt="スクリーンショット 2019-11-14 0.44.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532552/df50c7fb-2ff4-9704-81ba-0573b70a5053.png">

ハードディスクを選んで再起動で完了！
<img width="632" alt="スクリーンショット 2019-11-14 0.41.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532552/c30ac570-7e8b-6ad1-dfcf-ec0b16c39aa4.png">
graphql.schemaを分割

# お題
GraphQLを初めて１ヶ月。そろそろ少しずつアウトプットしていく。
今回は、プチ情報。
GraphQLでは schema ファイルに Query と Mutation を定義していく。
１人で開発している時は問題ないのだけど、複数人で開発していると同じ schema ファイルを修正するので、しょっちゅう競合する。
なので、（大抵は機能ごとに担当がわかれるので）機能ごとに schema ファイルをわける。

# 対象読者
複数人でのGraphQLを用いた開発を現場で始めて間もない方。

# 前提
- GraphQL自体の説明は無し
- gqlgen自体の説明も無し

※今回、バックエンドは Golang を使っており、GraphQLのサーバーサイド実装には gqlgen というライブラリを用いている。

# 実践
想定事例として、何かしらの「商品（Item）」の登録・参照と「ユーザー（User）」の登録・参照をGraphQLで表現する。

## schema ファイル分割前

プロダクションレベルでの検討はしていないけど、以下のような感じ。

```graphql:[graphql.schema]
schema {
    query: Query
    mutation: Mutation
}

type Query {
    item(id: ID!): Item
    user(id: ID!): User
}

type Mutation {
    createItem(input: ItemInput!): ID!
    createUser(input: UserInput!): ID!
}

type Item {
    id: ID!
    name: String!
}

input ItemInput {
    name: String!
}

type User {
    id: ID!
    name: String!
}

input UserInput {
    name: String!
}
```

これを gqlgen で golang のサーバーサイドソースを自動生成して、Playgroundで動作確認してみたのが↓
（ `resolver.go` は適宜修正している。）

![screenshot-localhost-8080-2019.11.14-00-22-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/457e37f0-276d-0dbe-92d6-6a86d3facaa6.png)
![screenshot-localhost-8080-2019.11.14-00-22-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/337bbf88-d9fd-1c85-3f96-384d52c10509.png)
![screenshot-localhost-8080-2019.11.14-00-22-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/208bbb86-6027-d14f-2168-1c65d586db5e.png)
![screenshot-localhost-8080-2019.11.14-00-23-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180599/3bad6a9c-4842-08fc-860d-11a40a15d480.png)

## schema ファイル分割後

### graphql.schema

Item と User に関する Query と Mutation を別ファイルに移動。
ただし、ベースとなる graphql.schema にも何かしら定義が必要になるため、Query の方は node 、Mutation の方は noop と適当なダミー定義を行う。
これらは、少なくとも現状は使わないので、gqlgen によって自動生成される resolver.go の中身は修正しない。

```graphql:[graphql.schema]
schema {
    query: Query
    mutation: Mutation
}

type Query {
    node(id: ID!): String!
}

type Mutation {
    noop(input: NoopInput): NoopPayload
}

input NoopInput {
    clientMutationId: String
}

type NoopPayload {
    clientMutationId: String
}
```

### item.graphql と user.graphql

肝は、 `extend` というキーワード。

```graphql:[item.graphql]
extend type Query {
    item(id: ID!): Item
}

extend type Mutation {
    createItem(input: ItemInput!): ID!
}

type Item {
    id: ID!
    name: String!
}

input ItemInput {
    name: String!
}
```

```graphql:[user.graphql]
extend type Query {
    user(id: ID!): User
}

extend type Mutation {
    createUser(input: UserInput!): ID!
}

type User {
    id: ID!
    name: String!
}

input UserInput {
    name: String!
}
```

# まとめ
これで、gqlgen によって自動生成されたソースは Item と User に関する部分に限って、
動作確認結果も含め、「schema ファイル分割前」と同じ内容・結果になる。

一応、今回の成果物は下記。
https://github.com/sky0621/study-gqlgen/tree/0cef7df53bee43e41e58258a9399d80cf7d2e7bd/try00

以上。
[Android] タッチの座標を確認する

タッチの座標をお手軽に確認する方法の紹介。
`input tap`するときの座標を確認するときに便利。

<img width="300" alt="Screenshot_1573656099_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37714/f25e647e-e8d7-e336-0c65-5e640c02eb34.png">

開発者オプションの"Pointer location"機能を有効にすることで、
画面上部にタッチイベントの詳細が表示される。

タッチ数・座標・測度・強さ・大きさおよび、タッチの軌跡が確認できる。

<img width="600" alt="Screenshot_1573656163.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37714/34637aa5-b7a4-a6a3-b962-36570deaef0c.png">


"Pointer Location"機能は、adbでも制御できる。

```shell
# Pointer Locationを有効化
adb shell settings put system pointer_location 1

# Pointer Locationを無効化
adb shell settings put system pointer_location 0
```
ネットワークの用語

## 概要

ネットワークに関連する用語の説明です．
ど忘れした時にぱっと確認する用なので，正確性より直感的な分かりやすさに重点を置いています．

## IPアドレス(Internet Protocol Address)

ネットワーク上の機器を識別するために割り当てられている数．
インターネット上での住所のような役割を担う．
ネットワーク部とホスト部からなる．

### クラスフルアドレス

先頭ビット列か10進法の数字をみればクラスが識別できるようになっていて，クラスが識別できれば，ネットワーク部とホスト部の区切りがわかる．

### クラスレスアドレス

クラスに割り当てられたサブネットマスクを変更することにより，1つのクラスをいくつかのセグメントに分割してアドレスを使用出来るようにするもの．

### グローバルIPアドレス

インターネットに接続するタイプのIPアドレス．

- 動的IPアドレス
  家庭でインターネット・サービス・プロバイダー(ISP)に接続する場合など
- 静的IPアドレス（固定IPアドレス）
  ホームページの公開サーバーや、メールの送受信のためのメールサーバーの場合など

### プライベートIPアドレス

インターネットに接続しないタイプのIPアドレス．
ブロードバンドルーターのNAT（Network Address Translation），つまりプライベートIPアドレスをグローバルIPアドレスに変換する機能が必要．

## ドメイン名

IPアドレスと紐付けられた文字．kagoya.jpなど．
インターネット上のネットワークの名前．

### トップレベルドメイン

ドメインの中でも「.」で区切られた最も右側の部分．

- 分野別トップレベルドメイン（gTLD)
  com, net, org
- 国コードトップレベルドメイン(ccTLD)
  jp, us
- 属性型JPドメイン名
  「jp」ドメインの中でも、トップレベルドメインの次の文字列（セカンドレベルドメイン）に指定の文字列が入り、その文字列ごとに取得可能な組織が限定されるドメインのこと

## ホスト名

ネットワーク内のコンピュータの名前．

## FQDN(Fully Qualified Domain Name)

ホスト名とドメイン名を省略せずにつなげて記述した文字列．

## URL(Uniform Resource Locator)

プロトコル+ホスト名+ドメイン名+パス名をつなげて記述した文字列．

## DNS(Domain Name System)

主にホスト名に対するIPアドレスは何かを教えてくれるシステム．

## DHCP(Dynamic Host Configuration Protocol)

TCP/IPネットワークにおいてホストに設定情報を伝達するための仕組み．
DHCPはクライアント・サーバ方式で、DHCPサーバがネットワークアドレスを動的に割り当て、設定情報とともにホストに送信する．

## TCP(transmission control protocol)/IP

通信の制御と信頼性の確保を担うTCPと，データをパケットに分割して通信相手に高速転送するIPという2つのプロトコルで構成される．
(WIP) Hyperledger Fabric でチェーンコードを呼ぶときの引数の扱い (Function, Args など)

取り急ぎ忘れないように、書きかけです。

# `peer chaincode invoke (query)` で呼ぶとき

`-c` オプションでJSON文字列を指定。
このJSONにはプロパティ `Function` (メソッド名) と `Args` (引数) を指定できる。

例えばメソッド `f` を引数 `arg1` および `arg2` で呼びたいならこうする:

```bash
peer chaincode invoke \
  -o orderer.example.com:7050 \
  -C mychannel \
  -n mycc \
  -c '{"Function":"f", "Args":["arg1","arg2"]}' \
  --waitForEvent
```

実は、**内部ではメソッド名は引数の一部として処理されている**ので、これと等価である。

```bash
peer chaincode invoke \
  -o orderer.example.com:7050 \
  -C mychannel \
  -n mycc \
  -c '{"Args":["f","arg1","arg2"]}' \
  --waitForEvent
```

基本的には、引数はバイト列の配列としてチェーンコードに渡されるが、文字列の配列として受け取るメソッドなどが用意されている。
なお、プロパティ名はcase insensitiveのようで、`Function` の代わりに `function` でも動くことは確認した。
(`Args` はやってない)

# Node.js のクライアント (Hyperledger Fabric SDK for Node.js) で呼ぶとき

古いAPIと新しいのがあるが、ここでは新しいほうの場合を紹介。

ここでは、チェーンコードの実装側は `Contract` インタフェースを実装して作られていると仮定する。

## `fabric-network` で呼ぶとき

このとき、呼ぶ側は

```javascript
const response = await contract.evaluateTransaction('f', 'arg1', 'arg2')
```

とする。いずれも文字列を与える。JSのオブジェクトをそのまま渡せるかと思ったら失敗したので `stringify` してから渡そう。

このとき、受け取る側はメソッド名に対応するメソッドが自動的に呼ばれる (これは例外的。Goでチェーンコード書いたりしたときは、特に自動ではディスパッチしてくれない。メソッド名は単なる第0引数)
マニュアルには引数は `JSON.parse` されると書いてあるように自分には読めたが、実際にはただの文字列として渡されるので自分でparseしよう。

> ちなみに、上記の `Contract` を使うチェーンコードではメタデータを渡せて、そこで引数のシグネチャをJSONスキーマで指定できる。
> スキーマを指定し、かつそこに `object` と型が書かれている時には `JSON.parse` されるらしいが、未確認である。

## `fabric-client` で呼ぶとき

*ちょっと忘れたので思い出したら書く*

## `peer chaincode instantiate` で指定したとき

最近知ったのだが、`Contract` ベースで実装したときに呼ぶ初期化メソッドを `-c` で指定できる。
この場合、`-c` で指定したメソッド (と引数) が初期化メソッドとしてinstantiate直後に呼ばれることが確認できた。
(instantiateトランザクションと同じトランザクションか別なのかは未確認)

なお、Goで書いたり `Chaincode` ベースで書いたチェーンコードをinstantiateする場合には、`-c` で指定した内容が `init()` や `Init()` に、そのまま配列として渡される。
ようやくHackMDをインストールできた

cenos7でdocker+nginxというのはよくみかけるんだけど
cnetos6.9+apacheリバースプロキシってのが全然資料がなくて
ネットで情報を探しまくりようやくできた。

+node v11.15.0
+npm 6.7.0

下記を参照した
https://qiita.com/KosukeJin/items/bb0daaed9f058439e225

https://qiita.com/teco_naka/items/88397c02c5b5f16032dc

https://qiita.com/atsuyuuki/items/072c41cb9405264cf368

https://qiita.com/suecharo/items/14f4d0b5430db811254e

これが一番役に立った
https://gist.github.com/Buravo46/60e1ba6a4e629f32b846e1b1aa6ef3b8

下記で簡単にssl化まで終わった

ProxyPreserveHost On
ProxyRequests off
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:port/$1 [P,L]
ProxyPass / http://127.0.0.1:port/
ProxyPassReverse / http://127.0.0.1:port

しかし、何故か安定稼働していたgrowiが壊れた
普通にmongodbが落ちてただけだった。
ActsAsPublishable 作ってみた

公開フラグの立ってるものだけを取るのをうまいこと書きたかったので、[acts_as_paranoid](https://github.com/ActsAsParanoid/acts_as_paranoid)をまねて作ってみた。

`:disabled` はコントローラから有効無効を制御する用。
（↑ユーザー権限が管理者のときは全部出したいなどという目的）

Rails素人にはこれが限界。

```ruby:ActsAsPublishable
module ActsAsPublishable
  thread_mattr_accessor :disabled

  module Publishable

    def published?
      self.published_at.present?
    end

    def self.included(base)
      base.extend ClassMethods
    end

    module ClassMethods

      def published_default_scope
        return nil if ActsAsPublishable.disabled
        self.all.table[:published_at].not_eq(nil)
      end

      def with_unpublished
        without_published_default_scope
      end

      protected

      def without_published_default_scope
        scope = self.all

        scope = scope.unscope(where: published_default_scope)
        # Fix problems with unscope group chain
        scope = scope.unscoped if scope.to_sql.include? published_default_scope.to_sql

        scope
      end
    end
  end

  def acts_as_publishable(options = {})
    include ActsAsPublishable::Publishable

    default_scope { where(published_default_scope) }
  end
end

# Extend ActiveRecord's functionality
ActiveRecord::Base.send :extend, ActsAsPublishable
```