OmniAICreator/Qiita-1.07M huggingface dataset:
[Laravel × AWS Lambda] Brefを使って、サーバレスでLaravelを実行してみた！

## まえがき

こんにちは。
[bref](https://bref.sh/docs/)を使って、AWS LambdaでLaravelを実行してみました。

そこで、この記事では、brefの簡単な紹介をしつつ、主に「使ってみて感じたメリット」を書いています。
感想のみが気になる方は、この記事の[使ってみて感じたメリット](#使ってみて感じたメリット)だけ読んでもらえると。

## brefとは？

brefは、AWS Lambda上でPHPを実行するためのランタイムを提供するパッケージです。
紹介は公式を読んでもらった方が早いです。

https://bref.sh/docs/

> PHP サーバーレスを実行する場合:
> - サーバーをセットアップする必要はありません。クラウドプロバイダーがそれを処理します.
> - 使用した分だけお支払いいただきます。
> - アプリケーションは自動的にスケーリングします。

まんまサーバレスのメリットって感じですね。

ただ、bref特有のキモは下記です。

- LambdaでのPHPのランタイムを手軽に準備できる
- Laravel・Symfonyにもそれぞれ対応
    - Laravelの対応がかなり手厚い印象！

### どうやって使うの？

えー、この項目は公式通りにインストールしておけばOKです。
Laravelを用意して、下記のドキュメントの通りに実行すればOK。

https://bref.sh/docs/frameworks/laravel.html

サクッと動かしてみたいあなた！[サンプルのgit repo](https://github.com/h-kusaba-1001/bref-laravel-example)を用意しておいたので、よければ使ってみてください。
(Laravel 9.x

## 使ってみて感じたメリット

使ってみて、下記のメリットを感じました。

- HTTPに関わる処理の実装が楽！
- Laravelと他のAWSサービスの親和性が高く、組み合わせやすい！
- サーバレスそのものの料金が安い！

それぞれ詳しく書きます。

### HTTPに関わる処理の実装が楽

（筆者が使い慣れた）Laravelであれば、Lambdaエンドポイントを使用する場合の、HTTPの処理がスラスラ書けて良いのが第一印象でした。
例えば、JSON形式のレスポンスや、リクエストのバリデーションなど。

JSやPythonのランタイムでスクラッチで書くことよりも、何倍も楽に書けます。
また、Laravelを用いて、スクラッチではやりづらい複雑な処理が書きやすいのもメリットですね。

### Laravelと他のAWSサービスの親和性が高く、組み合わせやすい

Lambdaは単体で動かすことはあまりなく、他のAWSサービスと組み合わせて使うことが多いですよね？
Laravelを用いる場合、(準)公式ライブラリや外部ライブラリを用いて、Facadeなどで楽に複数のAWSサービスが使用できるので、親和性が高いと思いました。シナジー！

AWSサービスと、Laravel9.xのドキュメントや外部ライブラリのリンクを、知ってる限り書いてみました。

- Laravelの公式ドキュメントに記載されているもの (リンクは日本語版
    - S3
        - https://readouble.com/laravel/9.x/ja/filesystem.html
    - SES
        - https://readouble.com/laravel/9.x/ja/mail.html
    - SQS
        - https://readouble.com/laravel/9.x/ja/queues.html
    - DynamoDB ※キャッシュバックエンドとして利用
        - https://readouble.com/laravel/9.x/ja/cache.html
- 外部ライブラリ
    - DynamoDB ※DBとして利用
        - [baopham/laravel-dynamodb](https://github.com/baopham/laravel-dynamodb)
    - Cognito
        - [ellaisys/aws-cognito](https://github.com/ellaisys/aws-cognito)

他にあったら、コメントで教えてください～

こんな感じで、他のAWSサービスとの連携部分を、直接SDKを用いずに楽に書けるのが最高でした。
Lambdaエンドポイントを使わないケースにおいても、このあたりの親和性を考慮して、brefとLaravelで書いてみるのもアリだと思います。

### サーバレスそのものの料金が安い！

EC2を立てる場合と比較して、思ってたよりも安かった。。。（感想）
実際には、実行時間とリクエスト数、割り当てたメモリの量により変動するところですが。

気が向いたら、料金のシミュレーションの比較を書くかもです。

## 詰まりどころ

開発していて詰まったところが、2つありました。

### SESでメール送れないんだが？

`Mail`(Mailable)で、メールを送ろうとするも、謎のIAM認証のエラーが出る。
S3とかは使えているのになぜ...？

と思っていたら、[公式ドキュメントのS3の記述](https://bref.sh/docs/frameworks/laravel.html#file-storage-on-s3
)と同様に、`AWS_SESSION_TOKEN`を指定しなければいけなかった。

これは、Lambda実行時に、IAMロールを元に一時的なcredentialが環境変数にセットされるのですが、そちらのトークンがLaravel上で指定されていない状態になっていたため、発生した現象でした。
`config/services.php`の`ses`の部分に、`'token' => env('AWS_SESSION_TOKEN'),`を追加しておきましょう。

余談ですが、
公式に「ドキュメント追記しない？」って言ったら、「PR大歓迎だよ！」と言われたので、そのうちPRを書きます。ワクワク

https://github.com/brefphp/bref/issues/1324

### S3の署名付きURLを発行しようとすると、リンクが有効期限前に無効になるんだが？

こっちもbref関係なく、Lambdaの知識の話。
S3の署名付きURLを発行しようとしている方、是非読んでください。

https://qiita.com/hkusaba/items/ccebea4daa845ed64c22

## 最後に

そんな感じで、brefを用いてLambdaでLaravelを使ってみた結果、**簡単&便利&お安く** 開発できました。
個人的には、Lambdaエンドポイントを用いてHTTPで通信する場合、または、Lambdaで若干複雑めのバッチ処理を行う場合、次もbref使ってLaravelで書いてみよっかなーと思ってます。

みなさんも快適なbrefでLaravelライフを！
ネットギア GS305E のWeb管理画面を開くまでのメモ

## 概要
タイトル通り、ネットギア GS305E のWeb管理画面を開くまでのメモです。
大したことはないのですが謎に詰まったので忘備録として残します

## アクセス方法
結論としては下記の通り
* GS305EはデフォルトでDHCPでIPアドレスを自動設定します
* 本体裏面にMACアドレスが記載されたシールが貼られています
* ブラウザにてhttpで割り当てられたIPアドレスにアクセスすればWeb UIが開けます
* デフォルトパスワードは`password`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213714/c26643ac-dfca-ef81-85cb-1ae5f111356c.png)

* ログインすると新しいパスワードの設定を求められます。  
* その際のパスワードの要件が結構厳しいので注意  
    * パスワードは6～20文字の半角英数字で、大文字、小文字、数字をそれぞれ1文字以上使用する必要があります。また、次の記号を使用できます: !@#$%^&*()

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213714/c4831531-43a1-eab5-2219-e90a65b5dc99.png)


IPアドレスはルーターのdhcpリース割りて画面でmacアドレスを頼りに探します。

https://www.downloads.netgear.com/files/GDC/GS105EV2/WebManagedSwitches_UM_EN.pdf 18ページめあたりに乗ってます
DHCPサーバーなしでも設定はできるようです(詳細は上記マニュアル参照)


パスワード設定後に新しいパスワードでログインすると下記のような設定画面が開きます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213714/bba98825-d80b-0e40-8f56-d5651715c0cc.png)
UE5で個別のユーザごとにスクリーン上にエラーやワーニングを出力する

# はじめに  
この記事は[Unreal Engine (UE) Advent Calendar 2022の12日目](https://qiita.com/advent-calendar/2022/ue)の記事です
UnrealEngineは設定ファイルであるiniファイルで様々な設定をプロジェクトメンバー全員に共有することが出来る  
しかし、大規模で開発している際には自分にだけ有効な設定だったり、特定の職位の人物にだけ有効にしたい設定が出てきたりする

内容によってはコンソールコマンドで切り替えて貰ったりすることや、プログラマに独自に設定できる項目を追加できる方法もあるが今回はiniファイルで簡単に解決できる方法で解決する

今回は個別のユーザのスクリーン上にだけエラーやワーニングを出力する方法をまとめる

# 開発環境
UE5.0.3
Microsoft Visual Studio Community 2022 Version 17.2.6

# iniファイルとは

[コンフィギュレーション ファイル](https://docs.unrealengine.com/5.0/ja/configuration-files-in-unreal-engine/)

通常、UnrealEngineの設定を共通で変える場合は"DefaultEngine.ini"や"DefaultGame.ini"などのファイルを編集する
プロジェクト独自の設定を共有しようとするなら"UserGame.ini"がある
しかし、この方法ではEngineの設定を個別に書き換えることはできない
DefaultEngine.iniではプロジェクトデータをバージョン管理ツールで共有している全ユーザが共有することになる設定ファイルであるし、それを各員に編集させるのは操作ミスで誤った情報を書き換えてしまうリスクがある
バージョン管理ツールのignore機能で除外できる設定ファイルを使ってEngineの設定を書き換えたいがそれはどうすればいいのかというのが本題

# スクリーン上にエラーやワーニングを出力する方法

Config/DefaultEngine.iniに以下のように書き換えることで可能である

```
[/Script/Engine.Engine]
DurationOfErrorsAndWarningsOnHUD=3.0
```
※なお、ここ数字は１以上ならなんでもいい

DurationOfErrorsAndWarningsOnHUDはデフォルトではBaseEngine.iniで以下のように0が代入されており、自分から弄らない限りは有効になっていない

```
; This is the startup state of the OnScreenDebugMessage system
bEnableOnScreenDebugMessages=true
; This shows errors and warnings on screen
DurationOfErrorsAndWarningsOnHUD=0
```

しかし、これではこのプロジェクトデータを持っている全員にエラーやワーニングが出力されてしまうので想定と異なる挙動となってしまう

# How to

## 対象のユーザ以外の設定をDefaultEngine.iniに記述する
"Config/DefaultEngine.ini"に以下のように書き換える

```
[/Script/Engine.Engine]
bEnableOnScreenDebugMessages=False
DurationOfErrorsAndWarningsOnHUD=3.0
```

こうすることでDurationOfErrorsAndWarningsOnHUDが1以上になっているので、ワーニングとエラーがスクリーン上に出るようにはなってはいるが、bEnableOnScreenDebugMessagesでOFFにしていることになる
つまり、大多数の”対象ではないユーザ”には体験としては同一の状態となる

## DefaultEngine.iniより優先度の高いEngine.iniファイルを作成する
以下のPathでiniファイルを作成する

```
【ProjectDir】\Config\UserEngine.ini
```

## bEnableOnScreenDebugMessagesを書き換える
UserEngine.iniを以下のように追記する

```
[/Script/Engine.Engine]
bEnableOnScreenDebugMessages=True
```

こうすることでDefaultEngine.iniで書き換えた「DurationOfErrorsAndWarningsOnHUDが1以上になっているので、ワーニングとエラーがスクリーン上に出るようにはなってはいるが、bEnableOnScreenDebugMessagesでOFFにしている」という状態をさらに書き換えてスクリーン上にワーニングとエラーが出力されるようになる

## バージョン管理ツールでUserEngine.iniをignore
これは環境によるので詳細な方法は記述しない
gitやperforce、SVNでそれぞれ調べてほしい

## 結果
### テストコード
ワーニングを出力するために以下のようなテストコードを書いた
```c++
void ATestCharactor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	UE_LOG(LogTemp, Warning, TEXT("Warning!! from TestCharactor"));

}
```


### 実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/cb5111e1-0cb6-b74d-cd67-fcd7b3afdd0b.png)


# おわりに
今回の方法で任意の対象のユーザにのみUserEngine.iniをバージョン管理ツールの対象外にしたうえで編集してもらうことで安全にEngine設定を書き換える方法を紹介した
検索してもUserEngine.iniに言及している記事はあまり見当たらなかったし、DurationOfErrorsAndWarningsOnHUDやbEnableOnScreenDebugMessagesについても言及している記事は見当たらなかったので備忘録としてまとめた
App Serviceの管理

●App Serviceの管理
App Service作成後はWebアプリのコンテンツのアップロードなどを行う必要があり、自動スケールやデプロイスロット、カスタムドメインなどが使用可能なApp Seriviceプランを使用している場合は、App Serviceの管理に利用する機能を選択し構成する。

■デプロイセンター
App Service作成直後は、アプリケーションサーバーにはサンプルページだけが入っている状態。そのため、デプロイセンターのメニューを使用し、App Serviceで実行するWebアプリのコンテンツをアップロードする必要がある。

■デプロイスロット
Standard以上の価格レベルのApp Serviceプランであれば使用できる。
Webアプリの新バージョンの開発および確認とその公開をスムーズに行うための機能。準備が完了したらスワップという操作によってスロットの中身を入れ替え、ユーザーはダウンタイムなしで新バージョンのWEbあぷりを利用できる。
再度スワップを行うことで以前のWebアプリに戻すことができる。

■カスタムドメイン
既定のApp ServiceのFQDNは「AppService名.azurewebsites.net」となり、割り当てられるURLにもこのFQDNが使用される。
独自ドメインでアクセスしたい場合は、App Service作成後にカスタムドメインのメニューを使用して設定する。ただ、カスタムドメインを設定するには、Azure ADと同じ様にドメインの所有権の検証が必要。

※まだドメインを購入していない場合は、カスタムドメインの設定画面内の「App Serviceドメインの購入」をクリックし、独自のドメインを購入して使用巣ｒことも可能。

■スケールアップ・スケールダウン
仮想マシンと同様に、必要に応じてApp Serviceプランのサイズを変更できる。

■スケールアウト・スケールイン
仮想マシンスケールセットと同様に、必要に応じて内部的なインスタンス数を変更できる。

■バックアップ
Standard以上で使用可能。
復元に関しては、上書きによる復元もできるが、同じApp seviceの別スロットへの復元や、別のApp Serviceへの復元も可能。したがって既存の環境に影響を与えずに復元して内容を確認できる。

App Serviceのバックアップは、仮想マシンのバックアップとは異なる固有のバックアップ機能。
仮想マシンのバックアップはRecovery Servicesコンテナーに格納されるが、App Serviceのバックアップはストレージアカウント内のBLOBコンテナーに格納される。そのため、App Serviceのバックアップを行うにはストレージアカウントを作成しておく必要がある。
【UE5】Windows10にUnrealEngine5をインストールする

# 1.はじめに
どうも、ARIの名古屋支社に勤務している愛知県民こと、
新藏（にいくら）と申します♪
(/・ω・)/

私は以前、自作PCを作成した記事を載せましたが、
利用目的の1つとしてUnreal Engine 5（UE5）を使ってみたいというのがありました。

https://qiita.com/Aichi_Lover/items/2164f1c0385899bfe199

そこで**今回はWindows10にUE5をインストールする方法**について記事にしたいと思います！
UE5について勉強中の方の参考になれば幸いです。
(*^^)v

ちなみに、12月は**ARIのアドベントカレンダ**もやっていますので、
もしよろしければ、こちらも応援お願いします♪

https://qiita.com/advent-calendar/2022/ari-group

https://qiita.com/advent-calendar/2022/aichi_lover_yomoyama

# 2.用語の説明
## Unreal Engine 5とは

Unreal Engine 5（UE5）とは、ゲームを作成するためのソフトウェアの1つで、
**グラフィックがとてもきれい、プログラミングなしでゲーム作成ができる**
等々の特徴があります。

以下にUE5を利用して作られたデモムービへのリンクを記載します。

https://www.youtube.com/watch?v=_R-tN9l6onQ

# 3.前提条件

* PCが以下のサイトに記載のあるスペックを満たしていること

https://docs.unrealengine.com/5.0/ja/hardware-and-software-specifications-for-unreal-engine/

# 4.UE5のインストール
では早速、インストールしていきましょう！

4.1.以下のURLにアクセスし、「ランチャーをダウンロード」を選択します。

https://www.unrealengine.com/ja/download

|![010_ランチャーをダウンロードを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/182b2e4c-9bd1-2f41-c825-7be6a26b79b3.png)|
|:--|

4.2.ダウンロードしたランチャーを開きます。

|![020_開く.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/29d80aeb-edf8-4be6-0080-42d8205537eb.png)|
|:--|

4.3.サインインを求められるので、GoogleアカウントやPSアカウントでログインします。

4.4.「Unreal Engine」を選択します。

|![040_UNを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/c899a79b-fc7f-1e59-fdbe-1ae18e969678.png)|
|:--|

4.5.「エンジンのインストール」を選択します。

|![050_エンジンのインストールを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/c756002b-551b-a146-c247-0d864f09f274.png)|
|:--|

4.6.利用規約に同意します。

|![060_利用規約に同意.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/dd85d8cb-afb0-e36d-95fe-2e7cb2694e5d.png)|
|:--|

4.7.「インストール」を選択します。

:::note warn
以下の画像は5.0をインストールした際のキャプチャですが、2022/12/12現在の最新バージョンは5.1です。
:::

|![070_インストールを選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/cd8245b7-6fba-f71c-2454-ac7b78be7ad7.png)|
|:--|

4.8.インストール終了まで待機します。

:::note info
インストールには、120GBほどの容量が必要です。
:::

|![080_インストール終了まで待機.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/accd9779-4959-daf5-d596-c4300506b251.png)|
|:--|

4.9.インストールが完了すると「起動」ボタンが表示されるので選択します。

|![090_起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/df235a21-9f9c-153c-d183-7bd16a2fa353.png)|
|:--|

4.10.UE5が起動します。

|![100_起動後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372071/cf3ba468-a75c-954f-7ceb-5a730797a90a.png)|
|:--|


# 5.おわりに
ここまで読んで下さり、ありがとうございます！！！
(^^)

今回は初歩の初歩ということでインストール方法でしたが、
次回以降は使い方について少しずつ書いていこうと思います♪
(:3_ヽ)_

#### 次の記事、投稿しました♪
https://qiita.com/Aichi_Lover/items/94427a8b9338783abd7c
graphql-rubyアップデートで引っかかった点(1.8->1.12)

備忘録＋自分と同じくgraphql-rubyを上げないといけなくなった人への助けとして。

QiitaではGraphQLおよび、graphql-rubyを採用しています。
Ruby3.0へのアップデートの中で、graphql-rubyを最低でも1.11.7まで上げる必要があり、しばらくあげられていなかったgraqhql-rubyをエイヤッと上げることにしました。
その中で、[CHANGELOG](https://github.com/rmosolgo/graphql-ruby/blob/master/CHANGELOG.md#1117-18-january-2021)は一通り目を通して問題ないかは確認しましたが、コードを実際に書き換えた部分というのは限られています。

この記事ではどういうとこを書き換えたのかを簡易的にまとめていき、「こういうとこ影響あるかもしれないなと」いう修正の感所の参考にして貰えばと思います。

※以降サンプルコードが出てきますが、わかりやすくするために簡易にしたり、実際のプロダクトとは大きく実装が違う部分がありますがご了承ください。

## 1.8.2->1.8.15
特に書き変えが必要な変更はありませんでした。

## 1.8.15->1.9.21
- GraphQL::Schema::Objectを継承したクラスで、fieldのメソッド定義にobjectを呼びたい時`object`ではなく`itself`と定義するようになりました。

```diff_ruby
class Hoge < GraphQL::Schema::Object
+  field :items, [type_class], 'A list of items', null: false, method: :object
-  field :items, [type_class], 'A list of items', null: false, method: :itself
end
```

- GraphQL::Schema::Objectを継承したクラスのfieldの定義で、クラス内に定義したメソッドを使ってデータを呼び出す場合`method`ではなく`resolver_method`を使うようになりました。


```diff_ruby
class Hoge < GraphQL::Schema::Object
- field :fuga, String, null: false, method: :fugafuga
+ field :fuga, String, null: false, resolver_method: :fugafuga
  field :piyo, String, null: false
  
  def fugafuga
    #(略)
  end

  def piyo # 同じ名前なら field定義でmethodは不要
    #(略)
  end
end
```

## 1.9.21->1.10.12
- define_edge、define_connectionなどが廃止され、Class-based(原文ママ)に書き換えられるようになりました。
    - これにより、Ruby側でEdgeを書かずに省略していたのを定義するなどの変更が生じています。
- fieldの方で整数型を示すのがIntegerに統一されました。

```diff_ruby
-  class HogeConnection = HogeObject.define_connection do # 1.9以前はHogeEdgeをRuby上で作らなくてもよかった
-    name 'HogeConnection'
+  class HogeConnection < GraphQL::Types::Relay::BaseConnection
+    edge_type (HogeEdge)
-    field :totalCount, !types.Int, do
-      resolve -> (obj, _args, _context) do
-        obj.parent.length
-      end
-    end
+    field :total_count, Integer, null: false 

+    def total_count
+      obj.parent.length
+    end
   end
```

```diff_ruby
+ class HogeEdge < GraphQL::Types::Relay::BaseEdge
+   node_type HogeObject
+ end
```

## 1.10.12 -> 1.11.7
- mutationなどのfield定義でキャメルケースでfield名が書かれている場合、スネークケースに直す必要があります。

```diff_ruby
HogeMutation < GraphQL::Schema::RelayClassicMutation
  
    graphql_name 'Hoge'

-   argument :hogeId, String, required: true
+   argument :hoge_id, String, required: true
-   field :hogeFuga, String, null: false
+   field :hoge_fuga, String, null: false

  def resolve(**inputs)
    # (略)
  end
end
```

## 1.11.7 -> 1.12.16
- Qiitaのソースコードでは変更が必要な点はありませんでした。

## まとめ
今回はQiitaのgraphql-rubyのアップデートでこういうところを修正したよ、というのをまとめてみました。
graphql-rubyを採用しているrailsプロダクトは多く、ruby2.7のEOLが近づいてきたことで急遽上げないといけなくなるプロダクトも少なくはないと思うので、誰かの助けになればと思います。
また、Qiitaではたまたま対象になってないBreaking Changeは多々あるので、これを読んで満足するのではなく実際にCHANGELOGや気になる部分のソースコードを読んでみてください。

※もしCHANGELOGの誤訳などにより、間違いを書いていた場合優しく編集リクエストを送ってもらえると幸いです。
よくわからないけどChatGPTをVSCodeに入れてみる

# 概要
脳筋で入れてみる
## やってみる
>インストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/c69cc76e-13a5-1bdf-3e3b-708daea86c3a.png)

>なんかでてきた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/cc21bda3-b80b-d63a-20c3-3a58741b9726.png)

> *Please enter your token (__Secure-next-auth.session-token), this can be retrieved using the guide on the README.*
トークン (__Secure-next-auth.session-token) を入力してください。これは、**README のガイドを使用して取得できます。** 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/0669d1e9-352f-787c-8d6f-8d464b89b650.png)
間違えたら「Shift+Ctrl+P」から再設定できる（ChatGPT:ResetToken）

>README.mdを探すが、途中で以下の説明文を発見。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/6460d697-064f-7769-d055-42f88f409e2e.png)
Usage
To use the extension: This package requires a valid session token from ChatGPT to access it's unofficial REST API. Open the VS Code Command Palette and Type ChatGPT: Reset token, this will prompt you for your session token.
To get a session token:
Go to https:\//chat.openai.com/chat and log in or sign up.
Open dev tools.
Open Application > Cookies (Storage > Cookies on FireFox)
使用法
拡張機能を使用するには: このパッケージは、非公式の REST API にアクセスするために、ChatGPT からの有効なセッション トークンを必要とします。 
VS Code コマンド パレットを開き、「ChatGPT: リセット トークン」と入力します。
これにより、セッション トークンの入力が求められます。
セッション トークンを取得するには:
https://chat.openai.com/chat にアクセスして、ログインまたはサインアップします。
開発ツールを開きます。
アプリケーションを開く > Cookie (ストレージ > FireFox の Cookie)

というわけで、サインアップ（アカウントの作成）し、F12でクッキー☆確認
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/a09c665a-d55c-396e-d5c9-bd3ab63e508e.png)

赤枠の部分をコピーしてさっきのとこに入力したあとVSCode再起動してもっかいChatGPT起動

・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/6a403671-5bc4-fb08-c5d7-b6bb854fef22.png)

できたー！
ついでになんか聞いてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154400/5b82ae9d-fcbf-c3dd-f1a4-fbd0478dc131.png)

