OmniAICreator/Qiita-1.07M huggingface dataset:
go  にも decltype が欲しいよ、と思った話。

# これは何？

go を書いていて、初めて decltype ほしいよと真剣に思ったので、その記録。

decltype ってのは、C++ にある言語要素で、式からその式の型を得る機能。

```c++:c++
using usec_t = decltype (timeval{}.tv_usec);
```

のようにすると、`usec_t` を 構造体 `timeval` のメンバ `tv_usec` の型にすることができる。便利。

そして。

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

にも参加しています。

# ほしいよと思った経緯。

## `unix.Timeval` を使いたい

go で `unix.Timeval` を使おうと思った。
まあ使おうと思った時点で負けという気もちょっとするけど、まあ使おうと思った。

`float64` の値をゴニョゴニョして作った値で `unix.Timeval` を初期化したい。

`unix.Timeval` は、 `Sec` と `Usec` というメンバを持っていてこれに値を入れたい。

## ターゲット

しかしターゲット環境は

* linux 386
* linux amd64
* darwin amd64

の三種（だということにする）。

それぞれの環境での `Sec` `Usec` の型は下表のとおり。

|型 ＼ 環境| linux 386| linux amd64| darwin amd64|
|:--|:--|:--|:--|
|`Sec`|`int32`|`int64`|`int64`|
|`Usec`|`int32`|`int64`|`int32`|

C/C++ と違って型が違う変数への代入は全面禁止。もとの値の `interval` は `float64`

## 書きたかったコード

```go:go
type SecType = なんか
type UsecType = なんか

t := unix.Timeval{
	Sec:  SecType(math.Floor(interval)),
	Usec: UsecType((interval - math.Floor(interval)) * 1e6),
}
```

こうしたい。
こうしたいんだが、「なんか」の場所に `typeOf(unix.Timeval{}.Sec)` などと書くことはできない。

## 実際にできること

仕方ないので

* `unsafe.Sizeof` などを駆使してなんとかする
* 条件コンパイルで `UsecType` と `UsecType` を適宜定義する
* go generate でなんとかできるのかも。よく知らない。

の三択から選ぶことになるんだと思う。他にもあるかな。
私は条件コンパイルを選んだ。
こういうことに頭を使わせないでほしいと思う。

## go1.18 以降なら

今なら、 Generics が使えるので

```go:go1.18以降
type SecConstraint interface {
	int32 | int64
}

type UsecConstraint interface {
	int32 | int64
}

func hoge[S SecConstraint, U UsecConstraint](s *S, u *U, interval float64) {
	*s = S(math.Floor(interval))
	*u = U((interval - math.Floor(interval)) * 1e6)
}
```

としておけば


```go:go1.18以降
t := unix.Timeval{}
hoge(&t.Sec, &t.Usec, interval)
```

と書ける。

しかしトリッキーな感じは否めない。
やっぱり前述の「書きたかったコード」のようにしたいよなぁと思う。
Paradoxのデータを見るツールを作った

Delphi Advent Calendar 2022 25日目

# はじめに
今年、なぜかParadoxを使っているプログラムの機能追加の仕事を請けたときに、昔々の知識を絞り出して作成したParadoxのデータを見るためのプログラムの紹介です。
まだ、Paradoxを使っているところが他にあるのか不明で、このネタに興味を持つ人がいるのか疑問ですが。。。

# 画面
画面は、以下のような感じです。
フォルダ選択で、Paradoxテーブルがあるフォルダを選択します。
テーブル一覧が、左部分に表示され、テーブルをクリックすると右グリッドにデータが表示される仕組みです。
データを表示した後に、フィルター機能やIndexを使う機能も入れてあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/d68f2781-f7dc-f46f-f80e-734c34070c67.png)

# プログラム

## コンポーネント

コンポーネントは、こんな感じで。
FolderDialogは、TMSのものを使ってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33683/151b2b46-aea4-c6f4-459a-528f40ab1e2c.png)

## テーブル一覧取得
フォルダ選択し、その中のテーブルの一覧を取得するコードです。
テーブルを固定して、データを見るだけでしたら、Databaseは不要ですが、テーブルの一覧を取得するために使います。GetTableNamesメッソドがこれです。
```
procedure TFormMain.BtnSelectFolderClick(Sender: TObject);
begin
  FolderDialog.Directory := GetMyDocumentsFolder;
  if FolderDialog.Execute then
  begin
    try
      Database.Close;
      with Database.Params do
      begin
        Values['PATH'] := FolderDialog.Directory;
      end;
      ListBox.Items.Clear;
      Database.Open;
      Database.GetTableNames(ListBox.Items, False);
      TableData.DatabaseName := FolderDialog.Directory;
      Session.NetFileDir := GetExePath;
      Database.Close;
    except
      raise;
    end;
  end;
end;
```

## テーブルオープン

テーブル一覧で開きたいテーブルをダブルクリック
```
procedure TFormMain.ListBoxDblClick(Sender: TObject);
begin
  TableData.Close;  TableData.Filtered := False;
  TableData.Filter := '';
  TableData.TableName := ListBox.Items[ListBox.ItemIndex];
  TableData.Open;
  TableData.First;
end;
```

## フィルター機能
```
procedure TFormMain.BtnFileterClick(Sender: TObject);
begin
  if BtnFileter.Caption = 'Fileter ON' then
  begin
    try
      TableData.Filtered := False;
      TableData.Filter := EditFilter.Text;
      TableData.Filtered := True;
      BtnFileter.Caption := 'Fileter OFF';
    except
      raise;
    end;
  end
  else
  begin
    TableData.Filtered := False;
    TableData.Filter := '';
    BtnFileter.Caption := 'Fileter ON';
  end;
end;
```

## インデックス機能
```
procedure TFormMain.BtnIndexFieldClick(Sender: TObject);
begin
  if BtnIndexField.Caption = 'IndexField ON' then  begin
    try
      TableData.IndexName := '' + Trim(EditIndexField.Text) + '';
      BtnIndexField.Caption := 'IndexField OFF';
    except
      raise;
    end;
  end
  else
  begin
    TableData.IndexName := '';
    BtnIndexField.Caption := 'IndexField ON';
  end;
end;
```

# おわりに

まだ、Pradoxを使っているプログラムはほかにあるのだろうか。という疑問を持ちつつ他にネタが思いつかなかったのでまとめてみました。
ちなみにこの案件のプログラムは、来年に書き換えるらしいです。
私にその話が来なかったのは、ちょっと残念。。。まあ、私一人でやったらずいぶん時間がかかるボリュームだから仕方がないかなとは思うけど。。

今年の最後のネタがこれで良かったのか。。。(笑)
【Ruby】深いハッシュで、ある要素が未定義かどうかを判定


例として、以下のような深いハッシュがあるとします

```ruby
> x = {a: {b: {c: 1}}}
=> {:a=>{:b=>{:c=>1}}}
```

このハッシュに対して、 `x[:a][:b][:d]`が存在するかどうかを判定したいです

直感的に、以下のようにすれば判定できそうです
```ruby
> x[:a][:b][:d]
=> nil
```
結果は `nil` が返ってきたので期待通りです。

では、次に `x[:a][:e][:f]`が存在するか判定します
上と同様に
```ruby
> x[:a][:e][:f]
```
としてみます 
しかし、ここで問題が発生します
`x[:a][:e]`が `nil`なので、それに続けて`[:f]`を評価することができず、エラーが返ってきます

