OmniAICreator/Qiita-1.07M huggingface dataset:
GoでAPI Clientのframeworkを考えてみた

今回Advent CalendarでいくつかAPI Clientを作って感じたことは、GoでAPI Clientの構成は細部は違くともほぼ同じ作りで大抵の箇所は前に作ったもののコピーでできてしまうということです。

しかしながら、外部パッケージではなくコピーしたところも動作保証しなければならないため、それらの箇所に関してもすべてテストする必要があります。

API ServerやApplicationを作るときにFrameworkを使うと最低限の箇所を作れば、いいのと同じように共通化できる箇所を1つのパッケージにまとめた`bone`を作りました。

Bone
https://github.com/usk81/bone

Boneは殆どのものにInterfaceを用意しています。
そのため、

最小限の構成を考えた場合、以下のようになります。
クライアントの作成は、`bone.NewClient`がほとんど対応してくれます。
足りない部分を記載してあげるだけで完了します。

APIごとに1番異なるのが、レスポンスを受けたあとの処理とエラーレスポンスの処理方法です。
エラー対応は`CheckResponse`を`SetResponseChecker`で差し替えることができるので、独自の処理に置き換えて使ってください。
boneでstatus codeをチェックするだけの処理を用意しているので、それを使っても構いません。

`ErrorResponse`はエラーレスポンスをエラーとして扱うためのものです。
こちらはinterfaceを用意していませんが、errorのダックタイピングになるので、`Error()`メソッドが用意されていれば同様に扱えます。エラーレスポンスのボディの内容を格納するなどして使ってください。

```go:client.go
const (
	defaultBaseURL = "https://httpbin.org/"
	userAgent      = "example"
	tokenKey       = "Authentication"
)

func New(httpClient *http.Client, token string) (c *bone.DefaultClient, err error) {
	c = &bone.DefaultClient{
		TokenKey: tokenKey,
		Token:    token,
	}
	if err = bone.NewClient(c, httpClient); err != nil {
		return nil, err
	}
	c.SetBaseURL(defaultBaseURL)
	c.SetUserAgent(userAgent)
	c.SetResponseChecker(CheckResponse)

	es := &ExampleService{}
	es.SetClient(c)
	c.SetService("example", es)
	return
}

// An ErrorResponse reports the error caused by an API request
type ErrorResponse struct {
	Response *http.Response
}

func (r *ErrorResponse) Error() string {
	// Error message
}

// CheckResponse checks the API response for errors, and returns them if present
func CheckResponse(r *http.Response) error {
	if c := r.StatusCode; c >= 200 && c <= 299 {
		return nil
	}

	errorResponse := &ErrorResponse{Response: r}
	// set optional parameters
	return errorResponse
}
```

DefaultClientには、NewRequestが用意されているので、これを使えば、リクエストするAPIのURLやHeaderの設定、リクエストボディの設定をよしなにやってくれます。

DoでAPIリクエストを行って、`bone.JSONDecode`でレスポンスボディをJSONをDecodeして`result`に格納しています。
`bone.JSONDecode`は`ResponseDecode`という関数型なので、`ResponseDecode`を満たすように作れば、XMLのレスポンスボディをDecodeすることも簡単にできます。

さらにDoは`Client`で定義されているわけではなく、`ResponseResolver`という別のinterfaceで定義されているので、リクエストを投げっぱなしにして結果を受け取りたくないのであれば、`Do`をつくらずに独自処理で解決することもできます。

```go:example_service.go
type ProfileService struct {
	client bone.Client
}

func (s *ProfileService) SetClient(c bone.Client) {
	s.client = c
}

func (s *ProfileService) Get() (result ExampleResult, err error) {
	c, ok := s.client.(*bone.DefaultClient)
	if !ok {
		err = errors.New("client is invalid")
		return
	}
	req, err := c.NewRequest(http.MethodGet, "anything"), nil, nil)
	if err != nil {
		return
	}
	if _, err = c.Do(nil, req, bone.JSONDecode, &result); err != nil {
		return
	}
	return result, nil
}
```

Boneは１日ぐらいで作ったもので、試用はできますが、まだコンセプトレベルです。
（テストも書いてませんし）

ですが、exampleを書いた感じだと開発工数は減らせそうな感触は得られたので、引き続き開発したいと思います。
[TouchDesigner]明日使える?小ネタ集