めっちゃ重かった
完
firebase login     Firebase CLI v11.16.0 is incompatible with Node.js v16.0.0 Please upgrade Node.js to version ^14.18.0 || >=16.4.0

# ［エラー］firebase login( Firebase CLI v11.16.0 is incompatible with Node.js v16.0.0 Please upgrade Node.js to version ^14.18.0 || >=16.4.0)

## 環境
MacBook Air (M1, 2020)
nodeバージョン　v16.00


## ぶつかったエラー
```
Firebase CLI v11.16.0 is incompatible with Node.js v16.0.0 Please upgrade Node.js to version ^14.18.0 || >=16.4.0
```
日本語訳
Firebase CLI v11.16.0 は Node.js v16.0.0 と互換性がありません Node.js をバージョン ^14.18.0 にアップグレードしてください
( Firebase CLIにnode.jsのバージョンを合わせる必要があるようです)



## やったこと
1. エラーメッセージをgoogle翻訳する。
1. ダウンロード可能なバージョンを確認（nodebrew ls-remote）
1. 希望のバージョンをインストール（nodebrew install-binary v14.18.0）
1. 使用可能なバージョンを確認（nodebrew ls）
1. 希望のバージョンに変更する（nodebrew use v14.18.0）
1. 確認する（node -v）