```ruby
> x[:a][:e][:f]
Traceback (most recent call last):
        4: from /usr/bin/irb:23:in `<main>'
        3: from /usr/bin/irb:23:in `load'
        2: from /Library/Ruby/Gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        1: from (irb):3
NoMethodError (undefined method `[]' for nil:NilClass)
```

このエラーを回避するためには、以下のようにして要素をひとつひとつ `nil` か否かを判定する必要があります

```ruby
> x[:a] && x[:a][:e] && x[:a][:e][:f]
=> nil
```

## hash.dig() を使う
上記の方法では、判定式が長くなってしまい可読性が低くなります
そこで、 `x[:a] && x[:a][:e] && x[:a][:e][:f]` をもっと簡単に書ける関数 `dig` を使います

```ruby
> x.dig(:a,:e,:f)
=> nil
```
これで、 `nil` が返ってきます

## 参考

https://qiita.com/ko-he-8/items/6819e93f76a302bf7597

https://shinkufencer.hateblo.jp/entry/2018/11/01/233000
クローズド環境における、お手軽機械翻訳の構築（構築時はネット接続必須）

# クローズド環境でのお手軽機械翻訳

## はじめに（セキュリティ事故もろもろ）
世の中にはGoogle翻訳やDeepLなどウェブ翻訳サービスが色々あります。
社外秘の文書をそれらサービスに突っ込むとセキュリティ事故になりかねません。
（virustotalでも社外秘を突っ込む人が絶えない・・・、アップロードされたものは有料で見えるよ！）（インターネットつながる環境でそんなもの扱うな！）

と、いうわけで、お手軽にクローズドな環境で使える機械翻訳サービスを構築します。

## 目的
膨大な外国語文書からお目当ての文書を探したい。
（正確な翻訳でなくとも、なんとなく何を言っているかの判別ができればいい）

## 環境
OS:Linux（Ubuntu22.04）
※ WindowsのWSLでもできたけど、別途環境構築（特にCUDA利用）が必要なので今回はUbuntuで・・・
GPU:Geforce GTX 1050 2GB
※ GPU無しでもできたけど、翻訳速度が桁違い。（メモリ優先、VRAMいっぱい積もう）

## ライブラリ
「[easyNMT](https://github.com/UKPLab/EasyNMT)」を利用しました。
(とにかくお手軽方針、pretrainedのモデルに全力で乗っかる)

## Code（日→英）
```python:sample.py
import easynmt
#引数でモデルを指定。予め用意されたモデルが色々あるので、easynmtのgithub参照
model = easynmt.EasyNMT('opus-mt')
#とりあえず憲法前文
sentence = "日本国民は、正当に選挙された国会における代表者を通じて行動し、われらとわれらの子孫のために、諸国民との協和による成果と、わが国全土にわたつて自由のもたらす恵沢を確保し、政府の行為によつて再び戦争の惨禍が起ることのないやうにすることを決意し、ここに主権が国民に存することを宣言し、この憲法を確定する。"
# 翻訳実行
translated = model.translate(sentence,target_lang="en",max_length=1000)
print(translated)
```
### 結果
※　初回実行時はモデルのダウンロードが始まります。（300MBくらい、キャッシュされます）

'The Japanese people act through representatives of the legitimately elected parliament and, for our children and our children, the results of cooperation with the people, the benefits of freedom, and the benefits of government throughout our nation, are determined to ensure that the scourge of war will not occur again according to the actions of the government, and here they declare that sovereignty will remain with the people and establish this constitution.'

### 注意事項
GPUがあればGPUを使ってくれますが、その場合、モデルがGPUメモリに乗る必要があります。
メモリが足りないとエラーとなります

### 補足
サンプルで使った「opus-mt」は、英→日変換に対応していません。（聖書の語句を出してる？）
m2m_100等を試しましょう。

興味があれば、AIコミュニティの[HuggingFace](https://huggingface.co/)を覗くと、いろいろモデル等が公開されています。

### おまけ

EasyNMTは、予め用意されているモデル以外にもHuggingFaceで公開されているモデルに対応しているものがあるようです。
例。英→日[Hugging Face](https://huggingface.co/staka/fugumt-en-ja)
```python
import easynmt
model = easynmt.EasyNMT(translator=easynmt.models.AutoModel('staka/fugumt-en-ja'))
sentence = 'We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.'
translated = model.translate(sentence,target_lang="ja",max_length=1000)
print(translated)
```
#### 結果
'私たち米国民は、より完全な連合を形成し、正義を確立し、国内の静けさを保証し、共通の防衛を提供し、一般的な福祉を促進し、自由の恵みを私たち自身と私たちの後身に確保し、命令を行い、米国のためのこの憲法を確立します。'
【意見募集】エンジニアが非エンジニアの人に知って欲しいこと

# エンジニアを理解する

エンジニアの生態についてはこれまでにも語られてきましたが、やっぱり他の職種と違う生き物だと感じるところはあります。
エンジニアだけを特別扱いしたい訳ではなく、別の生き物であるという区別が必要。特別と区別のニュアンスの違いは難しいですが、エンジニアの特性を知って頂きたいです。

# エンジニアのイメージ

エンジニアのイメージをいくつか上げてみます
自分自身が心当たりがあるものです

- 気難しい
- 出来ないばかり言ってやろうとしない
- 技術のことが好き
- マニアック
- 職人的

ただ、すべての人がそうでもないかなとも感じます。
今回はもう少し深堀りしてみたいと思います。

## プログラミングという仕事

人間が普通の生活の中でプログラミングをするという機会がないため、理解しにくい職業の１つだと思われます。

子供の頃から憧れるような職業は、人間が本能的に活動するときに行う行動が多く、自然に過ごす中でその仕事を理解できる機会があるものです。

音楽だったり、料理だったり、営業だったり、販売だったり、建物を作ったり、絵を描いたり、文章を書いたり、スポーツをしたり。
これらは小学生のときでも、同様の経験があると思います。

営業という直接の仕事はなくとも、学校生活の中で交渉を行うことはあります。販売の仕事は普段から買い物をするタイミングで触れる機会があります。音楽、料理、スポーツ、芸術などは人間が本能的に行うもので、お風呂に入っているときに鼻歌を歌ったり、木の枝で絵を描いたり、走り回って鬼ごっこしたりという活動があります。
最近はyoutuberやtiktokなどの活動もありますが、あくまで歌や踊りなどの変形した形です。

では、プログラミングという仕事はどうでしょう？
コンピューターというものがそもそもここ40-50年で急激に一般化したものです。
そのため、人間が本能的に活動するための機器になっていません。
通訳にも似ていますが、相手は人間ではなく、人間がコンピューターに合わせて調整する必要があります。

そういう意味でプログラミングというものは訓練した人間が、特殊な場面で上手く動くようにコンピューターに合わせた作業を行う仕事なのです。

つまり、プログラミングは普通の職種と違ってやってみる経験が非常に少なく、理解しづらいということです。

この理解しづらさを感覚的に理解していることから、エンジニアと非エンジニアという壁を感じることがあるのだと思います。


## エンジニアの特性を知ることで良い関係になる

この記事では、この壁をなるべく低くしていきたいなと思っています。

そのため、エンジニアの特性を知って行きたいです。

知っておくと
・エンジニアを怒らせずに済む
・上手くやり取りできる
・嫌な顔をされない
みたいなことを集めたいと思っています。

これは結果的にエンジニアの開発効率を高めることが出来ますし、エンジニアとのコミュニケーションには特別な感性が必要に感じるかもしれませんが、そのような難しい**コミュニケーションのストレスを減らす**ことが出来ます。




# エンジニア特有の感性

- リスクを恐れ、強く指摘する
    - プログラミングは１文字でも違うと正しく動かないため、曖昧なことに強く反応する
    - 少しのズレでも全体が出来ない原因につながるため、出来るロジックにならない場合指摘する
- 人とのコミュニケーションが少ない
    - PCに向き合っている時間はどうしても他の職種よりは多いです
    - 会社によりますが思ったよりもPCに向き合っているだけではないです


# エンジニア特有の事情

- プログラミングはコンピューターに実現するための翻訳も難しいが、ズレなく実現するための設計が難しい
    - 全体の流れや作りを考える時間が半分以上掛かることもある
    - 正しいロジックが考えてから、プログラミングを書くフェーズ
    - 作りながら考えないと見えないことも多い (設計ばかりやるより、作りながら判断する方が早い場合も多い)
- 見積もりは難しい。答えが見つかったときには半分以上終わっていることもある
    - 似ているものを作ることはありますが、同じものを作ることはほぼありません
        - 工場の製品生産とは違います
        - 一つ一つのシステムがオーダーメイドであり、同じものを作るわけではない
    - 初めてやることに掛かる時間を正確に見通すことはほとんど不可能です
        - 経験の中から似ていることを当てはめることで予測していますが、同じものを作ることは無いため想定外の事はよく起きます




# まとめ

システムの開発というものを扱う上での特性上、エンジニアの適正もある程度はコミュニケーション方法にも普通と違う傾向が出てしまう事があると思います。

その根拠を知ってもらえれば、もっと上手く会話がしやすくなるかもしれません。


エンジニアの人も歩み寄りが必須ではありますが、ぜひエンジニア自身でも自分の特性を理解した上で会話が出来るとよりよい関係が築けるのでは無いかと思います。


**皆さんのご意見も募集**

「エンジニアってこういうところがあるよね」みたいな、当たり前過ぎて気が付かなくなっている、エンジニアあるあるをQiitaのコメントやTwitterなどで教えてもらいたいです！

エンジニアと非エンジニアでの会話で、困った話などもあれば、Qiitaのコメントで聞かせて頂き、解決に向けたディスカッションなど出来ると嬉しいです。
【Swift】Xcodeのログを見やすくしたい

# はじめに
成功or失敗で条件分岐させた時にどこが実行されたか一目でわかるようにしたいです。
そう思った時にログに色を付けられたらいいのでは？と思ったのですが出来なさそうなので別の方法を考えました。

🟥🟧🟨🟩🟦🟪🟫⬛⬜

このような絵文字を使用してログを出力できるようにします。

# 実装
```swift
public enum LogType {
    case verbose
    case info
    case debug
    case success
    case warning
    case error
    case custom(String)
}