どうもこんにちは[初心者](https://qiita.com/nariakiiwatani/items/931f6f337a3a3dc54555)です。
しばらく触ってなかったんですが最近ちょこちょことTDを案件に投入してみていて、いくつかオレオレユーティリティが出来てきたので放出したいと思います。

使用は自己責任でご自由にどうぞ。
https://github.com/nariakiiwatani/TouchDesignerMyComponentsSelection2019

## Keep CHOP
![keep_chop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/b87a74d4-29c9-f60c-1b5e-dab6248d5118.gif)
入力を一定時間保持してからOFFにしてくれる。
複数トリガーがあってもON中なら吸収してくれるので、SEのボリュームとかエフェクトのアルファとかに使えるかも？

## SelectIndex CHOP
<img width="688" alt="select_index.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/11b247e8-c1c4-5f66-9e0b-7c412e3164cd.png">
in2のCHOPから、指定したインデックスのチャンネルだけを取り出す。
LookUp CHOPのチャンネル版。
notスイッチがあるのが地味に便利そう。

## Split CHOP
<img width="747" alt="スクリーンショット 2019-12-24 0.12.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/dcb65f15-96ba-ce9f-7d10-bd071b1a23b3.png">
チャンネルをオペレーターにバラしてくれる。
思いつきで作ったので使い所は不明。

## CycleIndex CHOP
![cycle_index.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/6b197919-f296-a287-a0d7-87ef4ff0769a.gif)
トリガーを受け取るたびにフェードアウト/インの時間を確保しつつ次のインデックスに移動する。
クロスフェードしないシーンの切り替えに。

## RangeIndex CHOP
![range_index.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/a26a91aa-71d2-61c6-5653-1230053bb54d.gif)
in1の値がin2で指定したどの区間にあるかを判定する。
それぞれ長さの違うソースのスイッチングに使えるかも。
in2は絶対値(Position)もしくは初期値と長さ(Duration)のどちらでも指定できる。

## Schedule CHOP
<img width="684" alt="schedule.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/cf09efa7-8e67-60fa-f107-918b22d451dc.png">
何時から何時まで何分おきになんかしたいみたいな時に使える。
時間を区切って演出をトリガーするインスタレーションとかに良いかも。

## BlendSwitch CHOP
![blend_switch_chop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/f4f7e827-5a0f-16ca-4946-c9db19833905.gif)
指定したインデックスの値までブレンディングしつつ遷移する。
入力の数とブレンドの速度がParameterで設定可能。

## BlendSwitch TOP
![blend_switch_top.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/e2c46ab3-c3aa-2733-e9a0-952a011f30f0.gif)
上のやつのTOP版。
Switch TOPのブレンドと違うのは、隣じゃないインデックスへ飛んでも正しくフェードできること。
入力の数とブレンドの速度がParameterで設定可能。

## DropShadow TOP
![dropshadow.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/d9c03eed-d1c9-6671-da04-977473d5667d.gif)
作っとくと便利系TOP。
ずらしてベタ塗りしてブラーかけてるだけ。

## MatteAdd TOP
![matte_add.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/2fb7c2a1-4e4e-0c1e-d21d-fab9663fc6ce.gif)
作っとくと便利系TOP。
アルファがあるところにだけaddしたい時に普通のadd TOPではできないのでmatteを併用。

## Number (CHOP?TOP?)
![number.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/48e51792-e511-e081-be07-6488a89ab865.gif)
入力した数値に従って、入力画像を切りはりして数字を作る。
gifではin2にText TOPを入れているけど、任意のテクスチャが使用可能。デザイナーから0~9の画像をもらったときに使える。
左右揃えと桁数の固定が可能。

## Translation DAT
<img width="1311" alt="translation.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16556/e59f24e9-434f-d9c5-9723-00ab79493299.png">
シンプルなテキスト置き換え処理。
正規表現も使用可能。
PostgreSQLに接続できず困った

herokuの為に初めてPostgreSQLを導入したら、
デフォルトのポート番号5432が既に使用中と表示されて、
しばらく接続出来ず苦労したので記録しておきます。



<h2>そのときの状態</h2>
該当のエラー文はもう残っていませんが、
要約するとポート5432は既に使用中という旨のエラーが表示され、
コマンドラインからも、もちろんSQLクライアントからもデータベースに触れなくなってしまいました。

ポート5432が使用中ということなので、
「タスクマネージャー」>「詳細」>「PID」を確認しましたが実行中のアプリはなく、
コマンドラインから「netstat」を使用しても5432には何もあてがわれていませんでした。

パソコンの再起動も試みましたが、依然として何故か5432が使用中で接続できません。

<h2>解決法</h2>

<b>「pg_ctl -D "dataフォルダのフルパス" restart」 で直った。</b>


```powershell
PS C:\Users\hoge> pg_ctl -D "C:\Program Files\PostgreSQL\12\data" restart
pg_ctl: PIDファイル"C:/Program Files/PostgreSQL/12/data/postmaster.pid"がありません
サーバが動作していますか?
とにかくサーバの起動を試みます
サーバの起動完了を待っています....2019-12-23 22:04:24.510 JST [14488] LOG:  PostgreSQL 12.1, compiled by Visual C++ build 1914, 64-bit を
起動しています
2019-12-23 22:04:24.516 JST [14488] LOG:  IPv6アドレス"::"、ポート5432で待ち受けています
2019-12-23 22:04:24.541 JST [14488] LOG:  IPv4アドレス"0.0.0.0"、ポート5432で待ち受けています
....完了
サーバ起動完了
```

PostgreSQLはサーバーに接続中のときは、
「data」フォルダに「postmaster.pid」というファイルが存在し、
接続が切れたときにこのファイルは自動的に消えます。

そのファイルがないのでサーバーに接続中ではないと判断されるのですが、
とにかくサーバの起動を試みてくれるのでこれでいけました。

<h2>ローカルホストのアドレスについて</h2>

またそれとは別に、
flask+postgreSQL系の記事でURLに使うlocalhostは「192.168.1.101」になってることが多くて、
SQLAlchemyでそのまま真似て書いてエラー吐きました。

<h3>pythonの記述</h3>
```python
import sqlalchemy
# 略
    URL = 'postgresql+psycopg2://ユーザー名:パスワード@192.168.1.101:5432/データベース名'
    ENGINE = sqlalchemy.create_engine(URL, echo=True)
    con = ENGINE.connect()
```
<h3>エラー</h3>
```
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused (0x0000274D/10061)
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?
```


ローカルホストのアドレスは、
「data」フォルダ内の「pg_hba.conf」に記述があって、
そこにあるアドレスを書いたら通りました。

<b>あと「 pg_ctl -D "dataフォルダのフルパス" start」
でデータベースを起動するのを忘れずに！ </b>

アドレスが正しいのに、そもそもデータベースを起動してなくて触れなかった
WEBサービス？を作ってみて

# はじめに
プログラミングの勉強を始めて、WEBサービス？を作り一段絡したので、ここまでやってきたことを整理しておく。
あえてQiitaに載せるのは、自分だけ見れる場所だとメモ程度しか残さないと思うので。
作ってみたもの：[own-places](https://own-places.com)
作成期間：３０時間〜３５時間

# どんなWEBサービスを作ったか
お勧めの場所を写真と文と地図で投稿して共有できるサービス。
投稿するにはユーザ登録が必要で、他の機能として投稿にタグを付けることができたり、他の人の投稿にお気に入り（サイト上では”行ってみたい”）をすることが可能。

# どうしてサービスを作成したのか
WEBエンジニアとして転職する為に、ポートフォリオを作る為作成した。

# どうして場所投稿のサービスにしたのか
実際に作る前から以下は決めていて、

- 学習したことを復習しながら作れるもの
- 自分の作りたいもの
- 作りたいものが既にあるかは考えない

場所投稿にした理由は、ネットや雑誌でカフェなどを調べた時、有名な場所に目が行きがちになるが、他にも”こんな場所があるよ！”と個人が紹介する媒体があったら面白いと思ったのが動機。
”SNSでいいのでは？”となるが、自分の中でTwiiterやInstagramでの場所についての投稿は、紹介というより”ここに行ってきました！”という活動のニュアンスのものが多いと思い、場所を紹介する専門の投稿サービス作成にたどり着いた。

# どの様にして作ったのか
自分の為にも残しておきたいのでここは順番に箇条書きにする。
今回Laravelを用いて作成し、作成段階で、簡単なHTML/CSS/Bootstarp/PHP、Laravelについては基本的なCRUD操作やユーザ登録の機能について学習ずみ。

- 必要な機能、ページの洗い出し
- 機能として必要となる画像の保存やマップの表示についてどの様に行うか調査
- ER図、ワイヤーフレームを作成
- トップページを作成
- ユーザ登録・ログイン機能、ユーザページを作成
- 投稿・編集機能、投稿・投稿内容のページを作成
　※この時点では投稿タイトル、文章、画像のみ
- お気に入り機能を作成
- 地図表示のためにGoogleMap APIについて学習
- 投稿内容にマップ（緯度・経度）を追加
- 表示の修正（画像の位置等）
- 追加でタグ機能を付けることにしたので調査
- 投稿内容にタグを追加、タグ検索機能を追加
- パスワード変更機能を追加
- 退会機能を追加
- ドメイン取得などし、EC2で公開


# 振り返り
#### 反省点:最初の洗い出しが不十分だったこと
これは、最初の洗い出しでユーザ登録ができる、投稿ができるというサービス上の機能面ばかりに目がいってしまい、結果一通り作って操作確認したところ、パスワードを忘れた時や、退会する時の機能がないことに気付き後から追加した。
サービスはユーザ目線でみることが大事とよく言われているが、実際に自分で作ってみて実感した。


#### 良かったこと：0から何かを作ったこと
WEBエンジニアとして転職して会社に入ったとしてもそこには既にサービスがあるので、自分で何を作りたいか考る→作る→サーバに載せて公開、と0から行うことはあまりないと思う。簡単なサービスではあるものの、何もないところから作ったのは良い経験になった。

# サービスの今後
タイトルにサービス?と"?"を付けたのは、サービスとして作ったからには実際に使われいることで完成だと思ったから。動機となった”個人のお勧めの場所を知れる”というのも色々な投稿がなければ成り立たないので、今後も改善していき使いやすいサービスにしていく必要がある。

今後の改善点としては、画像が１枚しか投稿できない状態なので複数枚投稿する様にしたり、マップ表示のための緯度・経度は検索の為のマップを用意しているものの、投稿の際には調べた緯度と経度をコピペしてもらう必要があるのでそこを自動入力にする必要があったりと、色々ある。

ただ、HTML/CSS/PHP/Bootsrap/Laravelについては２、3週間で詰め込んだのでまずはそちらの復習をしつつJavascriptのちしきも必要とわかったので、学ぶことはたくさんあるが、学びつつ改善していこうと思う。

# 最後に
もしここまで読んでくださった方がいたら、長い文章に付き合っていただきありがとうございます。
これがQiita最初の投稿となりますが、今後は技術面での気づきなどあれば投稿していきたいと思います。
ちょっとしたコードを動かすときはDartPadがオススメ

# DartPad

https://dartpad.dartlang.org/

今まではmain()関数だけが用意されていてDartのコードが試せるシンプルなものでした。
これだけでも十分便利だったのですが最近はFlutterも試せるようになっております。

左上の [< > New Pad] からFlutterを選択するとFlutterモードに切り替わります、
これでFlutterのWidgetを使ったレイアウトまで簡単に確認できるようになりました。


# DartPad + Gist

DartPadはGistと連携されていて、GistにあるコードをそのままDartPadで動かすことができます。
誰かとさくっと共有したい時とかはかなり便利ですね


#### 使い方
1. Gistにmain.dartだけで動くFlutterのコードを用意する
2. `https://dartpad.dartlang.org/{GistのID}`にアクセスする

#### 例

GistのURLは`https://gist.github.com/{ユーザー名}/{GistのID}/`となっているので

https://gist.github.com/ysknsn/d4d3305f86ac5a234d699d75fc47e5d9 の場合は、
DartpadのURLはこうなります
https://dartpad.dartlang.org/d4d3305f86ac5a234d699d75fc47e5d9

これだけでGistのコードがDartPadに表示されます

# 使用感

サジェストが弱くてもどかしいのである程度大きめのコードを書くのはまだまだ辛いですね
あくまでちょっとした挙動とかレイアウトとか、人のコードを軽く動かして見たりするぐらいな使い方が良さそうです
Noodlでみなさまにお礼してみた

# Noodlコミュニティの活動を振り返る
クリスマスイブなので、ちょっとだけ、Noodlコミュニティ活動のまとめです！！

[Noodlもくもく会 #1](https://togetter.com/li/1428240)
[【eLV】Noodl×Node-REDハンズオンもくもく会 ＃2](https://togetter.com/li/1433592)
[ノンコーディングIoTパーティー（ハロウィン版）](https://togetter.com/li/1423641)
[ノンコーディングIoTパーティー（クリスマス版）](https://togetter.com/li/1441341)
[Noodl LT懇親会 （Noodlもくもく会 #3 ）](https://togetter.com/li/1444034)

とっても楽しい1年でした！！！

5月くらいから始まったNoodlコミュニティ、はじめはイベントをやっても人が来ず非常に苦しかったのですが、
こうしてもくもく会やコラボイベント、アドベントカレンダーまでできるようになり、
本当に感謝＆毎日楽しいです。

来年も早速、いろいろな方といろいろな事を計画中で、今から楽しみにしていますっ。

一番変化したと感じるのは自分のマインドセットです。見える世界が変わりました。

本当にありがとうございます。


というわけで、

# 感謝の気持を込めて、Noodlでグリーティングカードを作ってみました！

[Noodlでグリーティングカード作ってお礼してみた！！](https://mizuki-kisa.github.io/adcale_deployed/)
※↑にアクセスしていただくと楽しめます。

<img width="1552" alt="スクリーンショット 2019-12-23 23.20.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480279/6afe1c8c-fb8d-cea6-0e2e-aff7275614ec.png">


# ...なんかスクショの画面、微妙に違わない？
なんか違う...

それに、ドラッグがこころなしかサクサク動く気がしませんか...？



その理由は... 明日のお楽しみです！！
java 配列変数

今回は配列変数について書きます。

# 配列変数とは
配列が複数の値がまとまったものですが。
配列変数はそれを変数に入れて使用する方式です。


例はこちら

```java:配列変数の例
public class Sample {
 
    public static void main(String[] args) {
         double[] d = new double[3];
         double sum,avg; //  合計値、平均値を入れる変数
         //  値を代入
         d[0] = 1.2;
         d[1] = 3.7;
         d[2] = 4.1;
         sum = 0.0;
         for(int i = 0; i < d.length; i++){
             System.out.print(d[i] + " ");
             sum += d[i]; //繰り返し構文で値を総ていれる。
        }
        System.out.println();
        avg = sum / 3.0;
        System.out.println("合計値：" + sum);
        System.out.println("平均値：" + avg);
    }
}
```

実行結果は
1.2 3.7 4.1
合計値：9.0
平均値：3.0
とで出てきます。

では詳細を進めて行きます。

# 配列の宣言

まず配列の宣言を行います。

```java:配列の宣言
(変数の型名) (変数名)[] = new (変数の型名)[配列の数];
または
(変数の型名) [](変数名) = new (変数の型名)[配列の数];
```

一番最初はこうした形で宣言しました。

```java:一部抜粋
public static void main(String[] args) {
         double[] d = new double[3]; //ここで宣言しています。変数dにdoubleの型,配列の数は3です。
         double sum,avg; 
```
エンジニアのためのテクニカル分析

# 1. はじめに
- ニューヨーク仕込みのダン高橋さんがテクニカル分析について解説していたので、自分自身への備忘録を兼ねて、お伝えしたいと思います。

# 2. 思想
- ファンダメンタルズはそんなに重要ではない
- テクニカルはアートである
- ファンダメンタルズは補助的に利用する
- 買い売りのタイミングはテクニカルで判断する
- RSIとMACDはみんなが使うから効果がある
- テクニカルは100人いれば100通りの意見があるので面白い

# 3. テクニカル短期分析
- RSI（アールエスアイ）
- 1年チャート、日足
- 50を割り切るとやばい
- 70を超えても上昇中は気にしない

# 4. テクニカル長期分析
- MACD（マックディー）
- 5年チャート、週足、8、16、6
- ヘッドアンドショルダーが出ると危ない（3回目がやばい）

# 5. 補足：一般的な考え方
## RSI
- 50を上回ると上昇トレンド（買い時）
- 70を超えると買われすぎ（売り時、上値）
- 50を下回ると下落トレンド
- 30を下回ると売られすぎ（底値）

## MACD
- 雲みたいなやつ（上下に伸びてる赤い線のやつ）が下から上に抜けると、買い時
- 雲みたいなやつ（上下に伸びてる赤い線のやつ）が上から下に抜けると、売り時
- 上記2点と参考に、線のクロスの箇所で、売り、買いするのもよい

## キャンドル（ローソク足）
- 陽線のひげなしは強気
- 陰線のひげなしは弱気
- 下ひげのみは上昇のサイン
- 上ひげのみは下降のサイン

# 6. チャートサンプル（2019/12/23）

![20191223チャート.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/f316105a-59d2-8ff4-026a-4e65006fd572.png)

# 7. 参考
- [YouTube：Zeppy投資ちゃんねる](https://youtu.be/f1FxakDnc-Q)
- [YouTube：Zeppy投資ちゃんねる](https://youtu.be/PtOVtx-DTWA)

# 8. おわりに
- いかがでしたでしょうか？エンジニアでも簡単なチャートぐらい読めるとかっこいいと思います。
今回の記事が、みなさまの学習の参考になれば幸いです。

2019/12/23 TAKAHIRO NISHIZONO
Font Awesome v4.5.0とv4.7.0の差分

## TL;DR;

- 差分は、アイコンの高さが1px増えるバグfix、instragm、mastercardのアイコン変更への追随、アイコン70点追加
- `v4.5.0`から`v4.7.0`へupdateしてしまって問題なし


## 差分の詳細

https://github.com/FortAwesome/Font-Awesome/compare/fddd2c2...a8386aa

- git diffの大半はdocumentの更新

## 差分のダイジェスト

- アイコン増えた: 605 -> 675
- アイコンの高さが1px高くなっていたバグがfixされた
    - https://github.com/FortAwesome/Font-Awesome/issues/8101#issuecomment-207132126
- instagramのアイコンのアップデート `fa-instagram`
    - 本家のアイコン変更への追随
    - https://github.com/FortAwesome/Font-Awesome/issues/9175
- mastercardのアイコンのアップデート`fa-cc-mastercard`


## 差分の知識が役立った場面

`v4.5.0`、`v4.7.0`両方が使われてるプロジェクトで統一してよいものか判断したいとき
【Vue.js】エラーの表示を簡単に実装してみる ~ vue-toasted ~

# 概要
本記事では、Vue.jsで使える便利なNotificationライブラリである **vue-toasted**についてまとめていきます。

## vue-toasted って？
vue-toasted とは、概要にも記述した通り、Vue.jsで使えるNotificationライブラリです。
実装自体も簡単で、3分あれば実装できてしまうとても便利なものです。
トーストでお知らせを表示させたい時にぜひ使ってみてください！

公式ページ : https://www.npmjs.com/package/vue-toasted

## 環境
Vue.js 2.9.6

### インストール
yarn、npm、CDNののいずれかでインストールしてください。

#### yarn
`yarn add vue-toasted`

#### npm
`npm install vue-toasted --save`

#### CDN
```html:index.html
<script src="https://unpkg.com/vue-toasted"></script>
```

### 実装方法
1. vue-toastedを読み込む

```js:main.js
import Vue from 'vue'
import App from './App.vue'
import Toasted from 'vue-toasted';

Vue.use(Toasted);

new Vue({
  render: h => h(App)
}).$mount('#app')
```
※CDNの場合はimportの記述は必要ありません。

2.Vueコンポーネントで呼び出す

```vue:App.vue
<template>
  <div id="app">
    <button @click="btnClick">クリック</button>
  </div>
</template>

<script>
export default {
  methods: {
    btnClick() {
      this.errToast("エラーです！");
    },
    errToast:function(msg){
      // main.jsで読み込んだので this.$toasted で呼び出せる
      this.$toasted.error(msg);
    },
  }
}
</script>

<style>
.toasted-container .toasted {
  /* スタイルを修正することもできます */
}
</style>
```

これで実装は完了です。
今回はエラーの表示の時のトーストを実装したため、赤色のトーストが表示されたと思います。
エラー以外にも、オプションを設定すれば様々なトーストを実装することができます。


## 応用編
### オプション

```js:index.js
import Vue from 'vue'
import App from './App.vue'
import Toasted from 'vue-toasted';

// オプション設定
// 今回はポジション・表示されてから消えるまでの時間・横幅についてのオプション追加
var options = {
  position: 'top-center',
  duration: 2000,
  fullWidth: true,
}

Vue.use(Toasted, options);

new Vue({
  render: h => h(App)
}).$mount('#app')
```

このようにオプションを渡してあげることによって、思い通りのトーストを簡単に実装することができます。
下記URLから、ぽちぽち操作して目で見ながら理想のトーストを作っていくこともできるのでおすすめです！
https://shakee93.github.io/vue-toasted/
Elixirで、RubyのArray#packなことをする

# はじめに
- [Monacoin](https://monacoin.org/)のtestnet4に、とある[コインベーストランザクション](https://testnet-blockbook.electrum-mona.org/tx/2d3dcae3531be76f8e1ad1ba15f1c4503b159329156ad3814b1904eab411a6dd)があります
- 以下、抜粋です
<img width="1177" alt="スクリーンショット 2019-12-23 22.56.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/0c9af043-6381-a4b3-4fe9-4011297ec19b.png">

- `coinbase`のところの  `"coinbase": "03e9bc0a42656c6965766520696e20796f7572207370697269742e20476f20666f7274682e00000000"` これはなんと書いてあるのかなー？　と
    - 先頭のほうの`03e9bc0a`と`00000000`を外した`"42656c6965766520696e20796f7572207370697269742e20476f20666f7274682e"`を以下読んでみます
    - 先頭のほうはたしかブロック高(だった気がする)
    - うしろのほうのやつは0だからいいでしょう
    - 16進文字列(上位ニブルが先)の形式になっています
- [Monacoin testnet4 Faucet](https://monacoin-testnet-faucet.torifuku-kaiou.tokyo/) `|>` これ動かしているの[私](https://twitter.com/torifukukaiou)です
    - 2017/10月か11月くらいから動かしています


# [Ruby](https://www.ruby-lang.org/ja/)なら
```Ruby
irb(main):002:0> ['42656c6965766520696e20796f7572207370697269742e20476f20666f7274682e'].pack('H*')
=> "Believe in your spirit. Go forth."
```

- [pack テンプレート文字列](https://docs.ruby-lang.org/ja/latest/doc/pack_template.html)

# [Elixir](https://elixir-lang.org/)なら
- 最近は[Elixir](https://elixir-lang.org/)にハマっていまして、[Elixir](https://elixir-lang.org/)ならどうやるんやろうなあーとおもってiexと戯れてみました
- [Enum.chunk_every/2](https://hexdocs.pm/elixir/Enum.html#chunk_every/2) がステキです！

```Elixir
iex(8)> (
...(8)> "42656c6965766520696e20796f7572207370697269742e20476f20666f7274682e"
...(8)> |> String.codepoints
...(8)> |> Enum.chunk_every(2)
...(8)> |> Enum.map(fn [a,b] -> "#{a}#{b}" end)
...(8)> |> Enum.map(&String.to_integer(&1, 16))
...(8)> |> List.to_string
...(8)> )
"Believe in your spirit. Go forth."
```

- もっと短くできるかもしれませんが愚直にやってみました
- **Thanks Elixir!**
- できた、できた
【Unity】LateUpdate()やOnGUI()よりもタイミングが遅い、OnEndOfFrame()を作ってみた

# 問題

フレーム内のなるべく遅いタイミングで、何か処理をしたい。普通なら、 `LateUpdate()` で十分だが、諸々の事情により `OnGUI()` よりも遅いタイミングが必要になった。

そこで実行順に関する[公式ドキュメント(Order of Execution for Event Functions)](https://docs.unity3d.com/ja/current/Manual/ExecutionOrder.html)を確認したところ良さげなタイミングを見つけたので、 `WaitForEndOfFrame()` を利用して強引に作ってみた。

```endofframetest.cs
public class endofframetest : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(StartEndOfFrame());
        Debug.Log($"Start():{Time.frameCount}");
    }
    IEnumerator StartEndOfFrame()
    {
        while (true)
        {
            // Wait until all rendering + UI is done.
            yield return new WaitForEndOfFrame();
            OnEndOfFrame();
        }
    }

    private void FixedUpdate()
    {
        Debug.Log($"FixedUpdate():{Time.frameCount}");
    }
    void Update()
    {
        Debug.Log($"Update():{Time.frameCount}");
    }
    private void LateUpdate()
    {
        Debug.Log($"LateUpdate():{Time.frameCount}");
    }
    private void OnGUI()
    {
        Debug.Log($"OnGUI():{Time.frameCount}");
    }
    private void OnEndOfFrame()
    {
        Debug.Log($"OnEndOfFrame():{Time.frameCount}");
    }
}
```

```Console.
Start():1

FixedUpdate():1

Update():1

LateUpdate():1

FixedUpdate():2

Update():2

LateUpdate():2

OnGUI():2

OnGUI():2

OnEndOfFrame():2
```

# 結果

Start()のタイミングを1フレーム目としたとして２フレーム目からしか呼ばれないので、その点は注意する必要があるが概ね問題なく利用できた。

ちなみに、、、OnGUI()も２フレーム目からしか呼ばれないようだ(確認したのはUnity2020.1α)。
Alibaba Cloud Academyについて

##はじめに
Alibaba Cloudの知識を高めたいと思いましたが、仕事で使う機会が少なかったので自分で調べるところからはじめました。ネットで調べたところ見つけたのがAlibaba Cloud公式のAlibaba Cloud Academyという教育サイトです。
この教育サイトにはいくつのＥラーニングコースがあり、とても役立ちますが（自分と同じ）初心者はどこから手を付けたらいいの分からす困ってしまう場合もあうと思います。
ぞんな方々のためにAlibaba Cloud Academyが主催しているイベントがあります。それは例えば[クリケットの試合のビッグデータコンテスト](https://edu.alibabacloud.com/training/cricket-bigdata)からのビッグデータを勉強できることです。

さて、今回そのAlibaba Cloud Academy　を紹介したいと思います。

##Alibaba Cloud Academy
現在Academyには130以上コースがあって、中はセクションでが分かれています。今回がこの中からおススメしたいを紹介したいよ思います。
###学習パス
ここは三つパスがあります
[ネットワーク](https://edu.alibabacloud.com/certification/network-learningpath?spm=a3c0i.11593861.1348954.2.49666d84uJAeLr)、
[DevOps]
(https://edu.alibabacloud.com/certification/devops-learningpath?spm=a3c0i.11593861.1348954.1.49666d84uJAeLr)
[ビッグデータ](https://edu.alibabacloud.com/certification/bigdata-analysis-learningpath?spm=a3c0i.11593861.1348954.3.49666d84uJAeLr)。
各パスが約１２コースずつがあり、全てやり遂げると証明書が貰えます。
<img src="https://img.alicdn.com/tfs/TB14ioCc3aH3KVjSZFjXXcFWpXa-3000-2000.jpg" width=50%>

###Apsara Clouder技術認定
[ここ](https://edu.alibabacloud.com/certification?spm=a3c0i.11593861.1102851.1.49666d84uJAeLr#guid-1232445)で多くのAlibaba Cloud Academyのコースの一覧学習パスやイベントのコースは全部ここを参考して割引をする。
各コースビデオかテキストの教材があり、最後にコースの知識を試すテストがあります、このテスト合格したらばバッジが貰えます。
<img src="https://xuecdn2.aliyunedu.net/img_fcd6587ae514cae1aaa6e8391de0275d.png" width=30%>

##イベント
イベントやプロモーションをAlibaba Cloud Academygが開催していると書きましたがが、まさに三日に前新しいイベントが始まりました、それの紹介と一緒にイベントの特色もちょっと触ります！
それは[冬休みセール](https://edu.alibabacloud.com/training/winterholidaysale?spm=a3c0i.11593861.1102849.2.633e6d84ismZlo#guid-1404685)です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399504/3eabe6cd-f497-91de-4fa8-173e8ae9473f.png)
あそこでコースパッケージが６個ありまして、各パッケージ三つコースあります（全部9割の割引で）。
4個コース終わったら、AcademyのシャツとETドルもらえます（最初の20名両方もらえますが、50名まではETドルだけです）のでお早めに！
<img src="https://img.alicdn.com/tfs/TB1X1cHo7T2gK0jSZFkXXcIQFXa-270-300.png" width=30%><img src="https://img.alicdn.com/tfs/TB1OvgEo1H2gK0jSZFEXXcqMpXa-236-300.png" width=30%>

Academy公式の[ツイッター](https://twitter.com/cloud_alibaba)も、イベントと言う程度ではないが、毎月一番コースを終わらせる人が紹介されますので、たくさんコースをして世界中に顔を知られることもできます
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399504/12f3eca7-c1c9-e0ae-5da3-83b1c70e1246.png" width=50%>

##おわりに
とても軽くの紹介でしたが、本当にシンプルのシステムでAlibaba Cloudを学べる所です。私結構使っているので、皆さんも使ってもらいたいです。**たくさんの人使ったら、もっといい講座が出るかもしれませんね！**

最後まで読んで頂き、ありがとうございました。
Atomのgit-controlでPushができないと思ったら、pre-commitでeslintにより弾かれていた件

これは[TOWN Advent Calendar 2019](https://adventar.org/calendars/4335) 23日目のエントリーです。

Atomの[git-control](https://atom.io/packages/git-control)プラグインを使ってGitの操作をしているのですが、コミットはできるもののプッシュができない（ボタンが選択可能にならない）現象が発生しました。
（よくよく見ると画面の下の方にエラーが出ていたのですが最初気がつかづ。。。）

こういうときには面倒ですがTerminalからコマンドを直接入力して確認をしてみます。


```
% git commit
husky > pre-commit (node v13.5.0)
  ✔ Stashing changes...
  ❯ Running linters...
    ❯ Running tasks for *.{js,vue}
      ✖ eslint
  ↓ Updating stash... [skipped]
    → Skipping stash update since some tasks exited with errors
  ✔ Restoring local changes...



✖ eslint found some errors. Please fix them and try committing again.

/project/plugins/firestore.js
  1:28  error  Delete `;`  prettier/prettier
  2:42  error  Delete `;`  prettier/prettier
  4:32  error  Delete `;`  prettier/prettier
  7:18  error  Delete `;`  prettier/prettier

✖ 4 problems (4 errors, 0 warnings)
  4 errors and 0 warnings potentially fixable with the `--fix` option.

husky > pre-commit hook failed (add --no-verify to bypass)
```

どうやらpre-commit時にeslintが効いてコミットが弾かれている、ということがわかります。

該当するファイルを修正して再度コミットすることでPushができるようになりました。

![スクリーンショット 2019-12-23 22.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46805/c310bdb6-ac11-a053-1b8a-597b0a8325f0.png)


git-controlは画面上のウィンドウサイズをを変更できないので長いログが出たときに見落としがちなので注意です。
MIT Open CoursewareのPerformance Engineering of Software Systemsをやっていく（１）

MIT Open CoursewareのPerformance Engineering of Software Systemsをやっていきます。


https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-172-performance-engineering-of-software-systems-fall-2018/

##プロプロセッシング

プリプロセッサはコンパイルのフェーズに入るまでに、ソースコードを改変します。以下の例を見てみましょう。

```preprosessor.c
// ALl occurrence of ONE will be replaced by 1
#define ONE 1

#define MIN(a,b) ((a) < (b) ? (a) : (b))

int c = ONE; d = ONE + 5;
int e = MIN(c,d);

#ifdef NDEBUG

if (something) {}

#endif
```
これを以下のコマンドでプリプロセスします。

```
$ clang -E preprosessor.c 
# 1 "preprosessor.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 362 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "preprosessor.c" 2





int c = 1; d = 1 + 5;
int e = ((c) < (d) ? (c) : (d));
```

NODEBUGではないので、`#ifdef NODEBUG`以外のところのみが表示されてますね。
では、以下のコマンドではどうでしょうか？

```
$ clang -E -DNDEBUG preprosessor.c 
# 1 "preprosessor.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 362 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "preprosessor.c" 2





int c = 1; d = 1 + 5;
int e = ((c) < (d) ? (c) : (d));



if (something) {}
```

NDEBUG内のコードが表示されましたね。他にプリプロセッサでは、#defineで定義された定数や、マクロなどが展開されています。コメントなども削除されてることにも注意が必要です。
【AtCoder】競プロ初心者でもできる300点問題

# はじめに
こんにちは、背の高い人と申します。今のところ何か特別強いものを持っているわけではありませんが、競プロが好きなので競プロの話をします(AtCoderのレートはたまに茶色パフォが出る程度の灰色です)。何か書くことないかなーと思ってAtcoder Problemsを見ていたら僕が自力でACできた300点問題を見つけたので2問ほど紹介しようと思います。200点問題が安定してきたから300点も解けるようになりたい！っていう人はぜひ解いてみて自信をつけてください。特に弊部のつよつよ1年生なんかは解けるのではないでしょうか。

#環境
C++14(GCC 5.4.1)

# 問題たち

## C - Remainder Minimization 2019
https://atcoder.jp/contests/abc133/tasks/abc133_c
この問題は全探索しようをするとTLEします。そこでループの回数を工夫しましょう。まず確認しておくと、  (i × j)mod 2019 とは 「(i × j)を2019で割った余り」のことです~~(僕は所見でググりました)~~。2019で割った余りを求めるのであれば、0 <= (i × j)mod 2019 < 2019 となります。ということはL < i < Rの範囲でループしながらL < j < L+2019 または L < j < R を満たす(i × j)mod 2019 の範囲を探索してあげればいいですね。そうすればなんと2重目のループの回数が最高でも2019回で済みます。
↓コードの例

```cpp 
#include<bits/stdc++.h>
using namespace std;
 
int main(){
 
    long long int l,r;
    cin >> l >> r;
    long long int ans = 2019;
 
    for(long long int i = l; i < r; ++i){
        for(long long int j = i+1; j <= r && j < l+2019; ++j){
            ans = min((i*j)%2019, ans);
            if(ans == 0)break;
        }
    }
 
    cout << ans << endl;
 
 
}
```
この問題に限ったことではありませんが、300点問題あたりから非常に大きな数値を扱うことが多くなります。適宜long long型の変数を使ってあげましょう。僕はとある問題で変数のサイズの設定のミスに**二日くらい気付かず頭を悩ませていた**こともあるので、考え方は正しいはずなのになぜかWAが出る！というときはデバッグ時にそこも気を付けてみてください。

## C - Exception Handling
https://atcoder.jp/contests/abc134/tasks/abc134_c
この問題は各ループで消去される変数が1個だけというのがポイントです。1個しか消去されないなら、数列の最大値が消去されない限りは何が消去されようと条件に合う要素の最大値はそのまま数列の最大値となります。ということで最大値をまず max_a という変数にコピーしてあげましょう。あとは基本的に max_a を出力し、 max_a と同値の要素が消去されたときは2番目に大きい要素を出力する…
というのは**実は間違い**です。というのも、この考え方では最大値が複数ある場合に対応できません。例えば、 {1. 3. 3} という数列の場合、2番目の3を消去しても3番目の3が残っているので、最大値は3になります。しかし、先程の考え方では数列の最大値である3を無視してしまうので適切ではありません。そこで、最大値を max_a にコピーするのではなく、隔離しましょう。最大値となる要素をを1つだけ max_a に格納し、その要素を0にしておきます。そして元々最大値であった0が消去された場合は現在の数列の最大値を、されなかった場合は max_a を出力すれば解けます。
↓コード

```cpp
#include<bits/stdc++.h>
using namespace std;
 
int main(){
 
    int n;
    cin >> n;
    vector<int> a(n);
    int max_a = 0;

    for(int i = 0; i < n; ++i){
        cin >> a[i];
        max_a = max(a[i], max_a);
    }

    for(int i = 0; i < n; ++i){
        if(a.at(i) == max_a){
            a.at(i) = 0;
            break;
        }
    }

    for(int i = 0; i < n; ++i){
        if(a[i] == 0)cout << *max_element(a.begin(), a.end()) << endl;
        else cout << max_a << endl;
    }

}
```
シェルスクリプト ファイル記述子

シェルにてファイルをオープンすると、ファイル記述子と呼ばれる番号が割当られる。
そしてこのファイルへの読み書きは、ファイル記述子を通して行われる。
ファイル記述子のうち、0 と 1 と 2 は以下のように予約済みとなっている。

|ファイル記述子  |内容 |
|---|---|
|0  |標準入力  |
|1  |標準出力  |
|2  |標準エラー出力  |

これらの番号以外は自分で指定して使うこともできる。
例えば 3 を使用してみる。

```bash
# ファイル記述子の3を使って、hosts ファイルを読み込み
$ exec 3< /etc/hosts

# ファイル記述子3の内容を標準入力に入れ、一行ずつ読み込み
$ while read row 0<&3; do echo $row; done
127.0.0.1 localhost
127.0.1.1 my-local-dev
```
FlexMessageのボタンに仕込むLIFFのリンクで気をつけること

以前LINE botで[Flex MessageのボタンにパラメータをつけたLIFFを取り扱う話](https://qiita.com/K_M95/items/ccbed26d492b3304f1cb)を投稿しました。謎のエラーが出てしまって解決できずモヤモヤした気分で書いていて、あわよくば読んでくれた誰かが教えてくれればと思っていました。すると奇跡的にコメントを頂いたので改めて検証してみました。

# 頂いたコメントによると
どうやらLIFFにパラメータを渡したリンクを仕込んだボタンを使っても普通にLIFFは起動するようです。そして、Flex MessageのJSONも[こちら](https://developers.line.biz/console/fx/)のシミュレータで作成したもので、自分の作った時と全く同じやり方でした。なので、Flex Messageの作り方に問題があるわけではないようです。となると、原因はURLにあるのでしょう。

#URLを調べてみた
今度はボタンに仕込んだURLを検証しました。ひとまずコメントで頂いたURLを自分のLIFFに合わせて変更したら問題なく動きました。
![giphy.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170520/6b67482a-bb3c-53d7-d262-7c2cb0785161.gif)


# 原因がわかった
そしてここでエラー原因がわかりました。原因は**パラメータに日本語を含んだURLを使っていた**ことです。Template Messageで気にせずやれていたことが、Flex Messageだとエラーになっていたのです。というわけでURIエンコードをかけて```【liff_URL】/URLエンコードした日本語```の形でURLを生成したらLIFFは問題なくたち上がりました。
![giphy (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170520/234dd2be-f1dd-f9b4-8c79-8c4f897a633e.gif)


# まとめると…
今回パラメータ付きのLIFFが立ち上がらなかった原因はFlexMessageの仕様の問題ではなく、LIFFのリンクに日本語が含まれていたことが原因でした。なのでFlex Messageで日本語のパラメータを含めたリンクを扱う際にはURIエンコードを使えばエラーなく使えます。（おそらくプロのエンジニアの人からしたらURIエンコードは当たり前のことでしょうが、、、）
Androidアプリでのエラー処理について

この記事は[CAM Advent Calendar 2019](https://qiita.com/advent-calendar/2019/cam-inc) の24日目の記事です。:golf:
昨日は@takehziさんの[トランザクションとロックと二重課金](https://qiita.com/takehzi/items/7dc5bf66f684ceae83b8)でした。


# :warning: エラー処理って何？
Androidに限らず、クライアントアプリ全般的に言えることですが、よく***「エラーが発生しました。もう一度やり直してください。」***みたいなポップアップを見かけると思うのですが、それを表示するまでに行う処理のことをここでの**エラー処理**とします。

ここで紹介するのはあくまで一つの手法です。


# :thinking: やること

**1. エラーを受け取る**
**2. 受け取ったエラーに対してそれぞれ処理を分ける**

... 以上

と言っても、これだけだとさっぱりなので順を追って説明できればと思います。


## 1. エラーを受け取る

この受け取り方はそれぞれだと思いますが、今回は`try-catch`で`Exception`なりを受け取る想定で書いていきます。

```kotlin

try {
...
} catch(e: Exception) {
// ここで受け取る
}
```

このとき`catch`には色んな種類のエラーがくることが想定されます。
何でもいいからエラーだったら「エラーが発生しました」というポップアップを出して終わりであればここで受け取って終わりですが、今回はエラーの種類によって出しわけたいのでこれでは不十分です。

それを行うにはどういった種類のエラーなのかを判断するための情報が必要になります。

**[2. 受け取ったエラーに対してそれぞれ処理を分ける](https://qiita.com/Jung0/private/50d41f8f9bf021c2ee57#2-%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%9F%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E3%81%9D%E3%82%8C%E3%81%9E%E3%82%8C%E5%87%A6%E7%90%86%E3%82%92%E5%88%86%E3%81%91%E3%82%8B)**に行く前に準備をしましょう。

### アプリ内で扱うエラーのクラスを作る

`catch`で受け取れるためにExceptionクラスを継承したクラスを用意します。

```kotlin
abstract class CustomException(errorMessage: String): Exception(errorMessage)
abstract class ApiException(errorMessage: String): CustomException(errorMessage)
abstract class LocalException(errorMessage: String): CustomException(errorMessage)
...
```

エラーを種別にするために上記のようなクラスを作って**継承関係**でわけてもいいですが、今回はKotlinの[`sealed class`](https://kotlinlang.org/docs/reference/sealed-classes.html)を使って分けてみます。

```kotlin
sealed class CustomException(errorMessage: String) : Exception(errorMessage) {
    sealed class ApiException(errorMessage: String) : CustomException(errorMessage) {
        data class NetworkException(val errorMessage: String): ApiException(errorMessage)
        ...
    }
    sealed class LocalException(errorMessage: String) : CustomException(errorMessage) {
        ...
    }
}
```

以上でエラークラスの準備は終わりです。

## 2. 受け取ったエラーに対してそれぞれ処理を分ける

受け取ったエラーに対してどのような処理を行うかを決定していきます。

```kotlin

try {
...
} catch(e: Exception) {
    when(e) {
        is CustomException.ApiException.NetworkException -> { 
                    // やりたい処理
           }
        ...
        else -> {...}
    }
}
```

とりあえずはここでやりたいことは終わりなのですが、このような書き方をすると全画面でエラーの分岐処理を書くことになります。
なのでエラーを処理する専用クラスを設けてそちらに処理をまとめると管理しやすくなります。

```kotlin
/**
 * 例外を受け取って処理を分ける
 */
fun onErrorReceived(e: Exception) {
    when(e) {
        is CustomException.ApiException.NetworkException -> { 
                    // やりたい処理
           }
        ...
        else -> {...}
    }
}
```

メソッドに返却値を設けて`Enum`などを返してもいいですが、`RxJava`や`LiveData`を使っているのであればそちらを使ってView側へ通知を流す形にするとスッキリ書けます。



## まとめ :notebook: 
`Exception`クラスを継承したクラスを自作してのエラーハンドリングを紹介しました。
久しぶりの技術ブログだったので何を書こうか迷った挙げ句、基本的な内容になってしまいましたが、これからは定期的に書いていければと思っています。


:santa: 明日は@kidoyunaさんの記事が公開予定です。ぜひそちらもご覧ください。:eye:
オープンソースに貢献してみる

この記事は[宮崎IT関連勉強会 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/miyazaki)22日目の記事です。

ServerlessFrameworkのプラグインを修正しました。

[Lambda関数をそのままAWS Batchに乗せ換える(Python3.6限定)](https://qiita.com/YasuhiroKimesawa/items/8d7ada7cc8bddd24d60b)

https://github.com/YasuhiroKimesawa/serverless-aws-batch


ServerlessでデプロイするLambda関数をAWS Batchにソースコードをいじらずに移行するプラグインですが、いくつかバグがあったので修正しました。

ちょっと動作確認中でまだPullRequestを出していないですが、手順を残しておきましょう。

１. フォーク元のGithubに移動し、フォークボタンを押すと自分のレポジトリにフォークできます。

2. 普段どおりにローカルにCloneして適切にブランチを切って修正、自分のレポジトリにPushしましょう。

3. PushしたブランチでPullRequestを作成しましょう。ここでフォーク元を指定できます。

4. フォーク元で問題なければ取り入れてもらえるでしょう。

5. フォーク元の更新を自分のRepositoryに取り込むのは

検索するといっぱい記事が出てきますね。。。例えば、、、
https://qiita.com/icb54615/items/3544c419a3f6fc3534fb

***注意としては、フォーク元の更新を自分のレポジトリに取り込みたいので、自分のレポジトリのmasterに自分の修正を入れないことです。***

よいOSSライフを！
会社の先輩に教えてもらったSOLID Principle: Single-responsibility principle

#自己紹介
動物大好き、唐揚げ大好きな（最近はサラダも好きです）本山公子といいます:woman_tone1:
母がアメリカ在住の人と再婚して８歳から２０年間アメリカ:flag_us:で育ちました。
その後はアメリカで働いたり、日本で英語の講師:pencil2:をしたりしていましたが、

**夢はハッカー！:desktop:**
**お金持ちになりたい！:atm:**
**ビルゲイツになるぞ！:dark_sunglasses:**

のような夢を持っており、プログラマーに転職しました:point_up:
今は健全な Reactを使ったフロントエンドデベロッパーです:raised_hands:
要領の悪い私は日頃から勉強に苦戦しており、会社の先輩に相談していたら、

**「SOLID　Principleをググってごらん。:man_tone3:」**
と言われて、ググって調べてみました。
とてもいいな！と思ったので、今回はその「S」をシェアします。
何かおかしなこと、訂正した方がいいところなどのアドバイス、歓迎します！

#SOLID Principle (単一責任の原則)
SOLID Principleとは、頭文字で、

* S - Single Responsibility Principle：単一責任の原則
* O - Open/closed principle：オープン/クロースドの原則
* L - Liskov substitution principle：リスコフの置換原則
* I - Interface segregation principle：インターフェース分離の原則
* D - Dependency inversion principle：依存性逆転の原則

の略です。今日は、その「Single Responsibility Principle」
について書きます。

##Single Responsibility Principle
Single Responsibility Principle(略してSRP)は、ざっと

**クラスは一つの仕事のみ担当せよ:point_up:**

という風に言われています。
例えば、こんなコードがあるとします。

```javascript
public class BankAccount {

  public function getAccountNumber(user: User): number {
    return 1234567890;
  }
}
```

めちゃめちゃシンプルに、銀行口座の番号を返す関数を作りました。
例として書いているので、どんなユーザーでも`1234567890`が返ってくるのは、ごめんなさい:joy:

今の状態は「Single Responsibility」な訳です。
どういうことかというと、このクラスは「Bank Account」がすべき事をしているからです。
他の関係ないことはしていません。

こんなコードを追加したらどうでしょうか？

```javascript
public class BankAccount {

  public function getAccountNumber(user: User): number {
    return 1234567890;
  }

  //追加↓
  public function getBalance(user: User): number {
    return 100,000,000,000,000;
  }
```

ビルゲイツ並みにふさわしく、ちょっと欲張って大金持ちになってみました:metal:

`getBalance`という関数を作りました。
自分の残高だって知りたいですよね。
毎回残高がこの金額だったら、ウハウハです:dancer_tone3:

どうですか？まだ銀行口座らしい仕事をしていますかね？
うん、いいんじゃないでしょうか。

じゃぁ、次はどうでしょう？

```javascript
public class BankAccount {

  public function getAccountNumber(user: User): number {
    return 1234567890;
  }

  public function getBalance(user: User): number {
    return 100,000,000,000,000;
  }

  //追加↓
  public function sendBalanceStatementToUser(user: User): void {
    ExpressMail.sendStatement(user.address, 100,000,000,000,000);
  }
```

いきなり長い関数名が出てきました。
`sendBalanceStatementToUser`は、お客さんに今の残高の「お知らせ通知」を手紙で送るサービスです:envelope:
ネットが使えない、紙の方がいい！という人に喜んでもらうためです:relaxed:

でもこれって、「銀行口座」のお仕事でしょうか？
銀行口座の任務を超えてる気がしませんか？
これが、

**Single Responsibilityに反している:skull:**

わけなんですね。

銀行口座は、「講座の管理をする」ことがお仕事であって、
「お客さんに通知のお知らせを送る」ことまでは、するべきではありません。

こういった場合、通知を送ってくれるクラスを作って、そのクラスにお仕事をしてもらいましょう！

```javascript
public class Mail {

  public function sendMailToUser(user: User, balance: BankAccount) {
    ExpressMail.sendStatement(user.address, balance);
  }
}
```

これで `BankAccount`は、銀行口座のお仕事だけに集中できますね:pencil2:
なので、先ほどのユーザーに通知を送る関数は削除しちゃいます。

全部のコードは、こんな感じです。

```javascript
public class BankAccount {

  public function getAccountNumber(user: User): number {
    return 1234567890;
  }

  public function getBalance(user: User): number {
    return 100,000,000,000,000;
  }



public class Mail {

  public function sendMailToUser(user: User, balance: BankAccount) {
    ExpressMail.sendStatement(user.address, balance);
  }
}
```

以上でした:sunglasses:
rails6.1から追加される予定のActionView::Componentを4ステップで入門

# rails6.1から追加される予定のActionView::Componentを4ステップで入門

## 準備

事前にサンプルrailsアプリケーションを作成しておきます。

```
$ rails new try_action_view_compponent
$ cd try_action_view_compponent
$ rails g scaffold user
$ rails db:create
$ rails db:migrate
```

## "actionview-component"の基本的な使い方

### 1. Gemfileにgem "actionview-component"を追加

```diff:Gemfile
+ gem "actionview-component"
```

```
bundle install
```

### 2. config/application.rbでモジュールをrequireする

```diff:config/application.rb
+ require "action_view/component/railtie"
```

### 3. componentをgenerate

```
$ rails g component User name
```

作成された以下のファイルがコンポーネントファイルです。

```
app/component/user_component.html.erb
app/component/user_component.rb
```

使いやすくするために編集します。
ここでは、classと要素を外部注入するコンポーネントにします。

```diff:app/components/user_component.html.erb
- <div>Add User template here</div>
+ <span class="<%= name %>">
+   <%= content %>
+ </span> 
```

```diff:app/components/user_component.rb
class UserComponent < ActionView::Component::Base
+ attr_reader :name

  def initialize(name:)
    @name = name
  end
end
```

### 4. viewからコンポーネントを呼び出す

事前準備でscaffoldコマンドで作成しておいたusersのviewsから呼び出してみます。

```diff:app/views/users/index.html.erb
<h1>Users</h1>

+ <%= render(UserComponent, name: "test name") do %>
+   Hello, World!
+ <% end %>
```

`rails s`して画面から`localhost:port/users`にアクセスすると呼び出したコンポーネントが表示される事が確認できます。

#### renderについて
`render`メソッドの第一引数にコンポーネントのクラス名を第二引数に変数のキーワード引数を渡します。
ブロックの中に記述した文字列が、コンポーネント内で`content`変数を使用する事で呼び出す事ができます。

## その他
### バリデーション

modelのvalidationの様にコンポーネントに注入される変数の入力チェックがあるので試してみましょう。

バリデーション宣言を追加します。
ここでは`name`変数は入力必須にします。

```diff:app/components/user_component.rb
class UserComponent < ActionView::Component::Base
  attr_reader :name

+ validates :name, presence: true
```

viewから呼び出す時に`name`に空文字を渡してみます。

```diff:app/views/users/index.html.erb
<h1>Users</h1>

- <%= render(UserComponent, name: "test name") do %>
+ <%= render(UserComponent, name: "") do %>
+   Hello, World!
+ <% end %>
```

`rails s`して、`localhost:port/users`にアクセスすると以下のエラーが表示される事が確認できます。

```
ActiveModel::ValidationError in Users#index
Validation failed: Name can't be blank
```

## CSSファイル
以下の様にサイドカーCSSを配置するのがベストプラクティスの様です。

```
- /app
  - /components
    - /alert
      - alert.css
      - alert.html.erb
      - alert.rb
```

See: https://github.com/github/actionview-component/issues/55

## 動作環境

$ rails -v
Rails 6.0.2.1
$ ruby -v
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-darwin17]

## サンプルコード
https://github.com/soartec-lab/try_action_view_component
古いXcodeで新しいOSの端末を動作させる

新しいiOSがリリースされたとき、それに対応したバージョンにXcodeをアップデートすることができない場合があります。
このような場合でもXcodeのバージョンをそのままに新しいiOSの端末でアプリをデバッグ実行できるようにする方法があります。

1. 新しいXcodeのdmgをダウンロードし、インストール
2. 新しいXcodeを起動すると、インストールのダイアログが表示されることがあるので、そのままインストール
3. 新しいXcodeを右クリックし、パッケージの内容を表示をクリック
4. 下記パスに新しいOSのフォルダがありますので、それをコピー
   - `Contents/⁨Developer/⁨Platforms/⁨iPhoneOS.platform⁩/⁨DeviceSupport/XX.X`
5. 使用するXcodeへ上記と同じ階層へペースト

以上の操作により、利用できるようになりますが、うまく行かないこともありますので、参考程度にお願いします。
ApiFlashを使って脱スクショ職人

最近、時間があるときにボーっと[ProductHunt](https://www.producthunt.com/)を眺めているのですが、その中で[「ApiFlash」](https://apiflash.com/)という便利そうなサービスがあったので紹介します。

# ApiFlsashとは？

![2019-12-23_21h28_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/4873c9ba-ff76-ea49-3fe7-d45d11237e8d.png)

**ApiFlashはWeb画面のスクリーンショットを撮って、画像データを返してくれるAPIを提供するサービス**です。百聞は一見に如かずで、Webサイトのトップページのデモをみるのがわかりやすいです。クエリパラメータでサイズを渡したり、ページ全体を含めるオプションを指定したりして色んなパターンのスクショを簡単に撮れます。

![apiflush.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/b5e1df80-9507-bdd0-055b-c862f09682d7.gif)

# 実行結果

APIを呼び出す際にアクセスキーが必要ですが、[GETパラメータで呼び出せる](https://apiflash.com/documentation#access)のでブラウザでも簡単に呼び出せます。（もちろんPOSTでも渡せます）いくつか試してみました。

## ブラウザ

ダッシュボードを開いて「Get Started」をみると、GoogleページをスクショするサンプルURLが表示されます。

![2019-12-23_17h52_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/360e9a5e-d30f-5e61-255c-23e2f8b1a6d9.png)

「Launch in new tab」ボタンを押すと、ブラウザの別タブでAPIの実行結果を表示してくれます。簡単ですね。

![2019-12-23_22h10_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/38ddd693-10d5-f089-b2da-aafa2160e219.png)

## curl

curlコマンドで呼び出してみます。

```sh
curl --request GET --url "https://api.apiflash.com/v1/urltoimage? 
    access_key=xxxxx&url=http://google.com&accept_language=ja" > screenshot.jpeg
```

先ほどのブラウザの例ではGoogleのページが英語だったので、ここではaccept_languageパラメータで日本語にしました。保存されたファイルを開くとこんな感じです。ちゃんと日本語になっています。
![2019-12-23_22h12_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/12370b4d-c33f-6f99-1aee-66e65129dfbd.png)

## Visual Studio Code(VSCode)

VSCodeの拡張機能である[「REST Client」](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)だとこんな感じで、レスポンス欄で画像そのものが確認できました。すごいｗ

![2019-12-23_22h00_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/874cbeb7-f885-8535-ad81-54e4cfd951c0.png)

# Query builder

[ApiFlashで使えるパラメータ](https://apiflash.com/documentation#parameters)は様々なものがあります。Query builderを使うと、簡単にパラメータ付きのURLを作れます。

![2019-12-23_18h00_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/3b5bc7b8-1f6d-0591-981c-88880ff8bde8.png)

フルページのキャプチャが撮れるので、ちょっとした表示テストとかに使えそうです。

![2019-12-23_18h01_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/7c10efeb-50ef-0b72-f200-617747ed897f.png)

自分でwidthを指定する必要がありますが、モバイル表示なども確認できます。（width=480の例）
![2019-12-23_22h34_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/ada32373-9f62-87d2-3738-273f5fc4530a.png)


スクショ作業を手でしないといけない…みたいなときに便利そうです。
【画像処理100本ノックに挑戦】Q.29. アフィン変換(拡大縮小)

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)
[【画像処理100本ノックに挑戦】独自の行列クラスを作る](https://qiita.com/jajagacchi/items/df881888ee6a116f7730)

# Q.29. アフィン変換(拡大縮小)
>アフィン変換を用いて、(1)x方向に1.3倍、y方向に0.8倍にリサイズせよ。
また、(2) (1)の条件に加えて、x方向に+30、y方向に-30だけ平行移動を同時に実現せよ。

これも行列演算が出来れば簡単です。座標をint型にキャストしているだけなので、画質が重要であればバイリニア補間等すべきでしょう。std::roundした方がよかったか（最近傍補間）。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	double a=1.3, b=0, c=0, d=0.8, tx=30, ty=-30;


	Matrix A(2, 2);
	A.set({
		d/(a*d-b*c),-b/(a*d-b*c),
		-c / (a * d - b * c),a / (a * d - b * c)
		});
	

	int Width = width * 1.3;
	int Height = height * 0.8;
	PPM ppm2(Width, Height);
	for(int i=0; i<Width; i++)
		for (int j = 0; j < Height; j++)
		{
			ppm2(i, j, 'r') = 0;
			ppm2(i, j, 'g') = 0;
			ppm2(i, j, 'b') = 0;
		}
	for(int i=0; i<Width; i++)
		for (int j = 0; j < Height; j++)
		{
			Matrix X2(2);
			X2.set({
				(double)i,
				(double)j
				});
			Matrix X0 = A * X2;
			int i0= X0(0, 0)-tx;
			int j0 = X0(1, 0)-ty;
			if (0 <= i0 && i0 < width && 0 <= j0 && j0 < height)
			{
				ppm2(i, j, 'r') = ppm(i0, j0, 'r');
				ppm2(i, j, 'g') = ppm(i0, j0, 'g');
				ppm2(i, j, 'b') = ppm(i0, j0, 'b');
			}
		}
	
	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/e7a3932d-9f91-a5fd-82f2-9057363e169d.png) ![out1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/7ccc2660-473f-31e1-3108-f9166510c1ab.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/76e4dfef-1f63-aafa-7dd1-c95f4194c217.png)
ディレクティブとは

ディレクティブの意味がしっくりきていなかったが、以下の記事で理解することができた。

```
ディレクティブ・・・コンパイル時にコンパイラーに与える補足情報。
```

https://qiita.com/kurodai0715/items/48f7a832312e36417619
https://www.javadrive.jp/servlet/jsp_directive/index1.html
IT資格について

今回は取得予定のIT国家資格について書いて行きます。
自分でまとめて資格取得ロードマップの作成して見ようと考えています。

# IT資格の意義
基本資格は許可証という側面があるものもありますが
資格があることで、その人の能力を客観的に証明することができます。

就職・転職、各種IT営業にもいい武器になります。

# IT国家資格一覧

基本下記の3種類に分けて説明して行きます。

* IT全般系(3種)
* エンジニア系(5種)
* マネージャー系(4種)

ほとんどの資格が合格率12~15%と狭き門ですが
そのぶん得た時の価値は高いものです。

## IT全般系
全般的な知識取得証明になる資格です。
IT未経験者・初心者の方におすすめで少しでも関わるならおすすめします。

### ITパスポート
IT業界に必要な基礎知識

すべての社会人が備えておくべきIT基礎知識を証明することができる国家資格です。

### 基本情報技術者
情報技術全般に関する基本的な知識・技能をもつ人や、プログラム設計書を作成し
プログラム開発、単体テストまでの一連のプロセスを担当する人のための国家資格です。

### 応用情報技術者
高度IT人材に必要な応用的知識・技術をもち、方向性を確立した人を対象にした国家資格です。

内容としては「基礎情報技術者」と同じですが。
情報技術を活用した戦略立案、経営戦略・情報戦略など
コンサルタントレベルの高い知識が必要になってきます。

## エンジニア系
ITエンジニアのスペシャリストとして働きたいと考えている方におすすめの資格です。
専門分野が多岐に渡り、一口に言えるものではないですが
エンジニアとしてのスキルを証明することができる5つのIT系国家資格を紹介します。

### 情報セキュリティスペシャリスト
情報システムの基盤を整備し、専門家として情報セキュリティ管理を支援する人のための国家資格です。

### ネットワークスペシャリスト
情報通信ネットワークの設計・運用を担当します。

ネットワークに関係する固有の技術を活用し
最適な情報システム基盤の企画・要件定義・開発・運用・保守で中心的な役割を果たし
情報システムの企画・要件定義・開発・運用・保守への技術支援を行う人のための国家資格です。

### データベーススペシャリスト
データベースの固有技術を活かします。

データベースに関係する固有の技術を活用し
最適な情報システム基盤の企画・要件定義・開発・運用・保守において中心的な役割を果たし
情報システムの企画・要件定義・開発・運用・保守への技術支援を行う人のための国家資格です。

### エンベデッドシステムスペシャリスト
組込みシステム開発の主導します。

エンベデッドシステムとは
携帯電話やスマートフォン、デジタルカメラ、炊飯器、エアコンなどあらゆるものに
組み込まれているシステムのことを言います。

この資格は高度IT人材として確立した専門分野をもち
組込みシステム開発に関係する幅広い知識や技能を活用して
最適な組込みシステム開発基盤の構築や
組込みシステムの設計・構築・製造を主導的に行う人のための国家資格になります。

### システムアーキテクト
アーキテクチャを設計する

ITストラテジストからの提案を受けて、情報システム、組込みシステムの開発に必要要件を定義し
それを実現するためのアーキテクチャを設計し、情報システムについては開発を主導する
人を対象にした国家資格です。

## マネージャー系
技術者として現場に立つのではなく、現場をまとめるマネジメント業務が主な仕事である方、
もしくは今後マネジメント系の業務を担当していくという方におすすめの資格です。

### ITストラテジスト
業務改革推進などの部門で活躍

高度IT人材として確立した専門分野をもち、企業の経営戦略に基づいて
ビジネスモデルや企業活動の特定のプロセスについて
情報技術を活用して改革・高度化・最適化するための基本戦略を策定・提案・推進する人を対象とした
国家資格です。

### システム監査技術者
情報システムを総合的に評価

情報システムの企画・要件定義・開発・運用・保守においてセキュリティ機能の実現を支援
あるいは情報システム基盤を整備して、専門家として情報セキュリティ管理を支援する人のための国家資格です。

### ITサービスマネージャ
品質とコスト効率の向上を目指す

情報システム全体について、安定稼働を確保し、障害発生時においては被害の最小化を図るとともに
継続的な改善、品質管理など、安全性と信頼性の高いサービスの提供を行う人を対象とした国家資格です。

### プロジェクトマネージャー
開発プロジェクトの責任者

プロジェクト全体の意思決定を実行し、品質・コスト・納期に全責任をもち
前提・制約条件の中でプロジェクトを確実に成功に導き
プロジェクトメンバを成長させるマネージャーを目指す方におすすめの国家資格です。
React Suspenseによって変わるデータ取得の世界観

## はじめに

待ちに待った(?) Suspense for Data FetchingがExperimentalとして先行公開されました。

<https://reactjs.org/docs/concurrent-mode-suspense.html>

`React.Suspense`自体は以前からあり、Data Fetchingについてはどういうものになるか憶測していたのですが、その憶測を上回る状態になって驚きつつ期待もしています。

本投稿では思ったことを雑多に書いていきます。

## Render-as-You-Fetch

React Suspenseは仕組み自体は簡単（promiseをthrowできるだけ）なのですが、それによってコーディングパターンは大きく変わります。それが[Render-as-You-Fetch](https://reactjs.org/docs/concurrent-mode-suspense.html#approach-3-render-as-you-fetch-using-suspense)というパターンで紹介されています。Suspenseを使う上で、必ずしもこのパターンに従う必要はないのですが、このパターンは様々なメリットがあります。

Suspenseを利用するメリットとしてよく言われるのは、loading stateをまとめて扱えることです。これは、シンプルかつ明確なメリットであり、UXを簡単に改善することができます。また、Render-as-You-Fetchでは、データ取得のタイミングが早いため、アプリによってはUXに影響する改善が見られるかもしれません。

一方で、Render-as-You-FetchではDX改善もされることが期待されます。

## もうuseEffectは使わない

React hooksが登場して、非同期処理特にデータ取得については、useEffectを使うことがベストプラクティスとして紹介されてきました。しかし、Suspense for Data Fetchingの登場により、それは過去の話になりそうです。Suspenseではデータ取得のためにuseEffectは使いません。

非同期処理にuseEffectを使うことは有効ではありますが、第二引数のdepsを正しく設定する必要があると言うのが悩ましい問題でありました。間違えると無限ループになったり、exhaustive-depsのルールに従う場合でも思い通りにならなかったりすることがありました。Suspenseではデータ取得はrenderの前に開始されるものであり、depsに頼ることはなくなります。useEffectの利用シーンはいわゆる副作用に限定され、より健全な形になるかもしれません。

## react hooksからのthrow promise

Suspenseに対応する文脈で、react hooksでデータ取得を開始して同時にthrow promiseする手法がありますが、これはRender-as-You-Fetchではありません。renderが開始してからデータ取得しているからです。その手法自体に問題があるわけではありませんが、本質的にはSuspenseのパワーを部分的にしか使えていない形になります。ただ、実際は多くのケースでは、renderはそこまで遅くないので、UXには影響しない可能性があります。React.lazyと併用する場合以外は、Render-as-You-FetchによるUXの恩恵は少ないかもしれません。

## Render-as-You-FetchによるDXのメリット

一言で言うと、fetchで取得したリモートデータとローカルのデータをほぼ区別することなくコーディングできるのです。コンポーネントのrenderにおいて、リモートデータがまだ取得中なのか取得済みなのかを区別する必要がなくなります。リモートデータは素直に外から与えられるpropsの一つになるか、内部で持つstateの一つになるだけです。

今までのデータ取得の考え方とは異なるので、全く新しいパターンとして認識する必要があります。

完全にシームレスにするにはProxyなどを使う必要があるのですが、そうでなくても、loading stateを無視できると言う点でリモートデータをローカルデータのように扱えるので、メリットがあります。

## 今後の展望

Render-as-You-Fetchは今後ベストプラクティスを確立していく段階だと思います。現状では、Relayが先行していますが、今後様々な提案がなされるのではないでしょうか。

私自身もこの新しいパターンに対応するライブラリを開発しています。

<https://github.com/dai-shi/react-suspense-fetch>

codesandboxで動作するリンクも用意していますので、興味ある方はいじってみてください。

## おわりに

Suspense for Data Fetchingが来ると分かっている中、React hooksでデータ取得をするためのライブラリ[react-hooks-async](https://github.com/dai-shi/react-hooks-async)を開発していたのですが、あまりの変わり様に驚いています。いい意味で。react-hooks-asyncの活用の場もないことはないのですが、やはり今後はSuspenseの可能性を探求していきたいと思います。