## 解説

#### 1.ダウンロード可能なバージョンを確認
コマンド　nodebrew ls-remoteを入力
```
~~~~~~省略
v14.14.0  v14.15.0  v14.15.1  v14.15.2  v14.15.3  v14.15.4  v14.15.5  v14.16.0
v14.16.1  v14.17.0  v14.17.1  v14.17.2  v14.17.3  v14.17.4  v14.17.5  v14.17.6
v14.18.0  v14.18.1  v14.18.2  v14.18.3  v14.19.0  v14.19.1  v14.19.2  v14.19.3
v14.20.0  v14.20.1  v14.21.0  v14.21.1  

v15.0.0   v15.0.1   v15.1.0   v15.2.0   v15.2.1   v15.3.0   v15.4.0   v15.5.0
v15.5.1   v15.6.0   v15.7.0   v15.8.0   v15.9.0   v15.10.0  v15.11.0  v15.12.0
v15.13.0  

v16.0.0   v16.1.0   v16.2.0   v16.3.0   v16.4.0   v16.4.1   v16.4.2   v16.5.0
v16.6.0   v16.6.1   v16.6.2   v16.7.0   v16.8.0   v16.9.0   v16.9.1   v16.10.0
v16.11.0  v16.11.1  v16.12.0  v16.13.0  v16.13.1  v16.13.2  v16.14.0  v16.14.1
v16.14.2  v16.15.0  v16.15.1  v16.16.0  v16.17.0  v16.17.1  v16.18.0  v16.18.1


v17.0.0   v17.0.1   v17.1.0   v17.2.0   v17.3.0   v17.3.1   v17.4.0   v17.5.0
v17.6.0   v17.7.0   v17.7.1   v17.7.2   v17.8.0   v17.9.0   v17.9.1   

v18.0.0   v18.1.0   v18.2.0   v18.3.0   v18.4.0   v18.5.0   v18.6.0   v18.7.0
v18.8.0   v18.9.0   v18.9.1   v18.10.0  v18.11.0  v18.12.0  v18.12.1  

v19.0.0   v19.0.1   
~~~省略
```