public func print(_ type: LogType, _ message: String) {
    switch type {
    case .verbose:
        print("⬜-VERBOSE: \(message)")
    case .info:
        print("🟦-INFO: \(message)")
    case .debug:
        print("🟧-DEBUG: \(message)")
    case .success:
        print("🟩-SUCCESS: \(message)")
    case .warning:
        print("🟨-WARNING: \(message)")
    case .error:
        print("🟥-ERROR: \(message)")
    case let .custom(emoji):
        print("\(emoji): \(message)")
    }
}
```

# 使い方
```swift
// verbose
print(.verbose, "This is an example of an verbose log.")
// info
print(.info, "This is an example of an info log.")
// debug
print(.debug, "This is an example of an debug log.")
// success
print(.success, "This is an example of an success log.")
// warning
print(.warning, "This is an example of an warning log.")
// error
print(.error, "This is an example of an error log.")
// custom
print(.custom("🚀-ROCKET"), "This is an example of an custom log.")
```

こんな感じで表示されます。
まぁまぁ見やすいですね
<img width="377" alt="log" src="https://user-images.githubusercontent.com/84154073/209585415-1f0a0f0c-2e78-490e-adb3-f7bdf83c5590.png">

# おわり
本当はログに色を付けたい。。。
できないのだろうか。。。

ライブラリにしてみました
スターください

https://github.com/SNQ-2001/LogKit
非同期処理を組み込む開発

# 非同期処理ってかっこいい
　非同期処理。言葉の響きだけでもかっこいいかんじがしてくる。開発したサービスにもそれはばっちり入っていて、なんとか機能はしている。これをこうしたら良い、というのはわかったが、本当のところ、いったいどうやって動いているのかわからない。

　すこし説明する。

# すべては操作性の向上

> 非同期とは、複数の主体がタイミングを合わせずに通信や処理を行う方式。対義語は「同期」（synchronized/synchronous）。
 https://e-words.jp/w/%E9%9D%9E%E5%90%8C%E6%9C%9F.html

　なるほど。わからない。私のサービスではこんなときに使っている。

　プルダウンで選択した値に応じて、ページを遷移しなくても項目が増えたり減ったりする。詳細はここに書いてある。

https://qiita.com/kyokucho1989/items/752b389b962aad05fa43

　通常はプルダウンで選んだ値は、ページ遷移のときに他のデータと一緒に送って処理している。しかし、こうなると操作性が悪くなる。「え、なんか使いづらいな」と思ってしまう。
　（ここで、「誰が」という話になるが、「俺がユーザー」なので俺だ）

 そこで非同期処理を行う。プルダウンで値を選ぶと、変更すべきところがすぐに変わる。わかりやすい。使える。良い。


　結局はユーザーが使いやすいか、それで問題を解決できるか、ということなんだろう。別に非同期処理を組み込まなくてもものはつくれる。

　そういうことか。
[Elixir]外部プロセスを管理する方針を紹介

この記事は[Elixir Advent Calendar2022-4](https://qiita.com/advent-calendar/2022/elixir)の24日目です。
執筆時、新型コロナにかかっていたのでコード少なめです m(__)m

---

# 開発環境
- Windows 10 + WSL2 + Ubuntu 22.04
- Elixir 1.13.4
- Erlang/OTP 25 

# 対象者
- Elixirの外側にある*.exeやコマンドを呼び出したい
- 呼び出しの結果を保持しながら同じコマンドを呼び出したい
- 重たい外部処理をスマートに呼び出したい

# 基本

## `System.cmd`
引数が１つの外部処理を呼び出すときに使います。

```elixir
iex> System.cmd("echo", [hello])
{"hello\n", 0}
```

## `:os.cmd`
`System.cmd`だと引数が複数あるときに記述が少しややこしくなります。
せっかく書いたのに動かないこともあります。
そんなときに`:os.cmd`が便利です。

```
iex> :os.cmd("rm -rf hello.txt")
[]
```

# 発展
## 重たい処理の実行終了と確認
外部処理が重たいとき、コマンドを実行するとそのまま制御が返ってこなくなってしまいます。
私の場合は再生時間が長い動画の変換や抽出処理で体験しました。

下記は[FFmpeg](https://ffmpeg.org/)で動画の音声を取得するコマンド例です。

```elixir
iex> :os.cmd("ffmpeg -i inputfile.mp4 outputfile.mp3")
...
```

制御を待っている間プログラムが止まってしまいますので「コマンドを打って終わるまでは別のタスクをして、終わったら本来のタスクに戻る」という動きをしたい。
こういうときのためか、`System.cmd`は`Port`モジュールを使用しているようです。
`Port`は下記のように使います。

```elixir
iex> path = System.find_executable("ffmpeg")
iex> port = Port.open({:spawn_executable, path}, [:binary, :exit_status, {args: ["-i", "inputfile.mp4", "output.mp3"]}])
```

オプションに`exit_status`を指定することでプログラムの終了通知を受け取ることができるようになります。
通知は[Port.monitor](https://hexdocs.pm/elixir/1.14/Port.html#monitor/1)を実行したプロセスにメッセージ送信されます。下記が受信するメッセージの例です。

```elixir
iex> Port.monitor(port)
{:DOWN, ref, :port, object, reason }
```

## 連続して重たい処理
CPUに負荷がかかるような外部処理をどんどん生み出すとCPUとメモリがなくなってしまいます。
常にプロセスを監視して、終了通知が来たら次の処理をしてくれて、もしプロセスが落ちても復活してくれるそんな便利なプロセスがGenServer。

Elixir Schoolにも解説があります。
https://elixirschool.com/ja/lessons/advanced/otp_concurrency

GenServer + Portを使うと、外部に渡すデータがある限り外部処理を順次呼び出すプログラムを作ることができます。

### 参考記事
英語ですが、下記がGenServerとPortの参考記事になります。

- [Learning Elixir's GenServer with a real-world example](https://papercups.io/blog/genserver)
real worldはhello worldの対の意味ではなく、現実にあるプロダクトでどんな風につかっているかという記事です。GenServerを使ってDBの更新をするサンプルをみることができます。 

- [Managing External Commands in Elixir with Ports](https://tonyc.github.io/posts/managing-external-commands-in-elixir-with-ports/)
今回、紹介したかったPort + GenServerで外部の重たい処理を呼び出す方法が解説されています。


# まとめ
簡単ですが、外部処理を呼び出す・管理する方法について紹介しました。

- シンプルな外部処理は`System.cmd`
- 外部処理の引数が多いなってときは`:os.cmd`
- 外部処理が重たい！ってときは`Port`モジュール
- 重たい外部処理を管理したいってときは `Port` + `GenServer`
IIFE、即時実行関数式について

こんにちは  
今回は僕がJavaScriptを書いているときにはまってしまった罠を共有しようと思います。
早速ですが、皆さんは下のコードがどのような振る舞いをするか分かりますか？
```React:App.tsx
import "./App.css";
const App = () => {
  const box = (name: string) => {
    return (
      <div className="box">
        {name}
      </div>
    )
  }

  return (
    <div className="App">
      <div className="row">
        <> {/*この中身の挙動を想像してみてください */}
          {box("box1")}
          {function () { return (box("box2")) }}
          {() => { return (box("box3")) }}
        </>
      </div>
    </div>
  );
}

export default App;

```

<details><summary>答えはこちら</summary>
box1のみが表示されてbox2, box3は表示されません。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/4ba77993-78bc-82b9-6db4-694a8215c3e7.png)

</details>

# なぜこのような挙動になるのか
一言で言うと関数の定義のみが行われて実行されていないからです。
開発者ツールでHTMLを見てみると、下の画像のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/e1ac0097-29a9-1a30-301f-b2443add4603.png)

このようにbox1のみしか存在していません。
この記事をお読みのエンジニアの方々は「早く関数の宣言じゃなくて実行しろよ！！！」と思われているかもしれないので実行してみます。

# 即時実行関数の登場

```React:App.tsx
      <div className="row">
        <>
          {box("box1")}
          {(function () { return (box("box2")) })()}
          {(() => { return (box("box3")) })()}
        </>
      </div>
```

結果はこちらです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/1c6c5b48-a35b-7e82-4e4a-61a44130cbbe.png)

ちゃんと表示されました。
今回変更した点としては関数全体を囲む括弧と関数の後につけた括弧があります。
二つの括弧の説明としてMDNにいい感じの文章があったので引用します。

>最初の部分は グループ化演算子 () に囲まれた静的スコープ付きの無名関数です。これは IIFE イディオム内で、汚いグローバルスコープと同様に変数へアクセスすることを防ぎます。
2つ目の部分は即時実行関数式の () で、これを通じて JavaScript エンジンは直接関数を解釈実行します。

つまり実際に実行するために動いているのは後ろの括弧です。
ではこの即時実行関数式はどのようなタイミングで使うべきなのでしょうか？

# 即時実行関数をいつ使うか問題を考えてみる

基本的にプログラムを書いているときは「宣言」→「実行」という流れが普通です。僕の肌感になりますが、宣言した瞬間に実行したい関数はあまりありません。そもそも関数は繰り返し行われる処理を簡単にするためであったり、プログラムの可読性を上げるために使います。
そのように考えていると、即時実行関数はおまけ機能くらいに思えてきます。ただ、私の中では一つ有用に使えるのではないかと思う場所があります。それはJSX Elementの中で式を利用しながら要素を作るときです。jsx Element内で関数を宣言してその後すぐに使うというよりも無名関数の即時実行関数で書いてしまった方が可読性が上がるのではないでしょうか？
結局普通の関数と違うところは宣言した瞬間に実行されるという一点になるので、この特徴を生かすために一回しか使われないような場面で使うというのが最もいいのではないでしょうか？


## 参考
https://developer.mozilla.org/ja/docs/Glossary/IIFE
Rails ルーティングについて備忘録

Railsを使用したアプリケーションでは、HTTPリクエストをクライアントが送信したときに、ルーティングと呼ばれる作業が実行されます。ルーティングというのは、送信されたリクエストに対してどのコントローラを参照するのかを決める作業です。

例えば、以下のようなコードでルーティングが決定されます。

```Ruby:routes.rb
Rails.application.routes.draw do
  root 'static_pages#home' #参照するコントローラ名/アクション
  get  'static_pages/about' #URL
end
```
以下のコードでアプリケーションのルートURL(最初に表示するURL）を定義しています。

```Ruby
root 'static_pages#home'
```
また、'static_pages#home#`というのは、static_pagesコントローラのhomeアクションを参照するという意味です。

つまり、上記のコードは、「ルートURLにアクセスした時は、static_pagesコントローラのhomeアクションを実行する」という意味になります。

また、以下のコードでは、getリクエストで'static_pages/about'がリクエストされた時に,static_pagesコントローラのhomeアクションを実行するということを定義しています。

```Ruby
get  'static_pages/about'
```

ちなみに、static_pagesコントローラファイルは以下のように定義されています。

```Ruby:app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
  def home
  end

  def about
  end
end
```

homeアクションとaboutアクションが定義されているので、それぞれのアクションをしっかりと実行することができるようになっています。

他にもルーティングの定義の方法はありまして、例えば以下のような書き方をすることができます。

```Ruby:routes.rb
Rails.application.routes.draw do
  root 'static_pages#home'
  get  '/about',   to: 'static_pages#about'
end
```

この記法を行うことの利点は以下のとおりです。

<ul>
<li>about_path,about_urlという記述を使用することができるようになる。</li>
</ul>

about_path -> '/about'
about_url  -> 'https://www.example.com/about'