#### 2.希望のバージョンをインストール
nodebrew install-binary v14.18.0
今回はv14.18.0を入力
```
######################################################################### 100.0%
Installed successfully
```
と表示されたらOK


#### 3.使用可能なバージョンを確認
nodebrew ls と入力
```
v14.18.0
v16.0.0
v18.10.0
v18.11.0
v18.12.0
v18.12.1
v19.0.0

current: v19.0.0
```
さっきインストールした　v14.18.0が確認できる
current: v19.0.0は現在使用してるバージョンなので切り替える必要がある


#### 4.希望のバージョンに変更する
nodebrew use v14.18.0と入力
use v14.18.0と表示されたらOK



#### 5.確認する 
先程と同じように　　nodebrew ls　入力
```
v14.18.0
v16.0.0
v18.10.0
v18.11.0
v18.12.0
v18.12.1
v19.0.0

current: v14.18.0
```
v14.18.0が変更できfirebase loginできました。
Python: ラムダ式で yield を使う

まずは普通のyieldの簡単な使いかたです。

```py:
>>> def g():
    yield 0
    yield 1
    return

>>> a = g()
>>> next(a)
0
>>> next(a)
1
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
```
こんな風にするとラムダ式でも yield できます。

```py:
>>> g = lambda : (
    (yield 0)
    , (yield 1)
    )
>>> a = g()
>>> next(a)
0
>>> next(a)
1
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration: (None, None)
```
```yield from``` も使えます。

```py:
>>> g = lambda : (yield from [0,1])
>>> a = g()
>>> next(a)
0
>>> next(a)
1
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
```
ループは使えないので再帰などを使って工夫する必要があります。カウンタの例。

```py:
>>> count = lambda n : (
    (yield n)
    , (yield from count(n+1))
    )
>>> a = count(1)
>>> next(a)
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
4
``` 
いたずらに変わった書き方をする必要はありませんが、主に他言語との連携、他言語からの類推でラムダ式をもっと有効に使いたいという潜在需要はあると思います。自己責任でお使いください。
名前や住所とかまとめてコピーして、順番にペーストしたい。

# はじめに
名前とか住所とかを、Webサービスに入力するのって意外と面倒じゃないですか。
まぁ、最近はオートコンプリートとかありますけどね。

お仕事とかでそういう「Webサービスに入力する」お仕事をしている方って結構いると思うんですよ。
お客さんからもらった別のファイルに入力する（入力しなければならない）情報が載っていて、
それをサービス側に入力していくという仕事ってまぁ少なからずあると思います。
（データ入力系のお仕事とかね）

でも、
Excelのレコードを1つずつコピーして、ペースト
という行為を入力項目ごとにやらなければならないわけです。

ましてや、電話番号なんて
080-XXXX-XXXX
っていう文字列を一気に流し込めるイケイケサービスならいいと思うんですが
080
XXXX
XXXX
みたいにフォーム分かれてるファ○キンサービスの場合ってエクスペリエンス最悪じゃないですか。
1項目なのに3項目分入力作業を繰り返さないといけない。
あぁこれはもう最悪です。

LIGさんが作ってくれているこういうフォームです。（アンチパターン集）
マジで最悪のエクスペリエンスです。（褒め言葉）
標準だとペーストもできません。

https://efo.showcase-tv.com/challenge/

なので、こういうフォームに対する解決策の一つとして
コピーは1回、ペーストをバシバシすればフォームに一気に入力できるアプリを作りました。


あ、LIGさんの本編のページもよろしくね

https://liginc.co.jp/555599

# リポジトリ

https://github.com/segfo/multiline_paster

# 使い方
まずこういうテキストファイルを用意します

```
田中
太郎
タナカ
タロウ
tanaka
tarou
foobar
subdomain1.example.com
foobar
subdomain1.example.com
hogehoge
subdomain2.example.com
hogehoge
subdomain2.example.com
```

LIGさんの作った使いづらいフォームは「ペースト禁止」処理が入っているので、以下のプラグインで無効化します。

https://chrome.google.com/webstore/detail/absolute-enable-right-cli/jdocbkpgdakpekjlhemmfcncgdjeiika


このプラグインでペースト機能が使えるようになったら以下の手順でペチペチしていきます

1. アプリをビルドして立ち上げます。
1. 作ったテキストをまるっとコピーします
1. ペチペチペーストしていきます。

こういう感じ

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/78de48c0-d307-35c8-53f9-b724aa10c83b.gif)

# まとめ
このようなUIが存在する現実は変えることのできない現実である。
だけど、そんなことをイチ利用者が言ったところで改善されることはない。
なので技術で殴って面倒くさい作業は楽になる方面で解決していこうと思う。

おわり。
Yamaha RTX1220 からL2MS機能で配下のSWX2110-5Gを制御する

## 概要
調子に乗ってYamahaのL2スイッチであるSWX2110-5Gを購入しました。
ヤマハ独自の機能であるL2MS機能を使用して管理をされる前提のスイッチで、RTX1220をL2MSのマネージャー(親機？)として動作させ、RTXからSWX2110の管理設定を行えます。

今回はL2MSをRTX側でも有効にし、RTXのWeb UIからSWX2110のVLAN設定を実施します。(スイッチ側でRTXと接続する以外設定は必要ありませんでした)

https://network.yamaha.com/products/switches/swx2110-5g/index

## 設定
下記コマンドでLAN1インターフェースでL2MSマネージャーを有効にします。
```
rtx1220# switch control use lan1 on
rtx1220# save
```
https://network.yamaha.com/setting/router_firewall/switch_control/switch_swx-command/search_info

## web UIへのログイン・VLAN設定
`http://<lan側に設定したIPアドレス>/` をブラウザのアドレス欄に入力し、Web UIへアクセスします。
ログインのダイアログが表示されるので、ssh接続のときに使用するのと同じユーザー名/パスワードをログインし

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213714/6bbf9bb3-7582-eed0-46b6-5dcd127af9e3.png)

LANマップ > タグVLAN からL2MSを利用したタグVLANの設定画面を開きます。
特に説明はありませんが、どうもRTX1220との接続に使用されているポートが`↑`のマークで表されるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213714/d2059dfc-bb5e-a15f-1f61-5c6413fd40ed.png)

この画面にて各VLANの「参加ポート選択」からVLANの割当ができます。
触って見た感じ、以下のような挙動をするようです
* RTX1220と接続するポート(この場合は５番ポート)はタグVLANポートとして設定できる
    * Native VLANは勝手に合わせてくれる
    * ダウンリンク側で任意のVLANを設定すると、自動的にタグVLANが設定されるようです
* ~~ダウンリング側のポートはアクセスVLANしか使えないようです~~ 「マップ」の画面からであればトランクポートの設定が行えました
    * VLAN320を割り当てた後にVLAN160を割り当てるとVLAN160のアクセスポートとして設定されました
一人エンジニアからCTOになって気付かされたこと

この記事は [Qiita x 日本CTO協会共催！あなたの自己変革について語ろう！ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-ctoa) の15日目です。

https://qiita.com/advent-calendar/2022/qiita-ctoa

# 自己紹介
株式会社YOLO JAPANのCTOをしています田端と申します。
日本CTO協会（以下、CTO協会）ではコミュニティーWGとエンジニア育成WGでコントリビュータをしています。

2021年9月にCTO協会に個人会員として入会し、同12月にコントリビューターとしてCTO協会を盛り上げるためにお手伝いをしています。

今回は、CTOになってから気付かされたことを書いていきたいと思います。


## CTO協会の4つのバリュー
```
Give First / あなたの当たり前は誰かの学び
Think Big, Start Small / 大きく考え、小さく一歩目を踏み出す
Fail Fast, Learn Fast / 早く失敗し、早く学ぶ
Always Day One / 常に初日の気持ちでいる
```


# CTOになるまで
20歳からWEB業界でエンジニアとして働き、最初こそ先輩エンジニアがいましたがリーマンショックなどがあり20代後半からは1人エンジニアとして様々なサービス開発をしてきました。
スキルは前半で伸ばすことはできましたが、それ以後のマネジメントなどを学ぶことはなく（先輩や部下もできず）1人で開発を進めておりました。
正しい開発手法とは何か？などはネットで漁っていましたが、ある研修をきっかけに「本当にこのままでいいのか？40歳になった時、定年になった時、自分はどう働いていて何を残せているのだろうか？」を考えると不安で眠れない日々が続きました。
その時に、現在の代表と共通の知り合いから「YOLO JAPANという日本に住む外国人向けのサービスを作りたいけどエンジニアを探している」というオファーから開発を受けることにしました。
代表とは、様々なお話をすることで、これからどうなっていくのか。何をやっていきたいのか。などの熱い想いを聞きながら、自分の現在不安に思っている部分を打ち明けることによって「これから変えてやる！」との言葉で転職を決意しました。

元々英会話スクールの会社でしたのでエンジニアはいませんでしたが、私が転職するまでの間にエンジニアを1人採用し、私が転職してからは2人で開発を進めました。
入った当初より開発リーダーとしてプロダクト開発をリードし、翌年取締役 CTOとして就任しました。


# CTOになって気付かされたこと
1人エンジニアからCTOというポジションになったが、CTOは何をするのか？どういう立ち振る舞いをすればいいのか？はわからなかったため手探りで色々とやっていました。
が、まずはプロダクト開発を進めるという認識で今までと変わらずコーディングをバリバリ書いて開発をしていました。