これらはrootメソッドでルートURLを定義しているから使用できる記述になっています。
【デモ環境あり】真・GASを使って掲示板を作ってみた話

この記事は僕が3年以上前に作成したアプリを改良したものになります。
元の記事は[こちら](https://qiita.com/rarara_x16/items/c1c6c0e8dc97347d70c1)

改良しようと思った理由はいくつかあります
* Vue.jsが3がリリースされたから
* vuetifyもVue.js3に対応したから
* バグもあり修正も含めてより使いやすいように改良したかったから
* 当時は独学すぎて変数名と関数名がスネークケースなのが気持ち悪かった
* GASの新しいエディタでもスクリプトプロパティが使いやすくなった
* 思ったより色々な方が利用してくれたから
などなど...色々と思う事があったので、2022年最後に作り直そうと思い作り直しました。

## デモ環境 
デモ環境は[こちら](https://script.google.com/macros/s/AKfycbwK54p5iRv22GHGAE39ulySIyaJVftUBE3XRliqGAyz2w4Di7aIX9dDBJCA6Tdypsk/exec)
ソースコードは[こちら](https://github.com/rararax16/GAS-SNS-BOARD)

## 画面イメージ

### 一覧画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/fca4a216-9c06-c08a-279c-2a67a59f58af.png)

### 詳細画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/91f96796-6814-6338-5937-3182816f125e.png)

### 投稿画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/6de4ef9c-e76b-7714-260c-95d3672b5ac6.png)


## 変更点
今回、アプリを作り直した事でできるようになったこととできなくなった事があります。
### できるようになった事
* 投稿一覧を一度に表示する件数を指定できるようになりました
スクリプトプロパティで一度に表示する件数を指定できるようになっています。
もっと表示したい場合は、一覧画面下にある「もっと表示」を押せば追加でデータを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/be2228f2-7368-78bb-4d43-594f8b9b6540.png)

最後までデータを表示した場合は「これ以上はありません」と表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/1e42020a-2ac6-4ab9-b65b-301b2a49228c.png)

* コメントを一度に表示する件数を指定できるようになりました
スクリプトプロパティで一度に表示する件数を指定できるようになっています。
投稿一覧と同様にもっと表示したい場合は、一覧画面下にある「もっと表示」を押せば追加でデータを取得します。

* 投稿一覧で自分が未読・既読が分かるようになった
投稿一覧で自分が確認していない投稿はアイコン横に赤丸が表示されます。
詳細を表示した投稿は赤丸は消えます。
自分が投稿した内容は赤丸は表示されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/3a97e8ac-71bc-2e0f-dc44-8ef7963d324f.png)

* 投稿一覧で添付ファイルまたは、リンクがあるのかが分かるようになった
投稿した記事に添付ファイルまたはリンクがあれば、一覧右側にアイコンとして表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211927/202ac768-d0fb-3d2b-0909-fb5d114e80c8.png)

* 投稿者のGoogleアカウントの画像が表示されるようになった
誰が投稿したか分かるようにアイコンを表示しています。

### できなくなった事
* コメント通知のメール送信ができなくなりました
コメントがあると投稿した人にメールで通知する機能は今回は消しています。
また必要だと思ったら、機能として追加したいとは思っています。

## 最後に

今回はよりソースコードをGAS上にコピペをすれば展開できることを意識して作りました。
なので、GASの部分はJavaScriptで、フロントもHTMLファイル一つになっています。

久々にGASでガッツリと作ったのですが
やっぱりTypeScript使いたいなーと思ったのと
HTMLファイルでvue.jsを使うのがコンポーネントとか分けにくいのがちょっと大変だなと改めて思いました。

これからも何か作っていけたらなと思いまいます。
ANS-C01受験結果

# 本記事について
この記事では３回目のANS-C01を受けるにあたって勉強した内容を整理するための記事です。
詳しくは[こちら](https://qiita.com/the13-HK/items/349cdf5f38e0ce1e47b1)をご覧ください。
今回はANS３回目の試験の受験結果報告となります。

# 結論
(ぎりぎり）**合格しました！！！！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/eacb0054-b0ab-496e-79e7-a6afd3288c3e.png)

合格ラインは750点に対し、785点なのでぎりぎりでした。
各セクションのコンピテンシー状況はすべて満たしていたので、まぁ良しとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/59e7e17b-9ddb-e004-ded3-2ad201e620ee.png)


## 3回受けて感じたこと

問題レベルが他試験と比べて圧倒的に高いのはもちろんですが、それ以外で感じたことを記述します。
- 日本語訳がかなり粗い
    - 訳が冗長でかなりわかりづらいです。しかし、3回も受けてくると結構慣れてきます。
- 同じ問題が結構出てくる
    - これ前の試験でも見た問題だ、ってやつがかなり多かったです。2回目までの問題でわからなかった問題をよく覚えておき、それを復習する、といった学習方法でも点数向上が期待できると思います。