人を増やそうという時期になりエンジニア面接で、私は大きな間違いをしました。

エンジニア面接する時は、下記のことを見ていくと思います。
* 今のプロダクトを伸ばせるほどスキルがあるのか？
* 会社や自分との相性がいいのか？


## どこを間違ってしまったのか
私は1人エンジニアから1人の部下を持つCTOになりました。
今まで自分より上の人を採用する事はない、自分が一番上という独占状態のポジションにいました。
そうです。プライドが邪魔したのです。

なので、面接をして `自分との相性` が良い人は僕のスキルを超えない人を選んでいたのです。
CTOというポジションなので舐められたくない！という恐怖心があったのです。

それに気付いた代表から
「CTOの上限がそこならこれから伸びる事はない。凄いやつを入れて自分の上限を上げるために成長しないでどうする！それができないなら考え直す」
と言われ思いっきり殴られたほどの衝撃を受けました。

私を信頼してCTOというポジションを任せると言ってくれたのに、私は成長するというより現状の自分を守ろうとしていたのです。
`自分より上 = ポジション交代`
という勝手な方程式を作り上げていました。


# Always Day One / 常に初日の気持ちでいる
自分の中の固定概念を壊した事により、世界が大きく変わったと思っています。
知らないことを知るという`無知の知` を知ることが一番大切だと学びました。

**自分より凄い人は多くいます。**

自分より優れている人から学べることは全て学べば自分はさらに成長できると感じています。
全て超えていなければいけないという事はありません。
どうすれば個々の力を最大限引き延ばせるのか？がCTOの役目だと思います。
チームや会社で化学反応を起こして、レベルアップさせていけばいいのです。
ゲームで例えると、どうすれば次のボスを倒すことができるのか？を考えれば自ずと必要な知識や人員を見つけることができます。


# さいごに
CTO協会に入ってから、多くのCTOから学ばせてもらっています。
今回は「**Give First / あなたの当たり前は誰かの学び**」 と 「**Always Day One / 常に初日の気持ちでいる**」 を併せて書かせていただきました。
そんなの当たり前と思いながら読んでいただいた人もいるかもしれません。
でもこうやってアウトプットする事により、同じように悩んでいる人に少しでも届けば幸いです。

CTO協会にも、同じように悩んでいる人がたくさんいます！
様々なステージで悩みは変わりますが一つでもみなさんの解決に繋がる情報を提供できるように活動してまいります！

最後までお読みいただきありがとうございます。
マジシャンズチョイスに引っかからない為に

### はじめに
スマートコントラクトの優位性として、コードが公開されていて誰もが検証できるということがあります。そしてそのコードが改変されないということも大きな利点として語られます。
自分にとってはここは本当に重要な点であり、また、自分がProxyパターンを利用した実装が好きではない理由のひとつでもあります。

そんなスマートコントラクトも正しい知識がなければ「見えるからこそ騙される」可能性があります。
マジシャンは相手が見えるということを利用しながらトリックを使い相手の視線や思考をコントロールします。
見えるからこそ信じてしまう。
その裏にあるトリックに騙される。
ある意味では、中途半端な知識がある人ほど騙しやすいとも言えるわけで、技術者としてはしっかりとした知識をつけていくことが大事ですよねというお話。

### サンプルコントラクト
テストネットにコントラクトをひとつデプロイしました。
https://goerli.etherscan.io/address/0x5ea9b66e3b2b400a4d8990b9f19326329ea0b758#code

```
contract Main {
    SubA a;

    constructor(address _a) {
        a = SubA(_a);
    }

    function callSubA() public view returns (string memory){
        return a.check();
    }

    function setOwner(uint256 tokenId) public {
        a.setOwner(msg.sender,tokenId);
    }
}

contract SubA {
    mapping(uint256=>address) public owners;

    function check() public pure returns (string memory){
        return "SubA was called";
    }

    function setOwner(address owner, uint256 tokenId) public {
        require(owners[tokenId] == address(0));
        owners[tokenId] = owner;
    }

}
```
MainコントラクトとSubAコントラクトがあり、MainコントラクトにはcallSubA()とsetOwner()という二つのpublic関数があります。

仮にcallSubA()を呼び出した場合、どういう文字列が返ってくるでしょうか。
callSubAはSubAのcheck()を呼びだしていますから、パっと見では"SubA was called"が返ってくるように見えます。
```
    function check() public pure returns (string memory){
        return "SubA was called";
    }
```

しかし、実際にEtherscanで呼びだすと、"HiddenA was called"という文字列が返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3048580/e3eb2d19-7c31-e22d-ad81-b74f2e81bb0f.png)
Verifyが通っているコードのどこを見ても"HiddenA"などという文字列はどこにもありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3048580/25bc8ced-df9c-0abc-7da0-f9bc157cb229.png)

setOwner関数はどうでしょう。
パッと見ではアドレス型のownerと、uint256のtokenIdが渡され、既に登録されていないtokenIdであれば呼び出し元アドレスがownerとしてmappingに登録される。
一度登録されたものについては、誰も更新できなくなる。
このように見えると思います。

しかし、実際にsetOwnerを呼び出してみると、何度でも好きなように更新ができます。
実際の実装としては何の制限もかかっていません。


今回のサンプルは初歩的なコード隠蔽を使っているので、少し知識がある人なら「あ～ やっとんな」と見破ることができると思いますが、人によっては混乱をするでしょう。
コードが見えており、かつ一定の知識があるからこその混乱です。

見えているコードには存在しない文字列が返ってくる。
requireが設定されているはずなのに制限されない。
これらはSolidityの仕組みをしっかりと理解しておかなければ意味がわからない動きとなってしまいます。

### 悪意のあるコードから非エンジニアを守るのも技術者としての大事な役割
今回のようなシンプルなものだけでなく、より複雑にした隠蔽や偽装はいくらでも考えることができます。
バックドアやラグプルの仕組みとしてひっそりと実装される可能性があるものです。
ライブラリーやプロトコルをうまく利用することも大事ですが、よりコアに近い部分の知識をしっかりと学んでおくことはとても大事だと思います。

「見えているからこそ騙される」ということはあるわけで、ともに切磋琢磨しながら知識を積み重ね、マジシャンズチョイスに引っかからない技術者、非エンジニアを守ることができる技術者になっていければいいなと思います。
【JS】配列内の要素を順番を逆にして並べ替える【ワンパン】

## やりたいこと
タイトルのとおりです。
以下のような配列を順番を逆にして入れ直します。

```js
var member = ['前田','堂安','遠藤','吉田','権田'];
```


## reverse()メソッドを使う
reverseメソッドは配列を逆転させてくれます。

```js
member.reverse();

console.log(member); //['権田','吉田','遠藤','堂安','前田']
```

注意点として、reverseメソッドはもとの配列そのものを加工しています。
なので、表示するときだけなど、一時的に逆にしたい場合は新たに別の配列を用意してreverseする、

もしくは、以下のようにするといいでしょう。


```js
var member = ['前田','堂安','遠藤','吉田','権田'];

console.log(member.slice().reverse()); // ['権田', '吉田', '遠藤', '堂安', '前田']
console.log([...member].reverse());    // ['権田', '吉田', '遠藤', '堂安', '前田']

//もとの配列はそのまま
console.log(member);                   // ['前田', '堂安', '遠藤', '吉田', '権田']
```
UdemyでPython関連講座を年間100時間以上視聴した私がおススメするPython講座

## はじめに
エンジニアでもない文系卒の超初心者ですがUdemyでPythonを勉強し倒しました。

１年前はPythonについて何も知らなかった自分が、いくつか資格も取れて、基本的なコードであれば業務でも使えるようになれましたので、感謝の意も込めて記事を書こうと思い立ちました。

Pythonでできることはたくさんあるのですが、

・データ分析・機械学習
・業務改善

上記領域についての個人的おススメ講座をご紹介したいと思います！

## データ分析・機械学習部門
https://www.udemy.com/course/kikagaku_blackbox_1/

**一度Pythonに挫折した人におすすめです**
難しい数式ありきではなく、ざっくりとPythonや機械学習について把握できることを目的としていて、**初心者が脱落しないように**という工夫が感じられる講座です。

https://www.udemy.com/course/python-data/

**アニメーションでまずは楽しく学習したいという人におすすめです**
**ウマたんさんのアニメーションが大変わかりやすい**のと、声が聞きやすく学習がしやすいです。youtubeにも楽しい動画をあげてくださっているので、そちらもぜひ見てみてください。

https://www.udemy.com/course/python-python3/

**初心者向けPython講座を探している人におすすめです**
**Pythonの基本構文がこれで網羅的に勉強**できて、満足いく１本です。
我妻さんの講座はこれ以外にもたくさんありますしどれも評価が高いので、興味のあるものをぜひ探してみてください。

## 業務改善部門
https://www.udemy.com/course/python-kaizen/

**EXcelやPDFをPythonで扱って自動化できるようになりたい人におすすめ**
実は意外と、Pythonで業務効率化を教えてくれる講座は少ないです。
この講座では、実務でありえるようなケースを想定して、コードを実際に打ち込んで教えていただけるのでまずは何かPythonで業務効率化してみたいと思われた方は必見です。


https://www.udemy.com/course/python-kaizen-advanced/

**メール送信の自動化や簡単なアプリ作成がしたい人におすすめ**
基礎編の続きの講座です。エクセル以外の業務効率化について教えてくださいます。


## ３つの勉強の心得
さいごに、私のUdemyでの勉強心得を３つご紹介します

・**動画をはじめから順番に見ようとしない**
せっかく動画になっているので、１から全部見る必要はないです！
全部理解しようとはせず、ざっくりと理解をまずはしていきましょう。
「面白そうだからここを先に見よう」という自分を飽きさせない工夫が重要です。

・**自分に合った講座を選ぶ**
時間が長い講座、評価がいい講座だけがいいとは限りません。
いくつか試してみて、まずは自分に合う勉強スタイルを見つけましょう。

・**隙間時間の耳学習を活用**
寝る前と通勤時間の耳学習を活用しまくりました。
隙間時間で勉強をすすめられると効率的ですよね。


最後までお読みいただきましてありがとうございました。
１つでも皆様のお役に立つ情報があったなら幸いです！
Lombokの内容整理①

## 目的
- ずっとなんとなく使っていたので、改めてこのタイミングで整理

## Lombokとは
- アノテーションをつけることでコンパイル時にコードを自動生成してくれるライブラリのこと
- 今回扱うアノテーション一覧
   - [<span>@</span>Getter/<span>@</span>Setter](#<span>@</span>Getter/<span>@</span>Setter)
   - [<span>@</span>ToString](#<span>@</span>ToString)
   - [<span>@</span>EqualsAndHashCode](#<span>@</span>EqualsAndHashCode)
## <span>@</span>Getter/<span>@</span>Setter
##### 概要
- アクセサメソッドを自動生成
##### 使い方
```java:Person
@Getter
@Setter
public class Person {
  private String name;
}
```
```java:コンパイル時に自動生成されるコード
public class Person {
  private String name;

  @Generated
  public String getName() {
    return this.name;
  }

  @Generated
  public void setName(final String name) {
    this.name = name;
  }
```
##### 指定場所 / 用途
- クラス・フィールドに指定可能
- フィールド変数にアクセスする場合に設定
## <span>@</span>ToString
##### 概要
- すべてのフィールドを1つの文字列表現に変換するtoStringメソッドを自動生成
##### 使い方
```java:Person
@ToString
public class Person {
  private String name;
}
```
```java:コンパイル時に自動生成されるコード
public class Person {
  private String name;

  @Generated
  public String toString() {
    return "Person(name=" + this.name + ")";
  }
```
##### 指定場所 / 用途
- クラスに指定
- ログ出力などで使用
## <span>@</span>EqualsAndHashCode
##### 概要
- すべてのフィールドを使用してequalsメソッドとhashCodeメソッドを自動生成
- equalsメソッドとは
     - Stringの場合：同じ文字列かどうかの比較を行う
     - Objectの場合：オブジェクトが同一かどうかの比較を行う
- hashCodeメソッドとは
     - 呼び出し元のオブジェクトをハッシュコードと呼ばれるint型の値に変換し、戻り値として返す
     - ※ハッシュコードとはオブジェクトにつけられる一つの整数値で、オブジェクトの一意の識別などに用いられる値
##### 使い方
```java:Person
@EqualsAndHashCode
public class Person {
  private String name;
}
```
```java:コンパイル時に自動生成されるコード
public class Person {
  private String name;

  public Person() {
  }

  @Generated
  public boolean equals(final Object o) {
    if (o == this) {
      return true;
    } else if (!(o instanceof Person)) {
      return false;
    } else {
      Person other = (Person)o;
      if (!other.canEqual(this)) {
        return false;
      } else {
        Object this$name = this.name;
        Object other$name = other.name;
        if (this$name == null) {
          if (other$name != null) {
            return false;
          }
        } else if (!this$name.equals(other$name)) {
          return false;
        }

        return true;
      }
    }
  }

  @Generated
  protected boolean canEqual(final Object other) {
    return other instanceof Person;
  }

  @Generated
  public int hashCode() {
    int PRIME = true;
    int result = 1;
    Object $name = this.name;
    int result = result * 59 + ($name == null ? 43 : $name.hashCode());
    return result;
  }
}
```
##### 用途
- インスタンスの一致確認が必要な場合に設定
Javaの比較いろいろ

## Javaでの比較

Javaの比較でよく使われるのは下記3つ。
- `==`演算子
- `equals`メソッド
- `instansof` 演算子

## `==`演算子について
javaの世界にはプリミティブ型と参照型が存在します。プリミティブ型の値を作ると直接メモリに値が書き込まれます。プリミティブ型には`int`や`boolean`が存在します。`==`はJavaのプリミティブ型の比較を行う時に使用します。

``` java
int a = 10;
int b = 10;
int c = 20;

System.out.println(a == b); //true
System.out.println(a == c); //false
```

また、Javaにはenumと呼ばれる列挙型があります。enumはクラスのように扱えますが、他のクラスでインスタンス化できず、enum内部で1度きりのみインスタンス化できます。つまりenumのインスタンスは、プログラムの中で一つということが保証されます。なのでenumも`==`比較を行うことができます。`==`はnullセーフなこと、enumの比較で型が違う時にコンパイルエラーで気づけることから、enumの比較では`==`を使用することが推奨されています。

``` java
public enum WEEK {
    SUNDAY("日曜日"),
    MONDAY("月曜日"),
    TUESDAY("火曜日"),
    WEDNESDAY("水曜日"),
    THURSDAY("木曜日"),
    FRIDAY("金曜日"),
    SATURDAY("土曜日");

    private String name; // フィールドの定義

    private WEEK(String name) { // コンストラクタの定義
      this.name = name;
    }
}
```

``` java
Week week = Week.SUNDAY;

System.out.println(week == Week.SUNDAY); //true
System.out.println(week == Week.SATURDAY); //false
```

## equalsメソッドについて
equalsメソッドは文字列やオブジェクトなど参照型の比較の時に使用します。
なぜ文字列やオブジェクトの比較で`==`を使ったらダメなのでしょうか？
答えは文字列やオブジェクトの比較で`==`を使用すると参照型変数が同じインスタンスを参照しているかどうかを判定(`等値判定`)してしまうからです。Javaで用意されている参照型のequalsメソッドを使用した場合は、参照先インスタンスの内容が一致するかどうか（`等価判定`）を判定します。

``` java
List<String> test1 = Arrays.asList("a","b","c");
List<String> test2 = Arrays.asList("a","b","c");

System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
```

equalsを使う上での注意点は２つあります。
１つ目はnull安全でないことです。下記のように左辺にnullが入っていた場合は`NullPointerException`が発生してしまいます。

``` java
String a = null;
String b = "test";

System.out.println(a.equals(b)); // NullPointerException
```

２つ目は、Objectクラスに定義されているequalsメソッドは、以下のように自身のオブジェクト(this)と、引数に渡された参照先のオブジェクトの等値判定のみが行われています。
``` java
public boolean equals(Object obj){
       return(this == obj);
}
```

なので自分たちが定義してあげたクラスのオブジェクトで等価判定をしたい場合は`equalsメソッドをオーバーライドしてあげる`必要があります。

``` java
public class Person{
  String name;

  // コンストラクタ
  public Person(String name) {
    this.name = name;
  }

  @Override
  public boolean equals(Object obj) {
    // Personにキャストして、nameの値が同じか調べる
    return name.equals(((Person)obj).name);
  }
}
```

``` java
Person test1 = new Person("test");
Person test2 = new Person("test");

System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
```

最後に余談ですが、Lombokでは`@EqualsAndHashCode`というアノテーションが用意されており、equalsメソッドを自動でオーバーライドしてくれて、`等価判定`を行えます。

``` java
@EqualsAndHashCode
public class Person{
  String name;

  // コンストラクタ
  public Person(String name) {
    this.name = name;
  }
}
```
``` java
Person test1 = new Person("test");
Person test2 = new Person("test");

System.out.println(test1 == test2); // false
System.out.println(test1.equals(test2)); // true
```

## instansof　演算子について
12.12記載予定
2回目のエンジニア転職後、現場でどのようなレビューをしてもらっているか。

## はじめに
:::note info
この記事は[🎅GMOペパボエンジニア Advent Calendar 2022](https://adventar.org/calendars/7722) **12日目**の記事です。
さまざまなエンジニアのメンバーが楽しい記事を書いているので、ぜひご覧ください。
:::

初めまして。ほりゆうと申します。
<img width="100px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557847/16fcd2a8-775a-0abd-31da-f265fcca344b.png">
2022年の7月に物流企業からGMOペパボ株式会社に転職したエンジニアです。前職ではLaravelやSalesforceを用いて倉庫を管理するSaaSを開発しておりました。現在は[SUZURI](https://suzuri.jp/)というオリジナルグッズ・アイテムの作成・販売ができるWebアプリケーションの開発をしております。

以前から憧れだった会社・メンバーの皆様と一緒にこうしてAdvent Calendarに参加できていて光栄です。ついこの前までは志望者としてみなさんの記事を読んでいました。この記事が、そんな誰かのためになれば幸いです。

本記事では、転職前に自分が気になっていた**コードレビュー**についてまとめたいと思います。

前職もとても良い環境でしたが、コードレビューの機会は少なかったので、研修や現職でどんな感じでコードレビューしていただいているのか、よくレビューをいただくポイントや印象に残っているもの、またレビューしてもらう立場としてどう準備しておくとよいかについてまとめたいと思います。

## レビュー内容
印象に残っているレビュー内容で共有できるものをまとめました。

### 🎁 論理演算子系

```diff: レビュー中のコード例(Ruby)
- if hoge
-    raise ActiveRecord::RecordNotFound if hoge != fuga
- end


+ raise ActiveRecord::RecordNotFound if hoge && hoge != fuga 
```

論理演算子は特に短く書く方法や、条件の評価順によって書かなくていいものなどのアドバイスをいただきました。


### 🎅 意味の多様性

```
◯◯◯という言葉には、◯◯◯という意味と●●●という意味があるので、より正しい意味が伝わるようにしましょう。
```
実装しているコードのテストや、ユーザーが利用する画面に出力されている文字などに関して、自分が受け取ってほしい意味とは別の意味に取られかねない表現を指摘していただくことがありました。

言葉に関しては、すでに実装段階でPMやディレクターの皆さんとお話しして決まっているものがほとんどでしたが、改めて実装した後に、プロジェクト以外のエンジニアの方からレビューをもらうと「そもそもこの表現って正しいんだっけ...？」という見直しの機会になりました。


### 🎄 実行されるクエリや実行計画を見て、重くならないかチェック
実装で特定のデータを取得してくる際にORMなどを使用する場合、実行されるSQLやその実行計画をチェックするようになりました。

### 🎂 メソッドやコンポーネントをまとめること
共通化をできる処理はまとめたり、Reactの実装では再利用できるような形でコンポーネントを作成しておくなど、**細かくまとめること**を指摘していただき、意識するようになりました。

再利用できるものは自分の後に実装するメンバーの負担を減らすことにもつながるので、積極的に取り組んでいきたいです。

---
入社後、たくさんのレビューをいただきましたが、以前より特に意識するようになったものを紹介させていただきました。

次に、レビューをしていただく中で、レビュー前にやっておいた方が良いなと思ったものを紹介します。

## 事前に共有しておくと良さそうなこと

### 🍗 影響範囲の調査と共有
実装によって予期しない場所に影響を及ぼしてバグを産まないかを調査し、影響する可能性がある場所をリストアップしておきます。事前に絶対に影響するところがわかると、レビュワーの方も実装者が知らない他に影響しそうな場所を推測できるためです。

### 🍷 セルフレビュー
コミットする前や、レビューを依頼する前にdiffを見てセルフレビューしてみます。また、コミットメッセージには実装した内容そのものではなく、実装した意図を書いておきます。自分で気付ける限界まで調査し、その上でレビューをもらうと良いと思います。

@jnchito さんの記事がおすすめです。

[プログラミング初心者はgit commitする前に必ずdiffを自分でレビューするクセを付けよう \- give IT a try](https://blog.jnito.com/entry/2021/01/30/172607)

### 🎉 レビューポイント（見てもらいたいところ・不安なところ）
特にレビューをしてほしいポイントを書きます。全部見てほしい気持ちもあると思いますが、そういった場合は不安な場所を書くと良いと思っています。レビュワーも注意すべきところが絞られるので、処理集中してレビューできると思います。

### 💝 動作確認方法の補足
コードだけではわからない動作確認方法を捕捉したり、コードを見れば分かるがアクセスしてほしいリンク、実行してほしいコマンドを添えるなどの配慮があった方がレビュワーのストレスにならないと思います。

### 🍾 実装の背景
この機能をなぜ実装したのか、関連のissueやそのissueを踏まえてなぜこのような実装になっているのかなどを説明します。また、プルリクエストを小分けする場合は、実装の全体像と現行のPRがどこに当たるのかを説明するのも大切だと思います。

実装の背景や全体像がわかると、レビュワーは前提を踏まえてより良いアドバイスができるためです。

---

以上が、レビューをしていただく中で自分が事前に注意しようと思ったところです。見ていただくことを感謝して、なるべくストレスがないように気をつけていきたいと思います。

## まとめ
入社後にたくさんのレビューをいただいて、気づいたことをまとめてみました。自分もレビューする機会がたくさんあるので、これからも他のメンバーの役に立てるように、そしてGMOペパボの「いるだけで成長できる環境」づくりに貢献できるように頑張っていきたいと思います。

レビューサイコー！
[Oracle Cloud] Base Database ServiceインスタンスでIntelシェイプ から AMD シェイプへの移行してみた (2022/12/12)

こちらの記事は [Oracle Cloud Infrastructure Advent Calendar 2022](https://qiita.com/advent-calendar/2022/oci) Day 12 の記事として書かれています。

Oracle Cloud Infrastructure（OCI）のOracle Databaseサービスの１つ、Base Database ServiceでIntelシェイプからAMDフレキシブルシェイプへ変更が可能になったのでやってみた。

# 前提条件
- DBシステムはOracle Linux 7 (OL7)であること。DBシステムがOL7より前のバージョンで実行されている場合、移行前にDBシステムをOL7にアップグレードする必要があります。
    - DBシステムはカーネルUEK5であること。UEK4上にある場合、移行操作により自動的にUEK5に更新されます。
- Oracle Grid Infrastructureは、19.15以上のバージョンであること。
- 次のOracle Databaseバージョンまたはそれ以上のバージョンを使用する必要があります。
	- 21.6.0.0.0
	- 19.15.0.0.0
	- 12.2.0.1.220418
	- 12.1.0.2.220419
- Oracle Database 11.2および18cは移行できません。


# 作業前の状態
- DBシステムとデータベースは「使用可能」状態であること
- データベースは正常に再起動可能であること。
- DBシステムは、Cluster Ready Services (CRS) Grid Infrastructureスタックに登録されていること。デフォルトでは、仮想マシン DB システムは CRS を使用します。
- データベースは、PFILE ではなく SPFILE (サーバー パラメータ ファイル) を使用するように構成されていること。デフォルトでは、仮想マシン- DBシステムのデータベースはSPFILE構成を使用します。
- 自動共有メモリー管理 (ASMM)のSGA_TARGETパラメーターにゼロ以外の値があります。デフォルトでは、仮想マシン DB システムはこの ASMM 構成を使用します。

# 補足・留意点

- Intel ベースのシェイプと同じoCPU数のAMD ベースシェイプにのみ移行できます。たとえば、Intel VM.Standard2.2 シェイプの場合、AMD 2 OCPU シェイプに移行できます。移行後は、AMD シェイプの OCPU を変更できます。
- シェイプを変更しても、DBシステムで使用可能なストレージの量には影響しません。
    - AMD シェイプに移行した後、最大 40 TB までストレージをスケールアップできます。
    - AMD シェイプへの移行後、ストレージはBalanced ボリューム パフォーマンス オプションを利用できます。Higher Performanceオプション への変更はできません。
- 移行が成功すると、AMD シェイプから Intel シェイプに移行することはできなくなります。
- 移行が成功すると、古いブート ボリュームのバックアップに復元できなくなります。
- シェイプ変更操作は、マルチノード DB システムのローリング方式で行われるため、データベースのダウンタイムなしでシェイプを変更できます。




# 作業ステップ

- OCI Webコンソールナビゲーション メニューを開きます。Oracle Databaseを選択し、次にOracle Base Databaseを選択します。
リストからシェイプ変更するDBシステムを選択しシステムの詳細を表示します。
- 「シェイプの変更」 をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/0c78c2d8-a092-b845-4dc9-11065feb714a.png)


- シェイプ・シリーズセクションで「AMD」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/9fbc2e3b-ca52-d94c-7b58-3482f385135f.png)
    - 再掲：IntelベースのX7シェイプからAMDベースのフレキシブルシェイプE4にシェイプを変更する場合、OCPUの数は変更できません。
- [シェイプの変更] をクリックします。
- シェイプ変更の確認で[シェイプの変更] をクリックします。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/5919b76f-9fb5-3d08-2caf-44feb9005002.png)
- 作業リクエストの確認 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108635/44694b20-a6d7-7b73-d95f-6b13a8431fa7.png)




# おわりに

Base Database ServiceのIntelベースのシェイプからAMDベースのフレキシブルシェイプへ変更することができました。

## 参考情報
- [Change the Shape of a DB System](https://docs.oracle.com/en/cloud/paas/bm-and-vm-dbs-cloud/changingshapedbs/index.html#articletitle)
ChatGPTの活用

# 初めに
最近話題のAI、[chatGPT](https://chat.openai.com/chat)を使って色々と試した結果をまとめてみた


## 何ができるのか
siriみたいな感じで、質問するとAIが回答を自動で生成します。

![](https://i.gyazo.com/c97abbd8e31a7eb25934246914e2c2fe.png)

siriと違うのは、「今日の天気は？」などwebサイトの情報を検索することができないことです。
逆に、「集客効果があるキャッチフレーズを考えて」や、「詩を作って」などクリエイティブな回答を得ることができ、
コードのリファクタリングや、違う言語への書き換えなども可能です。
![](https://i.gyazo.com/acf69a9d505c892d6bc697f7befa29e3.png)
![](https://i.gyazo.com/588a33ad10c5dc6e22f42e4bdd070158.png)

## どのように使えるか
今後このAIを利用してどのようなことができるようになるのかプログラマーとして考察します

・コードレビューをAIに任せられるようになる
・メールの作成などの地味に大変な業務も任せられる
・クリエイティブなアイデアを出させることができる

## 使ってみた感想
かなり面白いです。

難点があるとすれば、英語以外の言語で質問すると一度英語で回答を返してそれを翻訳している形なので
自然な日本語ではないことが多いです。そして英語で質問した時よりもかなり回答に時間がかかるので、
英語での解答でも問題なければ英語で質問することをおすすめします。

googleのようにたくさんの情報があるわけではないので、

質問内容によって、google検索とchatGPTを使い分けるのがいいと思います。

完全に無料なオープンソースなので、もしあなたの仕事を効率化できるのであれば

積極的に使っていきましょう。
ALB vs NLB

# 本記事について
この記事では３回目のANS-C01を受けるにあたって勉強した内容を整理するための記事です。
詳しくは[こちら](https://qiita.com/the13-HK/items/349cdf5f38e0ce1e47b1)をご覧ください。
今回はELBの記事となります。
主にALBとNLBについて触れます。GLBについては別記事を作成予定です。

# ロードバランサ―とは
サーバーの処理を分散させるための装置。
ロードバランサーの英字は「Load Balancer」だが、
Loadは負荷、
Balancerはバランス、を意味する。

リクエスト（ソース）とサーバー（ターゲット）の通信の間にロードバランサを噛ませることでサーバーの負荷分散（ルーティング）を行う役割がある。
AWSマネージドのロードバランサの総称をELB（Elastic Load Balancer）と呼び、具体的には以下4つがある。

- CLB(Classic LoadBalancer)
- ALB(Application LoadBalancer)
- NLB(Network LoadBalancer)
- GLB(Gateway LoadBalancer)

ANS-C01ではあまりCLBについて触れられないのでALB、NLB、GLBについて記載する。（GLBは別記事で記載予定）


# ALBについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/837c5984-f4f4-aa41-f718-25f24f43df15.png)
※公式HPより引用

ALBは [OSI7層モデル](https://www.itmanage.co.jp/column/osi-reference-model/) における、第7層（アプリケーション層）に当たるトラフィックを制御するためのサービス。

### ターゲットについて
ALBのターゲットとして利用できるのは以下サービス
- EC2, Auto Scaling
- Lambda
- Fargate
- EKS
- ECS
- IP Address


### ルーティング方法について
HTTP等のアプリで使用する情報を元に使用したルーティングルールの設定が可能。
HTTP情報に基づいたルーティングルールは以下のようなものがある。

- ホストベースルーティング
- パスベースルーティング
- クエリ文字列ルーティング
- HTTPヘッダー
- HTTPメソッド
- IPアドレス

各ターゲット事の重み付けも可能

### ヘルスチェックについて
ターゲット対象の正常性をおこなうためにHTTP / HTTPSプロトコルを使用してヘルスチェックを行うことが出来る。
ヘルスチェックとしてのリクエストを送信し、ＨＴＴＰステータスが200となれば正常とみなす。
（ヘルスチェックのリクエスト送信先も指定可能）

### ALB独自機能
- ALBの前にWAF設置可能
- 認証機能をALBに設定可能。Cognitoはもちろんフェデレーションなどの外部認証も利用可能
- ALB自体のIPアドレスは動的に変化するため注意
- セキュリティグループ設定可能

# NLBについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/07cc527c-3fd9-63cb-3fcf-77ba920765de.png)
※公式HPより引用

ALBは [OSI7層モデル](https://www.itmanage.co.jp/column/osi-reference-model/)  における、第4層（トランスポート層）に当たるトラフィックを制御するためのサービス。

### ターゲットについて
NLBのターゲットとして利用できるのは以下サービス
- EC2, Auto Scaling
- Fargate
- EKS
- ECS
- IP Address
- **ALB**

ALBと比べると、**Lambdaが未対応**
しかし、ターゲットとしてALBを指定できるためNLBでALB指定、ALBでLambda指定等でできなくはない。
NLBでALBを指定するケースは **ALB使いたい、でもALBのIPアドレスを固定させる必要がある時** 等
詳しくは[こちら](https://dev.classmethod.jp/articles/alb-type-target-group-for-nlb/)を参照

### ルーティングについて
ALBのような細かなルーティング設定はできない。
その代わり**高可用性、高スループット、低レイテンシ**なルーティングが可能。

### ヘルスチェックについて
HTTP / HTTPSプロトコルに加えて、TCPによるヘルスチェックが可能
※ヘルスチェックは**自動回復機能なし**、送信をやめるだけ。

### NLB独自機能
- NLB自体のIPアドレスを静的に指定可能
- セキュリティグループ設定**不可**
- 送信IPアドレスの保持が可能
    - ターゲットグループまで送信元クライアントのIPアドレス、ポート情報を保持することが出来る。

# NLB,ALB共通機能
- 証明書インストールが可能
    - 対象のリージョンでインストールを行う。（CloudFrontの場合はus-east-1で登録する）
- ステッキーセッションの設定が可能
    - 詳細は[こちら](https://e-words.jp/w/%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AD%E3%83%BC%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3.html)
- 設定するサブネットのIPアドレスの空きが**8個以上ないと作成不可**
    - 最低限/27以上のサブネットでないとALB、NLBを作成できない。

- NLBに登録されていないが、ターゲットグループには登録されているAZにEC2には、**ELBからの通信は行われない。**
    - NLBにもアベイラビリティゾーンを追加する必要がある。
Visual Studio 2022 Communityでのatlbase.hが見つからないエラーの解決方法

# はじめに
Active Template Library(ATL)は，ActiveXコントロールの作成に使われるライブラリです。
例えばC++でATLを使ってActiveXのDLLを作成し，C#やほかの言語から利用することが可能になります。

https://learn.microsoft.com/ja-jp/cpp/atl/atl-class-overview?view=msvc-170

https://learn.microsoft.com/ja-jp/cpp/atl/reference/atl-classes?view=msvc-170

しかし，Visual Studio Communityでは，デフォルトのインストールでATLが入っていません。
そのため，ATLを利用するプロジェクトをコンパイルすると，

:::note alert
atlbase.hがありません。
:::

というエラーが出ます。このエラーが出ると，開発環境にATLが導入されていないと考えられます。

# 解決方法発見まで

## 従来はどうだったか？

Wikipediaを見ると，VS2012までは，ATLおよびMFCは有償版のみに付属するライブラリであった。と書かれています。ですので，ATLを利用するためには，StandardまたはProfessionalを購入しなくてはならなかったようです。
しかし，Visual Studio Community 2013以降は無償版でもATL/MFCが利用できるようです。しかし，利用規約は厳しくなっているようです。

https://ja.wikipedia.org/wiki/Active_Template_Library

Learn Microsoftを見ると，MFCとATLはVS2017以降でサブコンポーネントとしてインストール可能になったようです。

https://learn.microsoft.com/ja-jp/cpp/mfc/mfc-and-atl?view=msvc-170

## なぜATLはインストールされなかったか？

ではなぜ，私のVisual Studio 2022 Communityには，ATLがインストールされていないのでしょうか？
以下の記事を読んでわかりました。

https://learn.microsoft.com/ja-jp/visualstudio/install/install-visual-studio?view=vs-2022

**インストールの時に「個々のコンポーネントを選択する」オプションでATLを選択しなかったからです**
では，既にインストールされたVisual Studio 2022 CommunityにATLをインストールするにはどうしたらよいのでしょうか？

## 救世主現る

そうこうしていると，以下のツイートを見つけました。

https://twitter.com/kami_mura_kei/status/1414951967374385167

# 解決方法
以下の動画から手順を起こしました。

https://www.youtube.com/watch?v=Lq3SllRv7a8&t=6s

1. Visual Studioを起動し，Platform Toolsetのバージョンを確認する。
Visual Studio 2022(vXXX) などと書かれているはずです。確認ができたらVisual Studioを終了します。
1. Visual Studio Installer を起動する。
Visual Studioをインストールした時に一緒にインストールされています。スタートメニューから探せば見つかるはずです。
1. 最初のダイアログのInstalledタブにある，先ほど控えたVisual Studioのバージョンのカードの右上にある Modfyボタンをクリックします。
1. Modfyingダイアログが表示されますので，Indivisual Componentsタブを選択します。
1. Sarch Componentsテキストボックスに，**atl**と入力します。
1. ARM，ARM64，x86，x64を対象としたものが表示されますので，**ATL**と**x86**または**x64**と書かれているものだけを選択します。(チェックボックスをチェックします。)
なお，**vXXX**が書かれたものでは，1.で調べたものと同じものは必ず選びます。
余裕があればMFCも該当するものをインストールしておいたほうが良いかもしれません。
1. ダイアログの右下にある **Modify** ボタンをクリックします。
1. 元のダイアログに戻ります。インストールが終了したら，Visual Studioを起動し，atlbase.hのエラーが出なくなったことを確認してください。

動画では，MFCのライブラリが一つだけ選ばれていますが，その意味が私にはよくわかりませんでした。理由が分かる方いらっしゃいましたら教えていただけるとありがたいです。

# 謝辞

神村慧様のTweetにより問題が解決しました。

[神村慧@ANFWorks](https://twitter.com/Kami_mura_Kei)

貴重な情報を提供してくださり，ありがとうございます。感謝します。