- 少しずつインライン教材が増えてきた
    - 主に英語メインですが、ANS-C01に対応したオンライン教材が増えてきました。
    - **問題集**
        - [whizlab](https://www.whizlabs.com/aws-advanced-networking-speciality/)
            - 全部で五回分の試験問題がありますが、一部分ANS-C01に対応しきれていない問題もありました。
        - [TUTORIAL DOJOS](https://portal.tutorialsdojo.com/courses/aws-certified-advanced-networking-specialty-practice-exams/)
            - 私は購入していませんが、おそらくANS-C01に対応した問題が提供されているはずです。
    - **教材**
        - [UDEMY](https://www.udemy.com/course/aws-certified-advanced-networking-specialty-ans/)
            - ANS-C01の範囲のサービスについて紹介している動画を見ることが出来ます。（英語）


# 最後に
（同じことを2回言いますが、）3回目にしてようやく合格できました。
今までのAWS試験の中で一番苦労した分、合格した時の喜びも一番大きかったです。
今まで弱かったインフラ部分の知識を多少なりとも身に着けることが出来たのも思わぬ果実でした。
後はSAPonAWSを合格すれば、１２冠達成なのでもう一度兜の緒を締めて頑張りたいと思います。

ANS-C01編の記事はこれにて最後です。
better than perfectの精神でとりあえず記事を書くことを目標にしていたので書ききることが出来てよかったです。
これからは内容も気にして、より良い記事を書けるように頑張りたいと思います。
Word相互参照の段落番号

# Word相互参照の段落番号

# 1. はじめに


Wordの相互参照の段落番号の備忘録です。すぐ忘れるので。

# 2. Wordの相互参照の段落番号


相互参照の文字列の段落番号には次の3種類があります。

* 段落番号
* 段落番号（内容を含む）
* 段落番号（内容を含まない）

    1.1.1のような段落番号を使っているときには、ほとんど？差がありません。（たぶん）

# 3. 段落番号に差が出る例


次のような段落番号が振られた文書で、1章1節に、4つの参照先を、3通りの文字列で相互参照を挿入してみました。

![xref_B46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/44a7c362-3ca2-3264-57b8-495cef22b96e.png)


こうなります。

![xref_B64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165394/c9710a4a-5ce3-66b7-b668-1237747ac262.png)

正確ではないですが、動きからは、上記のような感じです。
Hash.new([]) の挙動にハマった

## はじめに
`Hash.new([])` を使用して処理を書く場面があったのですが、
その際の思わぬ挙動にハマった話とその対処方法について記事にしました

## 問題のコード
```ruby
processed_ids = ::Hash.new {[]}

# user からは group_id と user_id を参照できる
users.each do |user|
    next if processed_ids[user.group_id].include?(user.user_id)

    processed_ids[user.group_id].push(user.user_id)
end
```

processed_ids にキーとして group_id を指定し、それに対して配列で user_id を追加していき、
既に group_id に対応する配列に user_id が追加されていたら、処理をスキップする、という処理を書いています。

上記のような記述で動作する...と思っていたのですが、
実際に動かしてみると想定した通りに動きません。

実際にコンソールで処理を細かく見ていくと、以下のような形になっていました。

```ruby
irb(main):001:0> processed_ids = ::Hash.new([])
=> {}
irb(main):002:0> processed_ids[1].push(101)
=> [101]
irb(main):003:0> processed_ids[1]
=> [101]
irb(main):004:0> processed_ids[2]
=> [101] # !?
irb(main):005:0> processed_ids[2].include?(101)
=> true # !!?
```

Hash に対して新しくキーを指定し push で値を追加してから他のキーで参照すると、
そのキーでも同じ値が格納されていました。
そんなバカなと思い、ドキュメントを確認してみると...

https://docs.ruby-lang.org/ja/latest/method/Hash/s/new.html

> - new(ifnone = nil) -> Hash
>   - 空の新しいハッシュを生成します。ifnone はキーに対応する値が存在しない時のデフォルト値です。設定したデフォルト値はHash#defaultで参照できます。
>   - ifnoneを省略した Hash.new は {} と同じです。
>   - デフォルト値として、毎回同一のオブジェクトifnoneを返します。それにより、一箇所のデフォルト値の変更が他の値のデフォルト値にも影響します。

> <b>一箇所のデフォルト値の変更が他の値のデフォルト値にも影響します。</b>

!?
どうやらこの挙動は仕様して存在しているようです。
ドキュメントに例として以下のコードが書かれていましたが、
```ruby
h = Hash.new([])

p h[1]                  #=> []
p h[1].object_id        #=> 6127150
p h[1] << "bar"         #=> ["bar"]
p h[1]                  #=> ["bar"]

p h[2]                  #=> ["bar"]
p h[2].object_id        #=> 6127150

p h                     #=> {}
```
`h[1]` に格納した値と、`h[2]`に格納されている値が同じものになっています。
なるほど...

## 対処方法
以下のように Hash の宣言をすると、先に挙げた挙動を回避できました。

```ruby
Hash.new { |hash, key| hash[key] = [] }
```

初期化の際にブロックを与えると、
まだ値が無いキーを参照した際にそのブロックが評価され別のオブジェクトになってくれるようです。

```ruby
irb(main):001:0> processed_ids = Hash.new { |hash, key| hash[key] = [] }
=> {}
irb(main):002:0> processed_ids[1].push(101)
=> [101]
irb(main):003:0> processed_ids[1]
=> [101]
irb(main):004:0> processed_ids[2]
=> []
irb(main):005:0> processed_ids[2].include?(101)
=> false
```
エラー処理についてすごく簡単にまとめてみた#3

## はじめに
エラー処理について３にパターン分けて記事を投稿する。

①Optional型 >>>>> 成功時は値を返し、失敗時はnilを返す
②Result型 >>>>> 成功時は値を返し、失敗時はエラーの値（詳細）を返す
③do-catch文によるエラー処理

今回は③について記載する。

下記URLの続編である。
https://qiita.com/RammaruIshii/items/861da45cd8c610b43341

## 詳細
- do-catch文によるエラー処理
    - エラーが発生する可能性のある処理をdo節内に記述する。そして、エラーが発生した場合、catch節へプログラムの制御が移る（要は、do節でエラーが起きると下で定義したcatch節内へ処理が走りますよってこと）。

- コードを見る上で押さえておきたいキーワードなどを簡単に説明
    - tryキーワード
        - throwsキーワードを定義した関数などを呼び出すときに必要なキーワード。
    - throwキーワード
        - エラー処理を投げれる（do-catch文のcatch節へ）。
    - throwsキーワード
        - エラーが起こるかもしれないという可能性を示すことができる。
        - エラー処理を投げる際は必ずthrowキーワードとセットで定義。
        - do-chatch文を用いずにエラーを発生させる「可能性のある」処理が可能だが、今回はそれはしません。
  


```swift:Swift
//今回は、引数の値を３倍にして返す関数を定義し、
//エラーだった場合、列挙体のエラー処理を走らせるということdo-catch文を用いて行いたい

//エラー発生時のエラー内容
enum OperationError: Error {
    case overCapacity
}

//throwsキーワード
//エラーが起こるかもしれない引数の値を３倍にして返す処理
func triple(of int: Int) throws -> Int {
    guard int <= Int.max / 3 else {
        throw OperationError.overCapacity
    }

    return int
}

let int = Int.max

do {
    //catch(失敗した時にエラー処理)へ送る関数と成功したときの処理を担うdo節

    //tryキーワードはthrowsキーワードを付与された処理を呼び出すときに必ず必要
    let tripleOfInt = try triple(of: 3)
    print("success: \(tripleOfInt)")
} catch {
    //このerrorはOperationErrorのErrorプロトコルで準拠したもの
    print("failuer: \(error)")
}
//出力
//success: ３


//番外編
//ちなみにdo節中のtry triple(of: )に先ほど定義した定数intを代入すると...
do {
    //catch(失敗した時にエラー処理)へ送る関数と成功したときの処理を担うdo節

    //tryキーワードはthrowsキーワードを付与された処理を呼び出すときに必ず必要
    let tripleOfInt = try triple(of: int)
    print("success: \(tripleOfInt)")
} catch {
    //このerrorはOperationErrorのErrorプロトコルで準拠したもの
    print("failuer: \(error)")
}
//出力
//failuer: overCapacity
```

## おわりに
修正箇所等あればご指摘ください。

## 参考記事
[[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)　](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-Swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E7%9B%B4%E6%84%9F%E7%9A%84%E3%81%AA%E6%96%87%E6%B3%95%E3%81%A8%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E5%85%BC%E3%81%AD%E5%82%99%E3%81%88%E3%81%9F%E8%A8%80%E8%AA%9E-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4297112132)
↑引用元
石川 洋資 (著), 西山 勇世 (著)
発行者：片岡 巌
出版社：技術評論社
印刷/製本：日経印刷株式会社

## 開発環境
- Xcode-13.4.1
- Swift version 5.7
SQLを実際のウェブアプリケーションで使ってみた

# 背景
SQLの学習サイトは多種多様存在するが、実際のアプリケーションでどのように扱っているのかが学習しにくいという体験があったため

# ※SQL主眼のため、MyBatisの詳細やMVC関連の説明は割愛、下記のみでは同様の結果は起こりません、ご容赦ください

# 基本的な検索
```example.xml: 
<select id="findPageByCriteria" parameterType="Information" resultType="Information">

        SELECT
            id,
            title,
            content,
            created_at
        FROM
            osirases
        <where>
            <if test="title != null and title != ''">
                AND title LIKE CONCAT('%', #{title}, '%')
            </if>
            <if test="content != null and content != ''">
                AND content LIKE CONCAT('%', #{content},'%')
            </if>
        </where>
```
> - LIKE CONCAT()部分は曖昧検索ですが、MySQL使用上の記述
> - %はワイルドカードで前方一致・後方一致などの厳密ではない検索に扱うことが可能
>   * パラメーターとして扱う値の前後に記述

検索フォームを作成し、AND検索を行うことを想定。
タイトルフォームに「ページネーション」
内容フォームに「練習」と入力し、検索ボタンを押下
その結果が下記のようなもの。

![スクリーンショット 2022-12-24 16.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073794/3f013705-abb7-3667-92ae-919bceeb4228.png)


SQL学習当初の場合は下記のような例を頻繁に観測した経験がある。

```SQL:
SELECT * FROM zoo WHERE animal = 'cat';
```
「zooテーブルからanimalカラムがcatであるものを全件取得する」
↓
「ズーテーブルノアニマルカラムガキャットデアルモノヲ...」
簡潔的な例なので理解はもちろん可能ですが、実際の使われ方の用途が不透明でした。

基本は大切です。しかし、SQLをどのような用途で扱うのか想像が出来なかったために、クエリした結果でも消化不良が払拭出来ないような心持ちでした。
今回のような簡易的なものですが、プログラムと共に扱うことで体感的なものとして昇華し、今後も邁進して行けたらと思います。

# おまけ
```SQL:example.xml
<select id="findPageByCriteria" parameterType="Information" resultType="Information">

        SELECT
            id,
            title,
            content,
            created_at
        FROM
            osirases
        WHERE
            1 = 1
            <if test="title != null and title != ''">
                AND title LIKE CONCAT('%', #{title}, '%')
            </if>
            <if test="content != null and content != ''">
                AND content LIKE CONCAT('%', #{content},'%')
            </if>
    </select>
```

こちらでも結果は同様になります。異なるものは下記。
```SQL:
WHERE 1 = 1
```
こちらはMybatisの
```SQL:
<where></where>
```
のような使い方が可能で、冒頭の物と同様にWhere句内の条件が当て嵌まらない場合は全件を取得したい（Where句が可変の場合とも言う）、そのような場合に使用します。また、用途によってはプログラムの視認性が向上することもあります。

最後は蛇足であったかもしれませんが、多様な書き方を学び選択できるようになれたらと思います。

ご覧いただきありがとうございました。
【Laravel】SQLの確認は$query->dd()が便利

こちらは [Laravel Advent Calendar 2022](https://qiita.com/advent-calendar/2022/laravel) 21日目の記事です。
遅ばせながらクリスマスイブの本日に投稿します！

# 検証環境
Laravel v8.83.8

# $query->dd()は良いぞ
「Laravel SQL 確認」で検索すると下記の方法をよく見かけますが、

```php
$query = User::where('id', 1);
dd($query->toSql(), $query->getBindings());
```

同じ処理を``$query``から直接実行できます。

```php
$query = User::where('id', 1);
$query->dd();

// 出力結果
// "select * from `users` where `id` = ?"
// array:1 [▼
//   0 => 1
// ]
```

公式サイトにも記述されています。

https://laravel.com/docs/8.x/queries#debugging

## 解説
``dd()``はクエリビルダのメソッドです。
Modelが作成するEloquentのビルダはクエリビルダのインスタンスを保有しており、そこから``dd()``を実行しています。

```php
// in vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
public function dd()
{
    dd($this->toSql(), $this->getBindings());
}
```

気になる方はコアファイルを読んでみてください。
- [Illuminate\Database\Eloquent\Builder](https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Eloquent/Builder.php)
- [Illuminate\Database\Query\Builder](https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Query/Builder.php
)

# $query->dump()もできるよ
処理を止めたくない場合は``dump()``も利用できます。
```php
$query = User::where('id', 1);
$query->dump();

// 出力結果
// "select * from `users` where `id` = ?"
// array:1 [▼
//   0 => 1
// ]
```

```php
// in vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php
public function dump()
{
    dump($this->toSql(), $this->getBindings());

    return $this;
}
```

# どのバージョンから利用できるの？
``v5.8``より利用可能です。
[v5.8のリリースノート](https://laravel.com/docs/5.8/releases
)に記述が無いため、当時のプルリクを参考に掲載します。

https://github.com/laravel/framework/pull/28357

使うと開発効率がちょっぴり向上しますね。
皆さま素敵なクリスマスを！
Gateway Load Balancerについて

# 本記事について
この記事では３回目のANS-C01を受けるにあたって勉強した内容を整理するための記事です。
詳しくは[こちら](https://qiita.com/the13-HK/items/349cdf5f38e0ce1e47b1)をご覧ください。
今回はGateway Load Balancerについてです。


# Gateway Load Balancerとは
ネットの記事によくある説明は
「ネットワークアプライアンス(以降、アプライアンス)の可用性を向上させることができるロードバランサーになります。」
とあります。
では、ネットワークアプライアンスとは何でしょうか。

### ネットワークアプライアンスとは
具体的には以下のようなサービスを指します。
   - ファイアウォール
   - 侵入検知および防止システム(IDS／IPS)
   - ディープパケットインスペクションシステムなど

「インターネットに向かう/ からくる通信の途中でIPの通信内容をチェックするためのサービス」で使われる仕組み、という理解です。
IPの通信内容をチェックするためには途中でチェック用のサービスに寄り道させる必要がありますが、その寄り道を効率的に行えるようにするのがGateway Load Balancer、というわけです。
#### ネットワークアプライアンスがある時とない時の通信の違い（イメージ図）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/87c2756d-fe99-fbd6-4bcd-5ae2b80a0653.png)

サービスとインターネットは普段通信するときにアプライアンスのことなんか意識して通信を行いません。
しかし、ロードバランサ―側は通信が来た時にネットワークアプライアンスに通信を横流ししています。


この際、LBは
- サービス / インターネットから来た通信は無条件に仮想アプライアンスに横流しする
- 仮想アプライアンスから来た通信は条件（ルートテーブル）に合わせて通信経路を決定する

といったルールを設定することが出来ます。

一方、仮想アプライアンスでは
- 通信が来るのはLBからのみ
- 送信先も無条件でLB
となるはずです。

このような通信を行うために作られたのがGateway Load Balancer（上記画像のLB部分を担うためのサービス）となります。
Gateway Load Balancerで使用する通信のプロトコルは**GENEVEプロトコル**と呼びます。

## Gateway Load Balancerの設定方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/63855275-772d-abea-847b-272816d3591a.png)

**注意点**
1. サービスと仮想アプライアンスのVPCは分ける
1. GatewayLoadBalancerの本体は仮想アプライアンス側
1. GatewayLoadBalancerとの通信相手は以下のどちらか
    - Gateway Load Balancer Interface Endpoint
    - Transit Gateway
1. Gateway Load Balancer Interface Endpointをサービス用VPCに立てるときは、サービス用サブネットとは別のサブネットに立てる


## まとめ
GWLBは一応ELBの一種ではあるが、ALBやNLBとは使い方が異なるため、しっかり整理しないと混乱してしまうサービスだなと感じた。
かなり概念的な部分しか記載していないためBlackBeltや他ホームページと合わせて理解を深めてください。


■ 参考になりそうなHP
- 安心と信頼のクラスメソッド
https://dev.classmethod.jp/articles/introducing-aws-gateway-load-balancer/

- 公式BlackBeltのパワポ資料
https://www.slideshare.net/AmazonWebServicesJapan/20210331-aws-black-belt-online-seminar-gateway-load-balancer
GitLab社内の運用がグダグダすぎる

# GitLab社内の運用がグダグダすぎる

私のお勤めの会社で使ってるのは無償版だし、何ならブランチ名に「＃」使わないでって言うだけでいいので、正直そんなに困らないというか・・・そもそも無償版を使わせてもらってる身なので、そもそもいうべき身ですらないんですけどね・・・（炎上覚悟でいいますけどね）

けど6か月も放置されて、担当部署が決まらないと責任の押し付け合いをissueで見せられてお怒りの有償プランご加入の困ってる人や会社多いんじゃないかなと同情を禁じ得ないわけですよ・・・

すべてオープンなので問題の原因とか見えて助かるんですけど、そういう責任の押し付け合いとかも見えてしまうので、良くも悪くも欧米の会社らしくて素敵だなと（笑

私のお勤め会社は2か月か3か月前から指摘され始めたので、実際にエラー原因入ってしまったのはそれぐらいからかもしれませんが・・・

◇問題のこれ
https://gitlab.com/gitlab-org/gitlab/-/issues/364565

「An error occurred while fetching commit data.」なんかでGitLabのサイト上で検索してもらえると責任の押し付け合いが見えてきてイラっと来ますｗ

P.S. 私個人的にはGitLabがそれでも好きなんですが、上記のようなBugが解消されないということでGitHub Enterpriseに切り替えたというお話や平行運用してるというお話を割とあちこちから聞きます。というかGitLabを提案したら（笑）ってなるんですｙ・・・勘弁してください・・・
人生初のQiitaに大量アウトプットを出してみての感想

# 概要


勢いで始めたひとりアドベントカレンダーも残すところあと2記事となりました。

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

実はこれまで技術的な記事を書いたことがほとどなかった（Qiitaの投稿数も3記事程度）だったのですが、このアドベントカレンダーを通して25記事を投稿することになります。

今回のアウトプットを通してまた新たな発見や気づきがあったので、今回の記事では振り返りながら気づきを共有したいと思います。


# 2022年のひとりアドベントカレンダーの継続に必要だったこと

## 周りにコミットする

一人アドベントカレンダーを作成したのが11/5でした。

https://twitter.com/isaka1022/status/1588690298112479234?s=20&t=n2Blz9SJTDjSUWmVaJE9rQ

このときからなんとなくやるぞ！という意思は持っていましたが、「継続できたらよいなくらいの温度感でした。

それが本気になったのは、職場のアドベントカレンダーの話が出たときに軽い気持ちで「今年は一人アドベントカレンダーやるんですよね〜」と話したときです。
その話がふとしたときに部署、あるいは部署横断で伝わってしまったので、やらざるを得なくなりました。
よく「継続したいことがあるときには周りに宣言する」という話をこれまでも聞いてきましたが、今回初めてその効果を実感しました。一度言ったからには途中で簡単には止められない意地のようなものが出てきました。

![スクリーンショット_2022-12-19_0_44_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238254/5a1be8f1-2af6-87ba-b271-cdb8f5f424ca.png)


## 事前のブレストでネタをストックしておく

以前に会社のブログ記事を書く際に、部署全体でブレスト会をやったのがよかったです。
今回はひとりでの投稿になるので、まずはネタ出しをひとりでやりました。
具体的には、Slackの個人チャンネルや、Notionを1年分眺めながら、記事にできそうなものをまとめていきました。

実施したのが11月の下旬だったのですが、いざ12月に入って書くネタがない日は書くことのハードルがすごく上がったので、ブレストを最初にやって執筆のハードルを下げることができてよかったです。

## 少し余裕を持って下書きを書いておく

12月に入った段階で、翌々文の2記事がある状態でのスタートになりました。
やはり毎日記事を書き続けるのは、業務が遅くなったり疲れていたり、イレギュラーがあったりとなかなか大変です。
そんなときにこの少し先まで記事の余裕がある状態が心理的な余裕になりました。

平日の稼働が忙しくても下書きを公開すればよいだけなので、公開ペースを維持できます。
「土日にまとめてやろう」と思っても1日書けて2,3記事が限界だったので、ストックしておいてよかったなと思いました。


# アドベントカレンダーを通して気づいたこと
実際に発信をしてみて気づいたことです。

## どんな課題を解決したかったのかが大事

初日にこちらの記事を見させてもらって、すごく大事なことに気づきました。
それは、価値のあるアウトプットにするにはその技術を使って「どんな課題を解決したかったのか」という具体的な事例の詳細が必要だということです。

https://qiita.com/MinoDriven/items/6718b5e70e3fb321ff9b

最初のブレスト段階では、僕の調べた技術記事のリンクが集まっていて、網羅的にまとめを作成しようかと思っていたのですが、勉強したことをまとめるような記事ではあまり他の人の役に立たないことに気付かされました。
結果、調べたものについての記事は書かず、自分がやったことベースで書いていこうという方針に変えました。

何か取り組んだ課題がないと、書くものもありません。
普段から「何の課題に取り組んでいるのか」を意識しながら、取り組む課題の数や大きさを少しずつ増やしていくことが大事だなと思いました。

## 日頃のメモが役に立つ

また今回アウトプットを出すにあたって、日頃のメモがかなり役に立ちました。

いつも、技術的なことを調べ始める前にSlackの分報チャンネルに、
1. 困っていることを投稿
1. スレに続ける形で調べたことを投稿
1. わかった原因
1. 解決した方法

の順でメモを残すようにしているのですが、これが合ったおかげで発信することがまとめやすかったです。
こちらは継続していこうと思います。


## 言葉にすることで解像度が上がる・再現性ができる

記事として自分がやったことを言語化していく過程の中で、自分の中で知識があいまいな箇所を見つけることができました。
文章にする際には、論理が通っていることを頭の中で整理するので、文章できない箇所、名前の呼び方がわからない箇所、ふるまいはわかっているけど内部の仕組みを理解できないことなどを調べる機会になりました。

技術以外の記事についても、改めて自分の普段の開発のやり方を振り返りながら自然とできていることや無意識的にやっていることを言葉にしてまとめることで、他の人に伝えやすい形で残しておくことができました。

## もっと貢献したいという意思が芽生える

また、これまでは読むばかりだった記事を初めて自分で書いてみると、なかなかに骨が折れる作業でした。
いつも発信したりまとめてくれる技術者の方がいるから自分の開発をできていることを考えると、自分もいつかコミュニティに他対して恩返しできるような知見を貢献したいという思いが芽生えてきました。


# まとめ

ということで、結論としてこれまであまりやったことがなかったアウトプットをたくさん出してみて、自分の中で色々整理されたり、新しい気付きや学びが合ってとてもよかったです。
これを機に、これからも発信頑張っていきたいと思います。
QRコードについての超基本知識

# １．QRコードって？
今や1日に1回は目にするといっても過言ではないQRコード。
まず<a herf="https://ja.wikipedia.org/wiki/QR%E3%82%B3%E3%83%BC%E3%83%89">wikipedia</a>より定義を確認します。
>QRコード （キューアールコード）は、 1994年 （ 平成 6年）に自動車部品メーカーである デンソー （ 愛知県 ）の開発部門（現在は分社化して デンソーウェーブ ）が 発明 した マトリックス 型 二次元コード である 。 「QR」は Quick Response の 頭字語 であり、高速読み取りを目的の一つとしている名称である。

![qrコードストーリー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003921/47344b40-24d8-abbd-2fdf-1fdfff66daf7.png)
(画像引用：https://www.denso-wave.com/ja/technology/vol1.html)

:point_up:QRコードを読み取ると、アプリのダウンロードURLやお店のURLがよく出てきますが、テキストならなんでも格納できるので、データをネットワークにつながずにデバイスに格納することも可能です。


# ２．作った人は？
デンソーウェーブ 原昌宏さん。もともとバーコードの開発者。
![原さん.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003921/d94cc681-004a-0115-042f-3c5a33b9998d.png)
(画像引用元：https://king.mineo.jp/staff_blogs/2029)
そのバーコードについて現場課題解決のため、新たなコード開発に取り組むことになりました。

# ３．思わず話したい技術の話

## なんでバーコードじゃだめなの？
QRコードは「業務現場での使用に強い」ことが特徴。

|種類|汚れに対して|
|:-----------|:------------|
|2次元バーコード|汚れがつくと読み取れない|
|QRコード|コードの一部が汚れで欠損しても正しく読み取ることができる「誤り訂正機能」でこの問題をクリア|

製造現場では油など汚れがつくのは当たり前の環境。
「誤り訂正機能」で「元々はこうだったはず」と訂正して、正しいデータを取り出すことができます。

## なんでいろんな方向からでも読み取れるの？(コードの上下とかを気にしなくていい)
・切り出しシンボルとよばれる、**3つの四角**のおかげ。
　QRコードの位置・大きさ・傾きを検知している。
　→まずスマホをかざしたとして、どこにQRコードがあるかを把握する必要がある。まわりに文字や似たような形のオブジェクトがあっても正しく把握する。
・このシンボルはただの適当な四角ではなく、「1:1:3:1:1」の比率が反映されている。
　→世の中にある四角のオブジェクトと区別できないと、デバイスはこのコードを抽出できない。

## 「1:1:3:1:1」の信頼性は？
![qrコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3003921/4edac34c-92cc-0e3a-226a-47d8ae661c31.png)
(画像引用元：https://king.mineo.jp/staff_blogs/2029)

・原さんチームは、チラシや雑誌、段ボールなどに印刷されている絵や文字をすべて白黒に直して、その面積の比率を徹底的に調べ上げることにした。
・開発チームは数えきれないほどの印刷物の調査を日夜続け、とうとう印刷物の中で「一番使われていない比率」を突き止めた。

## 情報量に差があるのにほとんど似たような見た目なのはなぜ？
　例えば、めちゃくちゃ長いURLコードと、3文字だけの情報量だと全然バイト数が違う。それでも似たような見た目。なぜか？
・「誤り訂正機能」を行うために、たくさんの情報が付与されている。
・QRコードは最大30％の面積が破損しても読み取れる。
・白と黒の比率が約半分ずつになるよう調整している
　
>「1:1:3:1:1」が偶然現れて、読み取りに支障をきたしてしまうことがあるからです。そこで、あらかじめ用意された8種 類のマスクパターンと重ね合わせて、その中から「1:1:3:1:1」の比率が極力少ないものを「今回のQRコードはこれ」と採用しています。




 (引用元：マイネ王β版　<a herf="https://king.mineo.jp/staff_blogs/2029">『なぜQRコードはこんなに広まった？　仕組みとスゴさを作った人に聞いてみた』</a>)
　
   
# ５．QRコードの今後

・画像データも載せたい
・データ量増加
・セキュリティ向上


# ６．この記事の参考文献

DENSO QRコード開発ストーリー

https://www.denso-wave.com/ja/technology/vol1.html

マイネ王　なぜQRコードはこんなに広まった？　仕組みとスゴさを作った人に聞いてみた

https://king.mineo.jp/staff_blogs/2029

多くの人に使ってもらうにはかなりの心配り(UX)が必要です。この開発のお話はDXを考える上でとても勉強になります。
ハッカソンで役に立つサービス（Amazon S3）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の10日目の記事です。
本日は、ハッカソンで役に立つサービス**Amazon S3**について書きます。

## S3とは
一言でいうと、『**AWSのストレージサービス**』です！

公式ドキュメントの説明
> Amazon Simple Storage Service (Amazon S3) は、業界をリードするスケーラビリティ、データ可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービスです。あらゆる規模や業種のお客様が、データレイク、クラウドネイティブアプリケーション、モバイルアプリケーションなど、事実上あらゆるユースケースで、あらゆる量のデータを保存、保護することができます。コストパフォーマンスに優れたストレージクラスと使いやすい管理機能により、コストの最適化、データの整理、特定のビジネス、組織、コンプライアンスの要件を満たすきめ細かなアクセスコントロールの設定を行うことができます。

https://aws.amazon.com/jp/s3/

## S3を使うメリット

### 1. 他サービスとの連携が簡単
**Lambda**などと連携して、画像や動画を保存することができます

### 2. データ上限がない
データの総量に制限はありません

### 3. 費用が低い
無料枠が用意されています

https://aws.amazon.com/jp/s3/pricing/?loc=ft#AWS_Free_Tier
【Shell】エスケープ文字を含むJSONを出力する

## やりたいこと
シェルスクリプトで以下のようなエスケープ文字を含むJsonファイルを出力したい

```json
{
    "hoge": "fuga",
    "nested_json": "{ \"hoge\": \"fuga\"}"
}
```

ネストしたjsonの中でエスケープ文字を使うときなど、上記を実現するためには`\"`といったエスケープ処理自体をエスケープして出力する必要がある。  


## 解決策

`\\\"`を使う。  

```sh

json="{\"hoge\": \"fuga\", \"nested_json\": \"{\\\"hoge\\\": \\\"fuga\\\"}\"}"

echo $json > result.json
```


## 結果

```json
{"hoge": "fuga", "nested_json": "{\"hoge\": \"fuga\"}"}
```

![スクリーンショット 2022-11-16 17.15.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/98ef3309-564f-d3d1-749f-c7c8a9a6420f.png)


syntaxエラーが出ずに無事出力できました！
ハッカソンで役に立つサービス（AWS DynamoDB）

# はじめに
この記事は[**ハッカソン Advent Calendar 2022**](https://qiita.com/advent-calendar/2022/hackathon)の9日目の記事です。
本日は、ハッカソンで役に立つサービス**Amazon DynamoDB**について書きます。
## DynamoDBとは
一言でいうと、『**AWSのNoSQLデータベースサービス**』です！
公式ドキュメントの説明
> Amazon DynamoDB は、ハイパフォーマンスなアプリケーションをあらゆる規模で実行するために設計された、フルマネージドでサーバーレスの key-value NoSQL データベースです。DynamoDB は、内蔵セキュリティ、継続的なバックアップ、自動化されたマルチリージョンでのレプリケーション、インメモリキャッシング、データのインポートとエクスポートツールを提供します。
https://aws.amazon.com/jp/dynamodb/
### NoSQLとは(AWS公式ドキュメントより引用)
> NoSQL データベースは、特定のデータモデル専用に設計されており、最新のアプリケーションを構築するための柔軟なスキーマを備えています。NoSQL データベースは、開発、機能性、パフォーマンスを大規模かつ容易に実現できるという点で広く評価されています。このページには、NoSQL データベースを理解して使用するための参考資料が含まれています。
https://aws.amazon.com/jp/nosql/
## DynamoDBを使うメリット
### 1. SQLの知識が不要
**DynamoDB**は原則API経由で操作します
### 2. クラウド（AWS）の知識がほぼ必要ない
サーバの構築が必要ないので、知識がない人でも環境構築できます
### 3. 費用が低い
無料枠が用意されています
https://aws.amazon.com/jp/dynamodb/pricing/?loc=ft#Free_tier
Ajaxの文法（Jacascript, Laravel）

## 始めに
Ajaxをよく使うので備忘録として作成しました。

Ajaxとは、非同期でサーバーとやり取りしてくれる機能のこと。
（要は、バックエンド部分の一部分を非同期で流すことができる。）
だから処理が早い！

## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __jQuery__ | 1.12.4 |
| __Laravel__ | 8.83.19 |
| __PHP__     | 7.3.10  |

## Ajaxの文法
ここさえ文法的に押さえておけば、最低限のものは書けるのかなと考えています。

```javascript:script.js
// Ajax機能
$.ajax({
    url      : "処理したいメソッドのURL",
    type     : "送信形式（POST か GET）",
    data     : "渡したいデータ",
    cache       : false,
    contentType : false,
    processData : false,
    dataType : "json"
})
// Ajax通信が成功した時
.done(function(json){
    // サーバー（Controller側）からのreturn値を受け取る
    var receivedData = json.receivedData;
    console.log(receivedData);
      alert('Ajax通信が成功しました。');
})
// Ajax通信失敗した時
.fail(function(jqXHR, textStatus, errorThrown){
    alert('Ajax通信に失敗しました。：' + textStatus + ':\n' + errorThrown);
});
```
文法通りに書いてもAjax通信が失敗する場合
→ パラメータをいじってみると通ることがよくある。
例：typeのPOSTをGETにしてみる
　　cache, contentType, processDataをいじってみる、削除してみる 

## 終わりに
最後まで閲覧ありがとうございました。
ご指摘、ご意見ありましたらコメントよろしくお願いします。
Google UXデザイン：デザインシステム（ステッカーシート）

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<details><summary>これまでの振り返り</summary>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d371bce4-836a-0ba5-fd7d-9d2e55f1b909.jpeg" width="700">

</details>

# ステッカーシートとは

ステッカーシート（デザインキット）は、デザインシステムの一部を構成する要素やコンポーネントの集合体です。

次は、あるアプリのステッカーシートの例です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7f6d2200-885b-93eb-b116-b3e00a63c1ed.png" width="６00">

ここには、デザインで頻繁に使用する色、ボタン、アイコン、ナビゲーションバーが含まれています。これにより、私のデザインにミスや矛盾が生じるのを防ぐことができるのです。

では、なぜこれがステッカーシートという名前なのでしょうか？

それは、コピー＆ペーストでデザインに貼り付けられるように、それぞれの要素を比喩的にはがせるからです。かっこいいでしょう！

# Figmaでステッカーシートを作成する

コンポーネントは要素から構成されています。例えば、ボタンは、文字、色、形などの要素で構成されるコンポーネントです。Figmaでは、コンポーネントは再利用可能です。


Figmaでは、最初に作ったコンポーネントをコンポーネントとしてラベル付けし、このコンポーネントのコピーをコンポーネント・インスタンスとして参照することができるのです。そして、コンポーネントがどこにあるのかを把握しやすくするために、ステッカーシートに配置することにしました。これで、コンポーネントに変更を加えるたびに、インスタンスにも変更が反映されるようになりました。


例えば、ステッカーシートのプライマリボタンの色をオレンジから青に変更すると、メインコンポーネントに結びついたインスタンスも同様に更新されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/489416a4-7d93-676e-a749-87447a0b606e.png" width="６00">

これで、ちょっとしたデザイン変更のたびに何個もボタンを更新する手間が省けますね。さらに、これまで散々言ってきたような一貫性を高めることができるのです。

ステッカーシートを作るのはとても簡単です。空白の枠を作り、その中によく使う要素やパーツをコピーして貼り付けるだけで、簡単にステッカーシートができます。

# Figmaでコンポーネントを作成する（例）

#### Step1:　Create component
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e4434cc6-1386-6313-60d1-65737fba0055.png" width="500">

#### Step2: 作成したComponentをコピーしてみる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e3013637-8c28-99fd-33d3-d6434afeec9e.png" width="400">


#### Step3: コピーもとのComponentをカスタマイズすると、コピー先も同期される（ここでは色を変更）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/01efeb74-4171-2381-7e97-94aac5af4658.png" width="５00">

# ステッカーシートのメリット

このステッカーシートは、デザインに携わる他のUXデザイナーや、コードを使って各コンポーネントを構築する必要のあるエンジニアに役立つことでしょう。例えば、

- 他のデザイナーと一緒にプロジェクトを進める場合、スタイルガイドとしてステッカーシートがあれば、2人のコミュニケーションがより円滑になります。

- デザインチームが大きくなっても、ステッカーシートがあれば、社内でデザインの一貫性を保つのに非常に役立ちます。チームメイトが角の丸いボタンを使っているのに、自分は角の尖った長方形のボタンを作ってしまうということがなくなります。

- デザインプロセスの途中でデザイナーがチームに加わった場合でも、すでにプロジェクトに割り当てられているデザイン要素にすぐに取りかかることができます。
SwiftUIで認証コード画面実装

## 概要
認証コードを受け付けるような画面をSwiftUIで実装しようと思います。
1文字入力したら、次のフィールドへフォーカスしたり、backspace押下でフォーカスを一つ戻します。
また、アーキテクチャにはMVVMを使用しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/d475c7d2-eb8c-7683-b7e5-ce2ea5b2da5d.png" width="200" />

## 環境
`Xcode 14.2`

## 実装
まず、`UIViewRepresentable`を使って`UITextField`をSwiftUIで扱えるようにします。
`updateUIView`を使って、テキストフィールドのフォーカスを制御します。
ざっくり以下の手順を想定してます。
1. `UITextField`をSwiftUIで扱えるようにする
2. ViewModelでフォーカス中のフィールド情報を更新する

### `UIViewRepresentable`
注目すべきところは、引数で`tag`, `focusTag`を受け取っていることです。
focusTagは現在画面でフォーカスが当たっているフィールドのタグです。
`tag`と`focusTag`の値が等しい時にフォーカスを当てます。

```swift
struct AuthCodeTextFieldRepresentable: UIViewRepresentable {
  ...
  @Binding var focusTag: Int?

  ...
  private let tag: Int
  ...

  init(
    ...
    focusTag: Binding<Int?>,
    ...
    tag: Int,
    ...
  ) {
    self._focusTag = focusTag
    ...
    self.tag = tag
    ...
  }

  ...
  func updateUIView(_ uiView: BaseUITextField, context: Context) {
      if uiView.tag == focusTag {
          uiView.becomeFirstResponder()
      }
  }
  ...
}
```

### ViewModel
現在フォーカスしているフィールドの情報はViewModelで管理します。
最初はどこにもフォーカスさせないので、nilで初期化しています。
`UITextField`の入力イベントは`PassthrouSubject`を使うことで受け取っています。

```swift
class HomeViewModel: ObservableObject {
  ...
  @Published var focusTag: Int? = nil
  ...

  ...
  private func subscribeEditingChanged() {
    editingChangedSubject
      .receive(on: DispatchQueue.main)
      .sink { [weak self] _ in
          guard let self = self else { return }

          if self.focusTag == .zero {
              self.focusTag = 1
          } else if self.focusTag == 1 {
              self.focusTag = 2
          } else if self.focusTag == 2 {
              self.focusTag = 3
          } else if self.focusTag == 3 {
              self.focusTag = 4
          } else if self.focusTag == 4 {
              self.focusTag = 5
          }
      }
      .store(in: &cancellables)
  }
  ...
}
```

ソースコードを[こちら](https://github.com/h-taro/auth-code-demo)に添付します。
老舗SIer歴12年から事業会社に転職し感じた違い

## はじめに

老舗SIerで12年働いた後、事業会社に転職し、4年ほど経ちました。
そこで私が感じた違いを紹介します。
あくまで私の置かれた状況の違いのため、全てに当てはまる内容ではありません。

## 職場環境

|-|老舗SIer|事業会社|
|:----|:----|:----|
|年齢層|平均40|平均33|
|部署の人数|50人|10人|
|チーム人数|10人|5人|
|PC|Windows|Mac|
|言語|COBOL/Java|Node/Rails/PHP|
|服装|スーツ|私服|

## チーム

|-|老舗SIer|事業会社|
|:----|:----|:----|
|メンバー構成|PL * 1<br>サブリーダ * 2<br>SE * 3<br>PG * 5|PdM * 1<br>企画 * 2<br>デザイナ * 2<br>エンジニア * 5|
|プロジェクト全体人数|50〜100人|10人|

## プロジェクト管理

|-|老舗SIer|事業会社|
|:----|:----|:----|
|進捗報告先|PM<br>社内（品質管理部）<br>社内（部内定例）|チーム内で完結|
|管理方法|WBS|チケット|
|遅延時の対応|遅延報告<br>残業or増員対応<br>リスケ|遅延報告<br>リスケ|
|プロジェクト開始時|プロジェクト計画書を作成|インセプションデッキを作成|

## 期待されること

|-|老舗SIer|事業会社|
|:----|:----|:----|
|チーム|要求通り80~100点の成果を出す|必要なものを必要なタイミングで提供する<br>要求通りにの結果にならない場合もある|
|個人|遅延をしない、予定通り対応する|チームの成果を追求<br>個人の進捗は重要視しない|

## 開発工程

|-|老舗SIer|事業会社|
|:----|:----|:----|
|要件定義|顧客or別チームが実施<br>共に工数見積もりが必要|チーム内で実施|
|外部設計/基本設計|SEが設計<br>- 画面設計<br>- 機能設計<br>- DB設計<br>- テスト計画|設計〜ITまでをエンジニアが一括で担当|
|内部設計/詳細設計|SE/PGが設計<br>- プログラム設計<br>クラス設計|ここに該当する成果物はない|
|PG|PG or 外部委託|設計〜ITまでをエンジニアが一括で担当|
|UT/単体テスト|PG or 外部委託<br>単体テスト設計~実施<br>外部委託の場合、受け入れテスト|設計〜ITまでをエンジニアが一括で担当|
|IT/結合テスト|結合テスト設計~実施<br>他チーム結合の場合、専用の環境でテスト実施|設計〜ITまでをエンジニアが一括で担当|
|ST/システムテスト|シナリオに従ったテスト実施<br>システム部門主観|企画担当による動作確認|
|UAT/ユーザ受け入れテスト|ユーザ部門主観で動作確認|ここに該当する成果物はない|
|リリース|要件定義、外部設計時に決めたリリース日にリリース|テスト完了後最短のリリース日にリリース|

## 体感

SIer時代は、進捗報告に向けた、タスク消化に追われていました。職位が上がってもメンバーからリーダーになるだけで考えることは同じです。
事業会社では、ユーザへの機能提供を十分な機能で必要なタイミングまでにリリースすることだけを考えています。

また、プログラミングに対する考えの違いも大きくあります。
SIer時代は、設計通りに実装することが重要なので、PGは初心者メンバーや協力会社メンバー、オフショアに出すことが多かったです。SEやPLになるとプログラミングをすることはほぼなくなります。毎日Excelを触っているだけです。
事業会社では、設計からエンジニアが一括して担当するため、マネージャーにならない限りプログラミングを全員が担当します。

このため、事業会社に転職してくるときに、PM/PLを経験してプログラミングと遠ざかっていた期間も長かったため、私は技術力はないと判断されました😅
この経験から、SIerから事業会社のエンジニアに転向する場合は、２０代の早いタイミングで行うことをお勧めします。

## 最後に

SIerと事業会社の両方の経験から記載してみましたが、どちらかが良いと判断するものではありません。私もまたSIerに転職するかもしれませんし。
SIerについては、経験したのが4年以上前でコロナ禍で状況は大きく変わっているかとも想像します。


複数の項目で記載しましたが、

- 進捗管理や枠組みのは、SIerがしっかりしている
- ユーザやプロダクトとの距離は、事業会社が近い

ざっくりこのような感想です。