OmniAICreator/Qiita-1.07M huggingface dataset:
LogicAppsでbuilt inコネクタの実行結果が「入力なし、出力なし」になってしまう件

### はじめに
LogicAppsで開発をしていたらコネクタは正常に処理してるみたいなのに、「入力なし、出力なし」になっている。なんてことがあります。これにはちゃんとした原因と解決方法があるので、解説していきます。

コミュニティを見てると以下に同じハマり方をしている人がいました。
https://learn.microsoft.com/en-us/answers/questions/1841474/logic-apps-run-history-inputs-outputs-private-endp

## 目次
+ [現象について](#現象について)
+ [原因](#原因) 
+ [解決方法](#解決方法)

## 現象について
LogicAppsでワークフローを起動して、実行履歴から各コネクタの実行状況を確認します。
すると、以下のように「入力なし、出力なし」に・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/e91ba49f-13aa-4121-8ee4-157f9b673308.png)


でも処理は正常終了してるしどうして！？となります。
恐らく以下条件下での発生かと思います。
+ LogicAppsはStandard構成
+ Vnet統合

## 原因
「入力なし、出力なし」はLogicAppsの受信トラフィックを使用するコネクタが多いため、受信トラフィックを拒否しているのが原因です。

では、なぜbuilt inコネクタは正常に動作することがあるのか。
それは、Vnet統合を設定しているとbuilt inコネクタは内部ネットワークを経由してエンドポイントにたどり着くことで正常に動作したということになります。

イメージにするとこんな感じですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/6c210978-4f28-404d-9d16-209f42ac02bf.png)

## 解決方法
解決方法は以下2つです。
①LogicAppsのFirewall設定で個人端末のIPを許可する。
一番手軽なのはこの方法です。以下手順できます。
1. 「IP確認くん」で端末のグローバルIPアドレスを確認する
1. [LogicApps] - [ネットワーク] で以下の部分をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/77068577-4496-4e9b-8115-7fd0a2327d50.png)
1. 以下赤枠の通り設定して、追加を入力し「1」で確認したIPアドレスの受信トラフィックを許可
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/17c4ccc4-d705-400d-be87-9cdf4319802a.png)

② プライベートエンドポイントを構成して、内部ネットワークからアクセスする。
先ほどの①と比較して、よりセキュアな構成で実現できます。商用利用のワークロードであれば、こちらの構成を検討してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678759/6ed5a4ae-12e2-4789-ab16-a34912ad3a41.png)

簡単に説明すると、Bastionを介して踏台用の仮想マシンへアクセスしプライベートエンドポイント経由でLogicAppsへ接続します。
妊婦Webデザイナーがエンジニア目指すってよ

# 私について（いま）
横浜で個人事業としてWeb制作をやっています。

前職は地方公務員。
将来の安定を考えて就職したものの、大好きな「なにかを作ること」を仕事にしたいという思いを捨てきれず退職。
「なにか」をWebの世界に求め、オンラインスクール①で一通りの勉強をしてWeb制作者になりました。

その後運良くクラウドソーシングサイトで制作会社にご縁をいただき、保守・修正を中心にHTML、CSS、WordPressまわりを実地で学びました。
2021年に第1子を妊娠・出産。
妊娠前はそこそこお手当をいただいていましたが「今の技術力では他の会社で生きていけない」と二度目の一念発起。
オンラインスクール②で0→1（企画、設計、デザイン、コーディング）を学び、ありがたいことに企業様から業務委託契約をいただいたり、個人様・企業様のサイトを0ベースで作らせていただいています。

本当に人生素晴らしいご縁に恵まれまくって、なんとかWeb制作者として生かしていただいていますが、AI等の技術発展によりWeb制作業はオワコンとも言われる未来を常に恐ろしく考えています。



# 私について（これから）
先ごろ、第二子の妊娠がわかりました。
そして三度目の一念発起をして、本格的に憧れのエンジニアを目指すことにしました。

3歳になった第一子と暮らしていくだけでもバタバタなのに、ここからさらに家族が増えるとなると、やはり「短時間で効率的に技術を高め、できること、仕事の質を高めていく」ことが大事になると考えています。

二回目の一念発起のときもそうでしたが、やはり子供に恥じない母でありたい。
仕事を誇りに思えるような母でいるために、私は本気で勉強をしていきたいです。

作ってみたいものはいろいろあるので、短期的にはまず今ぼんやり頭の中にあるアイデアを形にするための設計を、技術を学びながら固めていく。
中期的には、身近な方にテストをお願いしながら、サービスの精度を上げていく。
子供を産む前にサービスは（β版でも）1つリリースできたらいいなと思っています。

長期的には面白いことを思いついて実現したい同士の方を見つけて、一緒に面白いものを作っていけたらとぼんやり考えています。

どうぞよろしくお願いいたします
Power Automate と Teamsで承認フローを作成して Outlook に結果を飛ばす方法

## はじめに
この記事では Share Point リストと Power Automate そして Temas を使用した初歩的な承認フローの作成方法について解説したいと思います！

## 作成方法
1\. Power Automateにサインイン
+ 　Power Automate にサインインして、フローの作成を開始します。

2\. 新しいフローを作成
+ Power Automateのホーム画面で「+ 作成」をクリックします。
+ 「自動化されたフロー」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/784019b0-f215-9b14-e456-2c1393d49a79.png)

3\. トリガーの選択と設定
+ Share Point の「項目が作成されたとき」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/b2f51f36-7e25-4d8b-8470-93386644a623.png)

+ 次にそのトリガーに関連する設定を行います。
サイトアドレス：使用する Share Point サイトの URL を選択します。
リスト名　　　：フローをトリガーしたいSharePointリストを選びます。
+ 「新しいステップ」をクリックして、フローに次のアクションを追加します。

5\. アクションの設定
+ 「開始して承認を待機」を選択します。

| 項目 | 設定内容 | 必須 |
|:-:|:-:|:-:|
| 承認の種類  | カスタム応答...応答オプションを任意で設定可能| 必須|
|  | 承認/拒否...規定の回答オプション| |
|  タイトル |  任意で設定　【承認依頼】等 |必須|
|  担当者 | 承認申請の通知を飛ばす相手 |必須|
| 詳細 | 任意で設定　 |任意|
| アイテムリンク|作成されたリストへのリンク|任意|

今回は以下のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/381b7151-27a8-401a-81de-17faba9576ce.png)

+ 応答時のアクションの追加
応答が返ってきた時に、申請者へのメール通知と Share Point リストの申請状況の更新を行います。

**承認の場合**...申請者へ承認通知のメールと、Share Point リストの申請状況を `承認済み` に更新
**拒否の場合**...申請者へ拒否通知のメールと、Share Point リストの申請状況を `拒否` に更新

+ 新しいステップを追加して「条件」を選択して、以下の条件分岐を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/5a541955-f5a1-49fa-a8c6-1f273cc38182.png)

まずは **承認の場合** のフローを作成していきます。

+ **はいの場合** の中でアクションの追加を選択し Share Point の「項目の更新」を選択します。
サイトアドレス：トリガーで設定したサイトアドレス
リスト名　　　：トリガーで設定したサイトアドレス
ID　　　　　　：`項目が作成されたとき` のIDを選択
承認状況Value ：`承認` に変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/f3867b15-1f20-4cdb-b65a-a412c1e6c568.png)

+ アクションの追加で Outlook の「メールの送信(V2)」を選択します。
宛先：申請者のメールアドレス
件名：任意で設定
本文：任意で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/1b4e965d-f505-4ddf-9321-b71ea41691dd.png)


**拒否の場合** のフローを作成していきます。

+ **いいえの場合** の中でアクションの追加を選択し Share Point の「項目の更新」を選択します。
サイトアドレス：トリガーで設定したサイトアドレス
リスト名　　　：トリガーで設定したサイトアドレス
ID　　　　　　：`項目が作成されたとき` のIDを選択
承認状況Value ：`却下` に変更

+ 承認時と同様にアクションの追加で Outlook の「メールの送信(V2)」を選択し、メールの内容を設定します。

設定が完了したら `保存` を押して実際にリストを作成して動作を確認してみましょう。
Share Point リストにアイテムを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/667b247e-afb0-4823-b970-023c4341c532.png)


Teams のほうに承認要求が届きました。
コメントを入れて `承認` を押してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/af072d08-a3d9-4bfe-8764-d576b0ec41d5.png)

Outlook のメールに申請結果の通知が飛んできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/4139dd9c-2b21-484e-8626-2f406e0f4a02.png)


Share Point リストの `承認状況` も `承認` に更新されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719434/3575e4a5-6f88-41fa-ac7a-9d999bf46eb5.png)


## まとめ
今回は基本的な承認フローの作成方法について解説しました！
Share Point リストで解説しましたが Dataverse を利用したり、Power Apps アプリから承認申請をしたりと使い勝手はたくさんありますのでぜひ活用してみてください！！
HCP Terraform に key-value 形式のタグ機能が追加！Workspace や Project での管理が便利に

## はじめに

HCP Terraform の Workspace にはタグを設定できますが、従来はシンプルな文字列だけでした。
しかし、いつの間にか Workspace に key-value 形式のタグが設定できるようになっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/4ba17fb5-c950-4d0b-925b-19077821e989.png)

Workspace の key-value 形式でのタグ付けについて調べてみると、下記のブログで案内されていました。

https://www.hashicorp.com/ja/blog/new-in-hcp-terraform-linked-stacks-enhanced-tags-and-module-lifecycle-management

ドキュメントを辿ると、予約済みのタグキーも定義できるようです。
いくつか調査したメモを記載します。

## 予約済みのタグキーの定義

Organization 設定に `Tags` という項目が出現していました。
試しに Reserved Key に `env` というタグを定義してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/630438dd-56a8-489a-aabe-b8c6760bea46.png)

この状態で Workspace のタグ設定を開くと、下記のように key の候補として追加したタグが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/f061e3c9-e912-4a0c-9020-23b1703be70f.png)

また、Workspace の新規作成時にも候補が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/bb29ff85-22ed-4ba6-8745-8d4cec411519.png)

UI 上から Workspace を作成、更新する際に必要なタグを設定し忘れないようにする際に有効そうです。

:::note warn
2025/02/26 時点では beta 版の機能である旨が記載されているので、使用する際は最新のドキュメントを確認してください

https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/organizations/manage-reserved-tags
:::

## Workspace に key-value 形式のタグ付けをする方法

2025/02/26 現在は UI 操作と API からの操作がサポートされているようです。

API は下記の `Add/update tag-bindings on a workspace` を使用することになります。

https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#add-update-tag-bindings-on-a-workspace

terraform での設定について、2025/02/26 現在の最新の tfe provider v0.64.0 では未対応ですが、下記 PR で対応が進んでいるように見えます。

https://github.com/hashicorp/terraform-provider-tfe/pull/1543

現在シンプルな文字列でのタグ設定に使用できる `tag_names` の指定は非推奨になるかもしれませんね。

## terraform block の cloud block で key-value 形式のタグ指定で接続する方法

https://developer.hashicorp.com/terraform/language/terraform#connect-to-hcp-terraform

に記載されているように、**terraform 1.10 以降を使用すると** key-value 形式のタグ指定で接続できます。

```hcl
terraform {
  cloud {
    organization = "example_corp"
    workspaces {
      tags = {
        layer = "app"
      }
    }
  }
}
```

## Project へのタグ付け

ブログ記事の案内に記載されている通り、Workspace だけでなく Project にもタグ付けできることを確認しました。
こちらも予約済みのタグキーを候補として出してくれますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/91bc3fe9-7bce-4a66-a8e6-5a6beeee772b.png)

:::note warn
2025/02/26 時点では beta 版の機能である旨が記載されているので、使用する際は最新のドキュメントを確認してください

https://developer.hashicorp.com/terraform/cloud-docs/projects/manage#define-project-tags
:::

## まとめ

HCP Terraform Workspace や Project に追加された key-value 形式のタグ機能について紹介しました。
主なポイントは以下の通りです：

- HCP Terraform Workspace と Project で key-value 形式のタグが使用できるようになりました（Project のタグ定義は、2025/02/26 時点ではベータ機能）
- Organization 設定から予約済みのタグキーを定義でき、Workspace 作成・編集時に入力候補として表示されます（2025/02/26 時点ではベータ機能）
- key-value 形式のタグは、現在は UI 操作と API 経由での設定が可能ですが、tfe provider での対応は進行中です
- terraform 1.10 以降では、terraform block の cloud block で key-value 形式のタグを指定して Workspace に接続できます

この機能により、Workspace の管理がより柔軟になり、組織的なタグ付け規則の実装や環境の識別がしやすくなります。
ベータ版の機能のため今後変更される可能性もありますが、大規模な環境管理において有用な仕組みとなるでしょう。
【React】画像がクリックされたあと、一定時間その画像のクリックを不可能にする

# 目的
画像(imgタグ)をクリックすると処理が走るが、連続クリックしてしまうのを防止したい

## 前提
imgタグにonclick属性でクリック時の処理を記載


## 画像クリックを無効化する

```pointer-events: none;```にすることで要素のクリック、ホバーなどを無効化できる

onclickで渡されたevent.targetのpointer-eventsをnoneにする。
一定時間(Setinterval)経つと、auto に戻す

```jsx
event.target.style.pointerEvents = "none";
    setTimeout(function() {
      event.target.style.pointerEvents = "auto";
      console.log("クリック再開可能になりました。");
    }, 3000);
```


### 備考
画像が直接保存されたくない時などにも便利かも
【AWS】VPCの削除手順

## VPCの削除
1). VPCを開き作成したデータベースを選択し「アクション」→「VPCの削除」を押します。
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/c7e24e15-8fb3-4a06-abfd-12428d1df286.jpeg)



2). 「削除」と入力し、「削除」を押します。
![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/fb10fd62-2d59-42de-ac77-eafc022a2765.jpeg)



3). 削除されたことを確認して削除作業完了です。
![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/a9140e3f-9f8d-4814-961d-ccddcb6be984.jpeg)
【AWS】RDS DBの削除手順

## DBの削除
1). RDSを開き作成したデータベースを選択し「アクション」→「削除」を押します。
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/a8b25d5b-277f-4e59-8c26-fcce75d69c2b.jpeg)



2). 「delete me」と入力し、「削除」を押します。
![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/14cea9f8-ed9e-4abe-82a8-299b3d067047.jpeg)


3). 削除されたことを確認して削除作業完了です。
![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/81e83934-ae73-40ff-80b2-be26dd4ac154.jpeg)
KustoQuery(KQL)のクエリ結果を定数に変換する方法

# KustoQuery(KQL)のクエリ結果を定数に変換する方法

KustoQueryのクエリ結果を後続のクエリで定数として扱う方法についてご説明します。

クエリ結果が1行の場合に限定されますが、クエリ全体をtoscalar関数でくくってクエリ結果をスカラー値に変換することで、後続のクエリで定数として扱うことができます。

```KQL
let Column1Avg = toscalar (
Table1
| where TimeGenerated >= ago(30d)
| summarize Column1Avg = avg(Column1)
| project Column1Avg );
// ここまでで1つめのクエリ結果が Column1Avg という定数に変換されている
Table2
| where TimeGenerated >= ago(1d)
| summarize Column2Avg = avg(Column2)
| summarize Ratio = Column2Avg / Column1Avg
| project Ratio
```

用途としては、昨日分の全データの平均値が過去30日の全データの平均値と大きくズレていないかのチェックなどがあると思います。

以上、自分のメモがてら記事にしておきました。
テストのアイデアの組み立て方を簡単にまとめてみる

## はじめに
アプリを作った後はしっかり動作するかを確認するためにテストを書くことが重要です。本記事では、**Jest と React Testing Library** を使って、テストのアイデアをどのように組み立てるかを初心者目線で解説します。


## 前提とする環境
本記事の内容は、以下の環境を前提としています。

- Node.js 18 以上（`node -v` でバージョン確認）
- npm または yarn を使用（`npm -v` / `yarn -v` でバージョン確認）
- React 18 以上（`package.json` の `react` のバージョンを確認）
- Vite を利用した React プロジェクト
- Jest と React Testing Library を使用したテスト環境

---

## テスト環境の準備
まず、必要なライブラリをインストールします。

```sh
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
```

次に、`package.json` に以下を追加して、テストコマンドを実行できるようにします。

```json
"scripts": {
  "test": "jest"
}
```



## 基本的なテストの流れ
テストを書くときは、以下の流れで考えると分かりやすくなります。

### 「何をテストするか？」を決める
まず、テスト対象のコンポーネントで「正しく動いてほしい機能」をリストアップします。
(例)
- タイトルが表示されているか
- 入力欄に文字を入れて、登録ボタンを押すとデータが追加されるか
- 削除ボタンを押すとリストからデータが消えるか
- 入力なしで登録ボタンを押したときにエラーが表示されるか

### 「どうやってテストするか」を考える
Jest と React Testing Library を使って、どのようにテストするかを考えます。

| 目的 | 使用する関数 | 提供元 |
|------|------------|---------|
| コンポーネントを表示する | `render(<App />)` | React Testing Library |
| 画面から要素を取得する | `screen.getByText()` / `screen.getByTestId()` | React Testing Library |
| ボタンをクリックする | `fireEvent.click(button)` | React Testing Library |
| 期待する動作を確認する | `expect(...).toBeInTheDocument()` | Jest |

### テストコードを書く

例えば、「タイトルが表示されているか」をテストする場合、以下のコードになります。

📂 `tests/App.test.jsx`
```jsx
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import App from "../src/App";

describe("タイトル表示のテスト", () => {
  it("タイトルが 学習記録 であること", () => {
    render(<App />);
    const title = screen.getByText("学習記録");
    expect(title).toBeInTheDocument();
  });
});
```

### テストを実行する
ターミナルで以下を実行すると、テストが実行されます。

```sh
npm test
```

テストが成功すると `PASS` と表示され、失敗すると `FAIL` となります。



## まとめ
- Jest は「期待する動作になっているか？」を確認するためのツール
- React Testing Library は「React コンポーネントの動作をテストするツール」
- テストを書くときは、「何をテストするか？」→「どうやってテストするか？」→「コードを書く」→「実行する」の流れで考える

https://jestjs.io/ja/docs/getting-started

https://testing-library.com/docs/react-testing-library/intro/
【NetSuite開発者必見！】ユーザーイベントスクリプトからユーザーイベントスクリプトを呼び出せない！？③

こんにちは。Oracle NetSuiteパートナー EvangSolの湯浅です。
今回で最終回となります、弊社エンジニアが直面した、ユーザーイベントスクリプト（User Event Script：以下UE）からUEが呼び出せない事象について、具体的な対応策の後半部分とまとめについてご紹介いたします。

対応策3. Suiteletを利用する（リアルタイム処理＋ユーザーコンテキストの継承）
---
Suiteletを使えば、現在のユーザーコンテキストを継承したまま別の処理を実行できます。同期的に動作するため、フロントエンドの操作とあわせた処理が必要な場合に適しています。

手順例：
1.	Suiteletスクリプトを作成
2.	UE内で`N/redirect`を使ってSuiteletにリダイレクトし、必要なパラメータを渡す

コード例（抜粋）：
**〇ユーザーイベントスクリプト側**
```
/**
　　* @NApiVersion 2.x
　　* @NScriptType UserEventScript
　　* @NModuleScope SameAccount
*/
　　define(['N/log','N/redirect'],
　　function(log, redirect) {
　　　　function afterSubmit(context) {
　　　　　　// logging for test
　　　　　　log.debug({
　　　　　　　　title: '****************Start**************'
　　　　　　});
　　　　　　//The page will redirect to Suitelet on After Submit function and pass the parameter/s to it
　　　　　　redirect.toSuitelet({
　　　　　　　　scriptId: 'customscript148' ,
　　　　　　　　deploymentId: 'customdeploy1',
　　　　　　　　parameters: {
　　　　　　　　　　'recordId':'1273'
　　　　　　　　}
　　　　　　});
　　　　}
　　　　return {
　　　　afterSubmit: afterSubmit
　　　　};
});
```

**〇Suitelet側**
```
/**
　　* @NApiVersion 2.x
　　* @NScriptType Suitelet
　　* @NModuleScope SameAccount
 */
define(['N/record','N/log'],
function(record,log) {
　　function onRequest(context) {
　　　　var requestparam = context.request.parameters;
　　　　log.debug({
　　　　　　title: 'Parameter: Record ID',
　　　　　　details: requestparam.recordId
　　　　});
　　　　var objRecord = record.load({
　　　　　　type: record.Type.PURCHASE_ORDER,
　　　　　　id: requestparam.recordId,
　　　　　　isDynamic: true,
　　　　});
　　　　objRecord.setValue({
　　　　　　fieldId: 'memo',
　　　　　　value: 'Sample Comment',
　　　　　　ignoreFieldChange: true
　　　　});
　　　　objRecord.save();
　　}
　　return {onRequest: onRequest};
});
```
**Suitelet vs RESTlet：どちらを選ぶべき？**
| 比較項目 | Suitelet | RESTlet |
|:-:|:-:|:-:|
|UIの提供|可能（フォーム、HTML表示等）|不可（データ交換のみ）|
|アクセス方法|ブラウザ経由、内部スクリプト|API呼び出し(外部アクセス容易)|
|処理特性|同期処理（リアルタイム向け）|非同期処理(高速・バッチ向け)|
|外部連携|やや難しい|容易(統合ツールとの連携に最適)|
|パフォーマンス|比較的遅い(複雑処理で遅延有)|軽量で高速|
|権限管理|ユーザーセッションに依存|APIキーやOAuthなど簡易管理可能|


対応策4. ワークフローを活用する（ノーコードで解決！）
---
「そもそもコーディングしたくない」という場合には、NetSuiteのワークフロー機能を使うのも一つの手です。

手順例：
1.	レコード更新時のアクションをワークフローで設定
2.	必要があればアクションからスクリプトを呼び出し
ノーコードで比較的簡単に実装できるため、非エンジニアの方でも活用しやすい方法です。


まとめ – 最適な方法を選んでNetSuite開発を快適に！
---
「UEから別のUEを直接呼べない」というNetSuite特有の制約は一見厄介ですが、スケジュールドスクリプト・RESTlet・Suitelet・ワークフローなどを活用すれば、目的の処理を実現できます。
- 即時処理が必要：RESTlet、あるいはSuitelet
- 後でまとめて処理したい：スケジュールドスクリプト
- ノーコードで対応したい：ワークフロー

要件や運用体制に合わせて最適な方法を選び、NetSuiteでの開発効率をさらに高めていきたいものです。ぜひ今回の対応策を参考にしていただき、NetSuiteライフをより快適に過ごしていただければと思います。
個人的備忘録：ECR（Amazon Elastic Container Registry）でタグが付いていないイメージにタグを付ける方法

## はじめに

AWSのECR（Amazon Elastic Container Registry）を利用していると、タグが付いていないイメージが発生することがあります。

:::note info
***タグがないと、イメージの管理が難しくなるため、特定のタグを付与することで管理しやすくなります。***
:::

この記事では、ECRでタグが付いていないイメージに「test」というタグを付ける方法を解説します。

## 方法概要

タグが付いていないイメージに新しいタグを付けるには、以下の手順を実施します。

1. **ECRリポジトリのイメージをリスト表示**
2. **タグが付いていないイメージの****`imageDigest`****を取得**
3. **新しいタグを付与**

## 1. タグが付いていないイメージをリスト表示

まず、ECRリポジトリ内のタグが付いていないイメージをリスト表示し、その`imageDigest`を確認します。

### コマンド

```sh
aws ecr list-images --repository-name <リポジトリ名> --filter "tagStatus=UNTAGGED"
```

### 出力例

```json
{
    "imageIds": [
        {
            "imageDigest": "sha256:abcdef123456..."
        }
    ]
}
```

上記の出力例では、タグが付いていないイメージの`imageDigest`が `sha256:abcdef123456...` であることがわかります。

## 2. `imageDigest`を使ってタグを付与

取得した`imageDigest`に「test」というタグを付けるため、まずイメージのマニフェストを取得します。

### コマンド

```sh
aws ecr batch-get-image --repository-name <リポジトリ名> --image-ids imageDigest=sha256:abcdef123456 --output json | \
jq -r '.images[0].imageManifest' > manifest.json
```

次に、取得したマニフェストを使って新しいタグを付与します。

```sh
aws ecr put-image --repository-name <リポジトリ名> --image-tag "test" --image-manifest file://manifest.json
```

これにより、タグが付いていないイメージに「test」というタグが追加されます。

## 3. タグが正しく付いたか確認

タグが正しく付与されたかどうかを確認するには、以下のコマンドを実行します。

### コマンド

```sh
aws ecr list-images --repository-name <リポジトリ名>
```

このコマンドを実行し、指定したタグがリスト内に表示されれば成功です。

## まとめ

以上の手順で、ECRのタグが付いていないイメージに「test」というタグを付与することができます。

**手順のポイント**

- `list-images` コマンドでタグがないイメージを特定
- `batch-get-image` コマンドでマニフェストを取得
- `put-image` コマンドでタグを付与

これにより、ECR上のイメージを整理しやすくなり、運用がスムーズになります。***ぜひ試してみてください！***
Cursorエディタから謎の音🔔 

## 背景
ある時、Cursor(VSCode)エディタにて色々な音が鳴るようになっていました。
初めは可愛い音だったのでそのままにしていたのですが、途中から気が散る１つの要因になってしまってたので、今回はこの謎の音を消す方法について調べてみました。

## 音が鳴らないようにするには
設定で「Accessibility Support」をoffにします。(デフォルトはauto)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3985446/ac68b995-b9c8-4454-8078-1f01caac76b0.png)

## 補足
デフォルトでは「Accessibility Support」がautoに設定されていますが、「スクリーンリーダーを最適化」モードが設定されている際に音が鳴るようです。
このモードを切り替えることで音が鳴らないようにすることもできました。
- Macでは Shift + option + F1
- Windowsでは Shift + Alt + F1
上記ショートカットコマンドでモードの切り替えを手動で行うことができます。

私は急に鳴り始めたのですが、どうやら知らない間にスクリーンリーダーが最適化されてたみたいです。
Emit使い方

```parent.vue
<script setup>
import {ref} from 'vue';

const receiveData = ref({ id: '', name: '' });

const handleNode = (node) => {
  receiveData.value = node;
  receiveData.value = node;
  console.log('handleNode', receiveData.value);
}
</script>

<template>
      <!-- @data-sentが子コンポーネントから発火されるとhandleNodeイベントが発火する -->
      <NodeListLightVersion @data-sent="handleNode" />
</template>

```


```child.vue
<script setup>
import { ref, onMounted, defineEmits } from 'vue'
import { getAllNode } from '@/api/node'


// 親コンポーネントにデータを送信する
const emit = defineEmits(['data-sent'])

const nodes = ref([])

/**
 * 親コンポーネントへ送るデータ
 * @param event 
 * @param rowData 
 */
const sendDataToParent = (event, rowData) => {
    const item = rowData.item;
    emit('data-sent', { id: item.id, name: item.name });
}

/**
 * ページが読み込まれた時に実行
 */
onMounted(async () => {
    await fetchNodes();
})
</script>

<template>
    <v-container>
        <v-data-table :items="nodes" density="compact" @click:row="sendDataToParent">

        </v-data-table>
    </v-container>
</template>
```
個人的備忘録：スケールアウトとスケールインを言い間違えないように、体系的に言葉の意味を整理してみた

## はじめに

システムの負荷が増減する状況に応じて、柔軟にリソースを調整することは重要です。

特にクラウド環境では、効率的なリソース管理がコスト削減やパフォーマンス向上に直結します。そのため、多くのシステムでは「スケールアウト」と「スケールイン」といった概念が用いられます。

本記事では、それぞれの意味やメリット、具体的な活用例について解説します。

## 書こうと思ったきっかけ

私はよく言葉の単語を逆に考えてしまうことが多く、「スケールアウト」と「スケールイン」も混同しがちでした。
そのため、正しい意味や活用方法をしっかり整理しようと思い、本記事を書くことにしました。

また、ITスクールのハッカソンに参加している中で、負荷の変動に応じたインフラ構成の工夫が求められるケースがあり、改めて理解を深めたいと考えました。

## スケールアウトとスケールインとは？

### スケールアウト（Scale-Out）
スケールアウトとは、システムの負荷が増加した際に、サーバーやコンテナの台数を増やして処理能力を向上させる方法です。

https://knowledge.sakura.ad.jp/6217/

特にクラウド環境では、オートスケーリング機能を活用して、負荷に応じてインスタンスを動的に追加することが一般的です。

**メリット:**
- システム全体の耐障害性が向上する（単一障害点を回避）
- 必要な分だけリソースを増やせるため、柔軟な運用が可能
- 負荷が高い時に素早く対応できる

**具体例:**
- Webアプリのアクセスが増加した際に、ロードバランサーの下でサーバー台数を増やして対応
- バッチ処理を複数のコンテナで並列実行することで処理時間を短縮

### スケールイン（Scale-In）
スケールインとは、システムの負荷が減少した際に、不要なサーバーやコンテナを削減し、コストを最適化する方法です。

特に、長時間低負荷のままサーバーを維持すると、無駄なコストが発生するため、適切なタイミングでスケールインを行うことが重要です。

**メリット:**
- コスト削減（不要なリソースを削減）
- 管理の手間が減る
- 環境負荷を抑え、リソースの最適利用が可能

**具体例:**
- 夜間のアクセスが少ない時間帯にインスタンスを減らす
- 期間限定のイベント終了後に余分なサーバーを削減

## まとめ

スケールアウトとスケールインは、クラウド環境においてシステムのパフォーマンス最適化とコスト削減を両立するための重要な手法です。

:::note note
**特に、負荷の変動が激しいアプリケーションでは、オートスケーリングを活用することで効率的な運用が可能になります。**
:::

実際の開発や運用では、どのタイミングでスケールアウト/インを行うかが重要です。


## 参考文献

https://blog.future.ad.jp/scale-updown-outin
(QA) 「システム名は NS_JOB です。スキーマは QSYS2 です。」システム名とは何ですか？

[こちらの記事](https://qiita.com/gomAnomalocaris/items/a6a86c0529b83f377070)でご質問頂いた件、

IBM i サービス NETSTAT_JOB_INFO ビュー のマニュアルページ[(こちら)](https://www.ibm.com/docs/ja/i/7.4?topic=services-netstat-job-info-view)に記載のある、システム名　ってなに？という質問です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/e0844f3f-f92f-470e-b271-4dd799291af7.png)

上記の反転個所の記載です。
IBM i に精通していないといきなりわからないですよね。

## この場合の「システム名」とは何を指すか？

**答えはこの場合、「システム名」＝「IBM i OS上でのオブジェクト名」です。**

**なぜこういう事が起こるかというと、IBM i OS上のオブジェクト名は10桁まで、というOS/400時代の名残？仕様？制約？があるからです。**

IBM i サービスでは分かりやすくするために長い(10文字以上128文字までの）ビュー名、テーブル名、関数名を多用しているのですが、それらの実体としてのオブジェクトは10桁以内の名前を付けないといけない、という制約があるんですね。

## IBM i サービス NETSTAT_JOB_INFO ビューで確認してみる ##

それでは実際に確認してみます。
マニュアルページに記載からIBM i OS上のオブジェクト名は QSYS2/NS_JOB と分かっていますので、DSPFDコマンドでファイルの属性、DSPFFDコマンドでカラム属性を確認してみます。

### DSPFDコマンドでLF QSYS2/NS_JOB のファイル属性を確認する。

```
DSPFD QSYS2/NS_JOB
```
結果はこちら。１ページ下にスクロールしたものを転記しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/200e76da-d4bb-463c-acb2-bbffae703434.png)

上記のようにこのLFはSQLで作成されていることが確認できます。作成するDDLでNET_STAT_JOBINFO というビュー名が指定されていることがわかります。このビュー名はSQLで使用できる別名として指定されることになります。非SQLからは使用できない名前、とも言えます。RPGⅢのF仕様書のPF名等で指定したい場合は、実体オブジェクト名であるNS_JOBを指定する必要があります。


### DSPFFDコマンドでLF QSYS2/NS_JOB のカラム属性を確認する。

```
DSPFFD QSYS2/NS_JOB
```

上記コマンドの結果がこちら。
同様に１ページ下にスクロールした画面です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/21abdea4-f8f0-46f0-8317-fd9aa8c3234b.png)

一番上のフィールド属性を読み解くと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/5b5f0e2c-ca5a-4f1c-ad02-b90bdd821150.png)

**フィールド名 CONN_TYPE : LF上のフィールド名です。RPGⅢなどで非SQLで扱う場合はこのカラム名を指定します。SQLからも使用可能です**

**代替名 CONNECTION_TYPE : SQLからだけ使用可能な別名です。RPGⅢなどでは使用できません。**

代替名はSQLで10桁よりも長いカラム名、フィールド名を使用したい、というニーズから追加されたものです。

 
## IBM i OSシステム名（IBM i オブジェクト名）を使用したSQL実行例

ビュー名をNS_JOBに変えています。
```
  SELECT * FROM QSYS2.NS_JOB
  WHERE CONNECTION_TYPE = 'IPV4' ;
```
結果は下記のようにSQL別名を指定した場合と同じ結果が返ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/c0873b76-1aad-4767-94ae-d4b2e483aad1.png)


カラム名にシステム名 CONN_TYPE  を指定してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/95fa177c-096e-42ca-9db0-7378acd7b527.png)

SQL別名と同様に結果が返ります。
アドホックな勉強会とインセンティブについて

僕自身は、勉強会を９年ぐらい続けてきた。勉強会は直接お金にはなっていないが、僕も人間なので、生活するのにお金が必要である。やっぱりお金がほしいと思ってしまう。
勉強会を毎日のように続けてきたが、勉強会が直接お金になるのは違和感がある。参加者からお金を取れるかと言うと、普通にプログラミング初心者がお金を持っているとは限らない。お金持っている人だけがプログラミングを習得できる世界は、なにか歪んでいる気がする。
じゃあ、公金などを入れるべきかと言うと、僕もやってて思うけど、それもちょっと違和感がある。
公金を交付する人が勉強会をちゃんと監視できるかと言うと、それは無理だし、公金交付のための書類地獄は少し辛いと思う。使い方間違えると問題になる。「正しく」使わないといけないが、それが生産的とは限らない。
初心者も公金を交付する人も両方共通するのは、正しくインセンティブ設定をできるとは限らないということだ。正しくインセンティブ設定されないと、世界は余計に荒廃してしまう。寄付も同じである。その寄付は正しく使われているだろうか。寄付ドナーは、マーケティング戦略に影響されやすい。つまり、寄付などだと、実際の人助けより寄付ドナーへのマーケティングが優先される可能性がある。

これってオープンソースソフトウェアとお金の問題と似ている気がする。

では、僕としてはどうしたら良いと思うか、やっぱり勉強会は「能力証明」として使われるのが正しい気がする。それは部分的には（全面的に？）ポジショントークを含んでいるが、例えば、僕に関しては、勉強会を続けてきたということは、「何かの能力が確実に高い」ということである。それは技術能力とは限らないが。
それはオープンソースも似た側面があって、オープンソースのコントリビュータは、「何かの知識を確実に持っている」
それはネット上に動かぬ証拠として残る。
で、その、「確実に持っているなにかの知識や能力」のために、企業や顧客はある程度待遇に上乗せする合理性ができる。学位と同じ、ジョブマーケットシグナリングである。人的資本の育成も若干混じっているが。
それが、勉強会やオープンソース開発におけるインセンティブであっても良いのかなと思う。
「能力証明」がインセンティブの良い点は、インセンティブがかなり遅延して供給されるという点である。つまり、勉強会をかなり続けてから供給される。（多分１年ぐらい？）勉強会の場合、インセンティブが即金なのは有害である。

ということで、勉強会の主が、勉強会を続けていくには、勉強会に理解あるオープンソース系の会社を探すことが重要かもしれません。僕も無職状況でやってましたが、僕が考える以上に世の人は、無職に対して否定的な感情がある。
勉強会そのものでお金にしたくないというのも、無職や野良が世間で評価が低いということがある。お金をもらうと無職期間が伸びる。是非はともかく、やはり雇われは世間（日本）で評価が高い。まあこういう状況だから誰も起業しないでみんなサラリーマンやるんですけど。
結局のところ、お金が欲しいと言うより、無職が嫌だという話になる。

ちなみにプロプライエタリの企業と勉強会は両立が難しいかもしれない。今どきはオープンソース技術をどこのIT企業も使っていると思うので、そこら辺はわからないが。

ということで、理工学勉強会やってます。僕以外の人があんまり初心者にちゃんと教えたがる人が少ないので、そこら辺もしんどいです。

https://connpass.com/user/daisukeokaoss/
[Python / path / windows 対応] path の join や split を、複数OSに対応できるコードにしたいとき

# 1. 概要

以下のような事情の方には、ちょうど良い記事になると思います。

- Linux や Mac では path の区切りが `"/"` だが、 windows では `"\\"` とする必要がある
- この OS 間の差異のせいでエラーが発生している
- このエラーを解消し、**どの OS でも同じソースコードを実行できる**ようにしたい
- でも条件分岐 (if文) は書きたくない

`if` 分を使えば、両方の OS に対応するコードも書けますけどね、そのためにわざわざ書きたくないですよね。
そんな場合の対応方法を以下に記述しています。


# 2. 対応方法

## 2-1. split を置き換える

Linux / Mac などで、こんな処理を書いていたとします。

```python:before
>>> path = "/root/src/hoge.txt"
>>> path.split("/")
['', 'root', 'src', 'hoge.txt']
```

これだと、 path 区切りが "\\" になった途端処理結果が変わってしまいますよね。
そこで以下のようにします。

```python:after
>>> from pathlib import Path
>>> path = "/root/src/hoge.txt"
>>> _path = Path(path)
>>> _path.parts
('/', 'root', 'src', 'hoge.txt')
```

これでいい感じになります。windows の形式の path (`"C:\\root\\src\\hoge.txt"`)も分割してくれます。

まぁ若干差はあるんですけどね。それは戻り値の先頭部分です（`''` なのか `'/'` なのかが変わるので注意）
path の後ろの方だけを使うのであれば、ほぼ同等の結果が得られます。


## 2-2. join を置き換える

次は、こんな処理を書いていたとしましょう。

```python:before
>>> path_parts = ["dir_name", "class", "file_name.txt"]
>>> "/".join(path_parts)
"dir_name/class/file_name.txt"
```

これだと、 windows では処理できない path が生成されてしまいます。
この対処法は2種類あります。

### 2-2-1. os.path.join を使う

```python:after
>>> import os
>>> path_parts = ["dir_name", "class", "file_name.txt"]
>>> os.path.join(*path_parts)
"dir_name/class/file_name.txt"  # この結果は OS によって変わる
```

注目すべきは `os.path.join()` の処理結果です。
この方法なら、 path の区切り文字をこちらで指定しなくても、自動で判定して補ってくれます。
MacやLinuxなら自動で `"/"`に、 windows なら自動で `"\\"` をディレクトリ間の区切り文字として使ってくれます。

### 2-2-2. Path.joinpath を使う

以下のように書くこともできるみたいです。

```python:after2
>>> from pathlib import Path
>>> Path("dir_name").joinpath("class", "file_name.txt")
PosixPath('dir_name/class/file_name.txt')
```

`PosixPath` は簡単に文字列型にキャストできるので、この方法で変換しても良いでしょう。

```python:str へ cast
>>> str(Path("dir_name").joinpath("class", "file_name.txt"))
'dir_name/class/file_name.txt'
```

これらの結果も、 OS によって自動で区切り文字が切り替わるのでとても便利です^^


# 3. 関連記事

`pathlib.Path` には他にも便利な機能が盛りだくさんみたいです。
私は今のところ必要ないので触れていませんが、興味がある方には以下の記事が面白いかもしれません。

https://atmarkit.itmedia.co.jp/ait/articles/1910/29/news019.html

https://atmarkit.itmedia.co.jp/ait/articles/2211/29/news014.html
SMPでのthreadマイグレーション

MT7621にはせっかく4つもthreadがあるので、ちゃんと動いてるか確かめたくなりました。

FreeBSDのコマンドセットではxzがマルチスレッドに対応しているようです。

試したところTオプションをつけてもまったく変わりません。どうも小さいデータではマイグレーションしないみたいです。読み書きできるストレージがmdの10Mしかないので、大きなデータは試せません。

スケジューラーはULEを使っていますが、マイグレーションはkern.schedのパラメータでコストを忖度して行われるようです。

ネットで拾ったコードをいじってテストプログラムを作ってみました。

```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int done;

int fibonacci (int x)
{
    if (x <= 1) {
        return 1;
    }
    return fibonacci(x-1) + fibonacci(x-2);
}

void *runner(void *param)
{
        fibonacci((int)param);
        ++done;
        pthread_exit(0);
}

int main(int argc, char *argv[])
{
        int count, i;
        pthread_attr_t attr; 
        int num = 42;

        if (argc != 2) {
                fprintf(stderr,"usage: fibonacci <integer value>\n");
                return -1;
        }

        count = atoi(argv[1]);

        if (count < 1) {
                fprintf(stderr,"%d must be>= 1\n", count);
                return -1;
        }

        done = 0;

        pthread_attr_init(&attr);

        for(i = 1;i <= count; ++i){
                pthread_t thread;
                pthread_create(&thread,&attr,runner,(void*)num);
                pthread_detach(thread); 
        }

        while (done != count)
                sleep(1);
}
```

結果

```
# time ./fibonacci 1
       43.73 real        43.35 user         0.00 sys
# time ./fibonacci 2
       50.13 real        99.74 user         0.00 sys
# time ./fibonacci 4
       67.71 real       265.68 user         0.01 sys
```

ちゃんと動いてますね。ただふくすうにしたときのオーバヘッドが大きいです。

おうちのルーターなどでこれほど負荷がかかることはなくkern.schedの設定は調整が必要と思われます。

LUNA88Kでも似たような事をしていた記憶があります。当時はMACHのcthreadを使っていたような気がします。
【SwiftUI】UserDefaultsを使ってデータ型のデータを保存する

## はじめに
SwiftUIにおいて、簡単なデータを保存できるUserDefaultsについて学習したので、備忘録としてまとめます。
ここではUserDefaultsの基本的な使い方（データ型の保存）と、データを保存する簡単なアプリを例に説明します。

## 環境
【Xcode】16.2
【iOS】18.2
【macOS】Sequoia 15.3.1


## UserDefaultsとは
UserDefaults は、iOSアプリにおいてデータを永続化（アプリを閉じてもデータが消えないように保存）するための仕組みです。

### ✅ UserDefaultsで保存できるデータ型

UserDefaultsには以下のようなデータ型を保存できます。

・Bool（真偽値）

・Int（整数）

・Float（浮動小数点数）

・Double（倍精度浮動小数点数）

・String（文字列）

・Data（バイナリデータ）

・Array（配列）

・Dictionary（辞書）

※ 複雑なデータ型（独自の構造体など）を保存する場合は、**Codableプロトコル**を使ってJSON形式に変換する必要があります。

## UserDefaultsを使った簡単なアプリを作成

ここでは、スコアを保存・リセットできるシンプルなアプリを作成します。

### アプリの仕様

「スコア +1」ボタンを押すとスコアが増加し、UserDefaultsに保存

「リセット」ボタンでスコアを0にし、UserDefaultsからデータを削除

アプリを再起動しても、保存されたスコアが保持される

```swift
import SwiftUI

struct ContentView: View {
    // UserDefaultsから保存したデータを読み込む
    @State private var score: Int = UserDefaults.standard.integer(forKey: "highScore")

    var body: some View {
        VStack {
            Text("スコア: \(score)")
                .font(.largeTitle)
                .padding()

            HStack {
                // スコアを増加し、UserDefaultsに保存
                Button {
                    score += 1
                    UserDefaults.standard.set(score, forKey: "highScore")
                } label: {
                    Text("スコア +1")
                        .padding()
                        .background(Color.blue)
                        .foregroundStyle(.white)
                        .cornerRadius(10)
                }

                // スコアをリセットし、UserDefaultsから削除
                Button {
                    score = 0
                    UserDefaults.standard.removeObject(forKey: "highScore")
                } label: {
                    Text("リセット")
                        .padding()
                        .background(Color.red)
                        .foregroundStyle(.white)
                        .cornerRadius(10)
                }
            }
            .padding()
        }
    }
}
```


#### 1. スコアの保存
```swift
UserDefaults.standard.set(score, forKey: "highScore")
```

set(_:forKey:) メソッドでデータをUserDefaultsに保存。

キー（"highScore"）を指定することでデータを管理。

#### 2. スコアのリセット
```swift
UserDefaults.standard.removeObject(forKey: "highScore")
```
removeObject(forKey:) メソッドでデータを削除。

キー（"highScore"）に対応するデータ（score）が削除される。

---
## まとめ

UserDefaults は小規模なデータ（設定、スコア、フラグなど）を簡単に保存できる。

set(_:forKey:) でデータ保存、removeObject(forKey:) でデータ削除。

複雑なデータはJSON形式に変換し保存することも可能。
kernel上がって有線LAN使用不可修復メモ

# ある日突然有線LANが消えた

:::note info
補足
- 非公式の社内向け技術資料として作成
- 試した解決策を参考リンクとして記載、パターンに応じて試してみてください
- LANチップセットはRealtek 8168を使用と想定
- 意外とUSB−LAN変換アダプタで解決している方がいる模様 
:::

- Ubuntu22.04では概ね画面右上にLAN(有線・無線)のアイコンが出る
- SettingのNetwork項目がなくなった


<details><summary>En Summary</summary>

(上に空行が必要)

:::note info
Situation
- After kernel version is updated, wired LAN is disappear
- No Network setting
- If connected wireless LAN adapter, I could set network via phone
- In some FAQ site, solution is connected USB to LAN converter 
:::

# My solution

https://askubuntu.com/questions/1463163/ethernet-connection-disabled-in-ubuntu-22-04-os

- Wired Lan is not set as exception
- After replacing setting as above advice, wired Lan is recovered 

</details>

# 参考にした手順
1. @yukitoro0101 (yuki toro)さんの記事 

https://qiita.com/yukitoro0101/items/94ea8cd8540b92a36746

:::note info
結果
- 今回の現象では残念ながら改善されませんでした・・・
- でも、有効な解決策に成ると思われます
:::

2. @disksystem さんの記事

https://qiita.com/disksystem/items/5fb4c7af756214d10d6f

:::note info
結果
- 確かにr8169に変わっていて、本来のr8168が併記状態でした
- が、解決には至らず
- でも、有効な解決策に成ると思われます
:::

3. litoma さんの記事

https://text.yusukesakai.com/entry/20240114/1705237997



# 最終的に解決した設定変更

https://askubuntu.com/questions/1463163/ethernet-connection-disabled-in-ubuntu-22-04-os

## 確認内容

- 有線LANアダプタに以下の表示が含まれていました。

```Ubuntu:ターミナル画面

lshw -C network

```


```Ubuntu:ターミナル画面
*-network:1 DISABLED
       description: Ethernet interface

```
## 回答の解決策実行


```Ubuntu:ターミナル画面

sudo vi /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
```

- **確かに有線LANがない！**(当方環境では他にテザリングの設定あり)

```Ubuntu:ターミナル画面

[keyfile]
unmanaged-devices=*,except:type:wifi,except:type:wwan

# ここにEthernetを追加
[keyfile]
unmanaged-devices=*,except:type:ethernet,(以下略)

```

:::note info
結果
- おそらく、上記2つの手順あってのところもある可能性
- 確かにこの表示と同じ状態でした
- 私のケースでは設定変更後、再起動で直りました
:::

## 他参考リンク

https://www.realtek.com/Download/List?cate_id=584

- LANドライバのバージョンは最新にしておくと良いと思います
PHPで「変数を参照」の動作を確認してみた。

# 概要

PHPで「変数を参照」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/var/index5.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
<?php
$num1 = 320;
$num2 =& $num1;

print '$num1 ='.$num1.'<br />';
print '$num2 ='.$num2.'<br />';

$num1 = 18;

print '$num1 ='.$num1.'<br />';
print '$num2 ='.$num2.'<br />';

$num2 = 75;

print '$num1 ='.$num1.'<br />';
print '$num2 ='.$num2;
?>
</p>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
$num1 =320<br />$num2 =320<br />$num1 =18<br />$num2 =18<br />$num1 =75<br />$num2 =75</p>

</body>
</html>
```

# まとめ

何かの役に立てばと。
howler.js 個人的結論


## バージョン

howler.js 2.2.4

## 数々のバグに苦しみ、最終的に編み出された結論はこれだ！

```js
function loadSound(path, _option = null) {
    return new Promise((resolve, reject) => {
        const option = {
            src: [path],
            volume: 1,

            // trueだとユーザー操作がどうのこうので音が鳴らない場合がある。例えユーザー操作があっても。
            html5: false,
            
            // https://github.com/goldfire/howler.js/issues/293
            onload() {
                resolve(sound);
            },
            onloaderror(id, message) {
                reject(new Error(message));
            },
            onplayerror(id, message) {
                throw new Error(message);
            },
        };
        if (_option !== null) {
            Object.assign(option, _option);
        }
        const sound = new Howl(option);
    });
}

function playSound(sound) {
    const state = sound.state();
    if (state !== "loaded") {
        throw new Error(`sound.state() → ${state}`);
    }
    return new Promise(resolve => {
        // https://github.com/goldfire/howler.js/issues/1753
        if (Howler.ctx.state === "suspended" || Howler.ctx.state === "interrupted") {
            Howler.ctx.resume().then(() => {
                sound.play();
                resolve();
            });
        }
        else {
            sound.play();
            resolve();
        }
    });
}
```

終わり

## ちなみに

`html: false`で`sound.unload()`しても解放されないっぽい。
要するにメモリリークしている可能性がある。

https://github.com/goldfire/howler.js/issues/1731

## 昔書いた苦悩

https://qiita.com/mogamoga1337/items/0e787fc2964c62d018b1
脱IT初心者～リネームにはTABキー編～

## 本記事の読者ターゲット層
・たくさんのファイルをリネームするのが手間だと感じている方
・初心者エンジニア


## たくさんリネームするのって手間

エビデンスとかとってたらこうなりますよね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/2d02b768-a0c9-4c3a-af8f-6684eba8994b.png)

これを「2桁に揃えて」と言われたら皆さまはどうしますか？

僕はこうしていました
1.ファイル名の上でクリック！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/5fda899a-5cdd-4803-a38f-4eef41b3240d.png)

2.ファイル名を変更！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/848144f7-d3bb-4da1-a923-a4aa6aa7ec04.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/026d7788-8c34-4894-b024-2f574add0ab0.png)

3.エンターキーで決定！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/a75533a5-1ee7-4622-bdfb-45e5ffdaa065.png)

4.次のファイル名の上でクリック！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/a2516936-8fb9-462a-a24d-907a4ef1755e.png)

～～～繰り返し～～～
大変手間！


## 時短リネーム術

リネームにはTABキーを使おう！
僕はエンジニア歴1年半でやっと知りました

1.ファイルを選択してF2キー
（そもそもファイル名の上でクリックするのは少し待たないとダブルクリック扱いにされたりするのでやめよう。F2キーを活用するのが良いですよっておしえていただきました。すげー。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/f471c9f6-c31b-4905-98ba-e3c4bd2c6ede.png)

2.ファイル名を変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/bd38b90f-1293-425d-8feb-6b3c0fa7987a.png)

3.TABキー押下！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/7533019d-baa4-4f92-8513-e7d9fc9f38ca.png)

なんと次のファイルのファイル名変更に移行しました！！！
なんと便利なことでしょう
かなり重宝しますよ！！！


察しの良いそこの読者のあなたもお気づきかと思いますが
Shiftキーと同時押しで上のファイルに移動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/4f20ee2a-3679-4fee-95d1-d037458ea7fb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835749/c05250ab-66b2-4e37-9c6c-1545f704995e.png)
僕も察しが良いのでこれは自分で気づきました


## あとがき
これ常識なんですか？本当に知りませんでした
スキルや知識以外に、まだまだ知らないことがたくさん
ファイル整理なんて雑用みたいな仕事ですが、それでも覚えることはたくさんありますね

3桁に揃えてとか500ファイルくらいリネームしなくてはならないときは
エクセルでRENコマンドを一挙に作ってしまって一気に実行するのが手早いと思います
また機会があれば記事にしたいと思います！
それすら面倒なくらいの量の作業の場合は、TABキーでリネームの手間を省いてくださいね
WindowsのコマンドプロンプトからOpenHandsを起動する

# はじめに

Windows 11 Homeの`コマンド プロンプト`から、[OpenHands](https://docs.all-hands.dev/)を起動・停止します。

**Running OpenHands**

https://docs.all-hands.dev/modules/usage/Installation

**`コマンド プロンプト`での起動例**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/f9fbd9ba-1cdc-47e2-ad1b-10f2cf0f2b8a.png)

# 準備

Windows 11 Homeに[WSL2](https://learn.microsoft.com/en-us/windows/wsl/install)と[Docker Desktop](https://www.docker.com/get-started/)をインストールします。

**WSL2**

https://learn.microsoft.com/en-us/windows/wsl/install

**Docker Desktop**

https://www.docker.com/get-started/

`コマンド プロンプト`を開き、dockerイメージを取得します。

- `docker.all-hands.dev/all-hands-ai/runtime:0.26-nikolaik`

```bat: dockerコマンド
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.26-nikolaik

```

# 起動

コマンド プロンプトを開き、次の`dockerコマンド`でOpenHandsを起動し、ウェブブラウザで、 http://localhost:3000 へアクセスします。

```bat: dockerコマンド
docker run -it --rm --pull=always ^
    -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.26-nikolaik ^
    -e LOG_ALL_EVENTS=true ^
    -v //var/run/docker.sock:/var/run/docker.sock ^
    -v %USERPROFILE%/.openhands-state:/root/.openhands-state ^
    -p 3000:3000 ^
    --add-host host.docker.internal:host-gateway ^
    --name openhands-app ^
    docker.all-hands.dev/all-hands-ai/openhands:0.26

```

:::note info
オリジナルのコマンドとの違い

Windowsの`コマンド プロンプト`で実行できるように、[オリジナルのコマンド](https://docs.all-hands.dev/modules/usage/Installation#start-the-app)の一部を変更しています。

**変更点1:** 改行をコマンドの続きとするための `\` を `^` に変更しています。

**変更点2:** docker.sockのボリュームを `wsl` のファイルとしています( `/` を追加)。

**変更点3:** ホームディレクトリの参照方法（`~`）を環境変数を使った方法（`%USERPROFILE%`）に変更しています。

```bat: オリジナル
docker run -it --rm --pull=always \
    -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.26-nikolaik \
    -e LOG_ALL_EVENTS=true \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v ~/.openhands-state:/.openhands-state \
    -p 3000:3000 \
    --add-host host.docker.internal:host-gateway \
    --name openhands-app \
    docker.all-hands.dev/all-hands-ai/openhands:0.26
```

:::


**ウェブブラウザでの初期表示**
http://localhost:3000
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/749c987a-235b-45fe-a0f2-44dac8878257.png)

# 停止

起動したコマンドプロンプトで、`CTRL` + `C`を押下すると停止します。

:::note warn
コマンド プロンプトを閉じてしまった場合

`Docker Desktop Dashboard`を開き、`Containers`に表示された**opnehands-app**の`Actionsボタン`で停止(Stop)することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252891/cb88051a-fe0c-495d-aa25-269d372b86ab.png)

:::

# おわりに

公式の[Running OpenHands](https://docs.all-hands.dev/modules/usage/Installation)に従って、Windows 11 Homeの `コマンド プロンプト`からOpenHandsを起動しました。

コマンドの書き方には、次の３つのポイントがありました。

1. 改行をコマンドの続きとするための `\` を `^` に変更しました
1. docker.sockのボリュームを `wsl` のファイルとしました(`/`を追加)
1. ホームディレクトリの参照方法（`~`）を環境変数を使った方法（`%USERPROFILE%`）に変更しました
数値と接尾辞が分離：HTMLで一体化できない問題

## 前提
{record.time}のところにinputに入力した数値が入る形になっています。

# 数値と接尾辞が分離している箇所
```.jsx
<span data-testid="time">{record.time}時間</span>
```
HTMLの構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/7a2d467a-2965-4da2-bf51-f4a3028a606a.png)

## 数値と接尾辞がHTMLの構造で一体化するように修正
```.jsx
<span data-testid="time">{`${record.time}時間`}</span>
```
HTMLの構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3789688/73b96226-8fa5-458d-b6b5-902c412b5c97.png)

## 行ったこと
文字列とオブジェクトをテンプレートリテラルで結合させました。

## まとめ
問題にあたったときには基礎的な構文や文法間違い等がないかなどを
まず確認するようにしていきたいと感じました。
Power BIにおけるDAXの使い方

# はじめに

こんにちは！
記事をご覧いただきありがとうございます。
本記事では、Power BIにおけるDAXの使い方について解説します。

ぜひ最後までご覧ください！

# 目次
4.  [DAXとは](#daxとは)
1. [基本構文](#基本構文)
4. [使いどころ](#使いどころ)
4.  [最後に](#最後に)


# DAXとは
DAXは、Power BI、ExcelのPower Pivot、Analysis Servicesで使用されるデータ分析用の関数言語です。Excelの関数と似ていますが、Power BIのデータモデル内で高度な計算やフィルタリングができる点が特徴です。

### DAXが必要な理由

Power BIでは、単純なデータの集計だけでなく、条件付き計算や時間軸を考慮した分析が求められます。DAXを使うことで以下のような高度な計算が可能になります。

- 売上の前年同期比

- 動的なランキング

- 累積合計

- 条件付きグループ分け


# 基本構文
DAX関数は、以下のような形式で記述されます。
```
新しいメジャー = 関数名(引数1, 引数2, ...)
```
例えば、合計売上を求めるには以下のように記述します。
```
合計売上 = SUM(売上[金額])
```
また、新しい列を作成する場合は「計算列（Calculated Column）」を利用します。
```
売上ステータス = IF(売上[金額] > 50000, "高", "低")
```


# 使いどころ
## 1. 基本的な集計関数
| 関数名 | 説明 |
|--------|------|
| `SUM()` | 指定した列の合計を計算 |
| `COUNT()` | データの個数を数える |
| `AVERAGE()` | 指定した列の平均を計算 |
| `DISTINCTCOUNT()` | 重複を除いたデータの個数を計算 |

例：
```DAX
総売上 = SUM(売上[金額])
顧客数 = DISTINCTCOUNT(売上[顧客ID])
```


## 2. 条件付きの計算

IF() や SWITCH() を使うと、データの条件分岐ができます。
```
売上カテゴリ = SWITCH(TRUE(),
    売上[金額] > 100000, "VIP",
    売上[金額] > 50000, "ゴールド",
    "一般"
)
```

## 3. フィルターを適用した計算

CALCULATE() を使うと、特定の条件を適用して集計できます。
```
2024年売上 = CALCULATE(SUM(売上[金額]), 売上[年] = 2024)
```

また、全体の売上に対する特定のカテゴリーの割合を計算することも可能です。
```
カテゴリ売上比率 = DIVIDE(SUM(売上[金額]), CALCULATE(SUM(売上[金額]), ALL(売上)))
```
## 4. 時系列データの分析
DAXには、前年同期比や累計を計算するための関数があります。

| 関数名 | 説明 |
|--------|------|
| `SAMEPERIODLASTYEAR()` | 前年の同じ期間のデータを取得 |
| `TOTALYTD()` | 年初からの累計を計算 |
| `DATEADD()` | 指定した期間を前後にシフト |

例：前年の売上を計算
```DAX
前年売上 = CALCULATE(SUM(売上[金額]), SAMEPERIODLASTYEAR(カレンダー[Date]))
```

# 最後に

本記事では、Power BIを使ったデータ分析でのDAXの活用方法について紹介しました。
今後もDAXの活用方法やDAXの応用の仕方を学びながら、より高度な分析を実現していきたいと思います。
読書感想文「内部構造から学ぶ　PostgreSQL　設計運用計画の鉄則」　実行計画

# 書籍名「内部構造から学ぶ　POstgreSQL　設計運用計画の鉄則」　実行計画

# 印象に残った部分

## p256 実行計画とは
```
問い合わせを発行すると、PostgreSQLのプランナは様々な検索方法の中から処理コストが最小になる選択や組み合わせを計算します。
上のコストが最小化された検索方法のことを実行計画という。
統計情報に基づいて実行計画は作成される。
```

## p258 実行計画の取得方法
・SQLで実行する方法
　EXPLAINコマンドを使う

・自動的に取得する方法
　拡張モジュール「auto_explain」を有効にする

## p40 統計情報とは
統計情報・・各列の典型的な値と各列のデータ分布を概要を示す度数分布

アナライズ・・クエリを実行する際に利用する統計情報を収集してpg_staticシステムカタログを更新する処理。

## p266 p262 統計情報の取得方法
・SQLで実行する方法
　ANALYZEコマンドを使う
　
・自動的に取得する方法
　自動バキューム機能を使う

## p273 実行計画の構造 

```plantuml
@startuml
object Sort
object Append
object HashJoin
object SeqScan1 as "SeqScan"
object SeqScan2 as "SeqScan"
object Hash
object IndexScan


Sort <-- Append
Append <-- HashJoin
Append <-- SeqScan1
HashJoin <-- Hash
Hash <-- IndexScan
HashJoin <-- SeqScan2
@enduml

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f09a6337-a7ca-49fe-ad13-2f4272b33d3d.png)




下から順に実行される
最初にindex Scanが実行されて
ノードの分類|説明|具体的なノード|備考
-------|---|------------|---
スキャン系|最初に実行されるノード。</br>データを選別するフィルタ条件| Seq Scan</br>Index Scan</br>Index Only Scan</br>など|Where？、Index
複数のデータを結合|２つのテーブルのスキャン結果を入力とし、１つの結果を出力|Nested Loop</br>Hash Join</br>Merge Join|inner Join Left Joinなど？
データを加工|なし|Limit </br> Result|--

Sortは優先度低い

## p288 289 処理コストの見積もり値と実行結果
・処理コストの見積もり＝実行計画
・実際の実行時間→EXPLAIN ANALYZE を実行して確認できる
・見積もり時間と実行時間は統計情報に基づいて算出されるため、統計情報は定期的に取得する。

todo なんで見積もりと実際の実行時間が変わるんだ？？？理由をあとで調べておく


# 実践すること or 感想
実行計画の概要を知れて良かったです。
とりあえず、統計情報→実行計画の順で取得するってことは理解できました。
実行計画と統計情報を自分の言葉で説明しろって言われてたら　グレーですね。まだ理解不足感ありますね。



## 実践すること
・実際にクエリを打って、実行計画を確認する
・前にSQLパズルのリポジトリがあるので、それを使う。
https://github.com/RYA234/SQL_Puzzle_Learning

・本書のパフォーマンスチューニングの部分を読み込む
競プロ日記#25/02/26

# アルゴ式-[単発のクエリ](https://algo-method.com/tasks/824)
- 問題自体はとても簡単で特筆すべき点はないが、C++において以下の方法でも配列を定義することができる
```
int A[] = {3,1,4,1,5,9,2,6,5,3};
```
- その代わりに.at()でアクセスできなくなる
Javascriptのイベント制御

参考にさせていただいた記事
https://developer.mozilla.org/ja/docs/Learn_web_development/Core/Scripting/Events

https://www.javadrive.jp/javascript/event/

https://qiita.com/axoloto210/items/bcd567e377f9b07fc569?utm_source=chatgpt.com

https://tcd-theme.com/2022/09/javascript-event-target-currenttarget.html

# 学習トピックの整理

## **JavaScriptにおけるイベント制御**

### **① イベントの基本**
- イベントとは何か？
- イベントの種類
- イベントの登録方法

### **② イベントの実行フロー**
- イベントの伝播（キャプチャリング、ターゲット、バブリング）
- イベントの委譲（イベントデリゲーション）

### **③ イベントオブジェクト**
- イベントオブジェクトの構造
- `e.target` vs `e.currentTarget`
- `preventDefault()` / `stopPropagation()` の活用

### **④ イベントのデフォルト動作**
- デフォルト動作とは？
- `preventDefault()` による制御
- 具体的なデフォルト動作の例

---

# **イベントの基礎**

## **イベントとは何か？**
ユーザー操作やページ読み込みなど、処理の実行の起点となる出来事を指します。  
イベントが発生すると、**ブラウザーがシグナルを発し、対応するコード（イベントハンドラー）が実行される**仕組みです。

---

# **イベントの発生時のフロー**

1. **イベントオブジェクトの生成**
   - イベントが発生すると、ブラウザーは `event` オブジェクトを生成。
   - `event` オブジェクトには、**発生源（`e.target`）やキーコードなどの情報** が含まれる。

2. **キャプチャリングフェーズ**
   - **DOMツリーのルート要素** から **ターゲット要素（`e.target`）** に向かって **イベントが伝播する**。
   - これを **「キャプチャリングフェーズ」** と呼ぶ。

3. **ターゲットフェーズ**
   - **`e.target`（イベントが発生した要素）に到達**。
   - 登録された **イベントリスナーのコールバック関数が実行** される。


4. **バブリングフェーズ**
   - **`e.target` からルート要素に向かって、イベントが逆方向に伝播**。
   - これを **「バブリングフェーズ」** と呼ぶ。

---

# **イベントの伝播と実行条件**

### **イベントハンドラーが実行される条件**
　**伝播経路にある要素**  
　**イベントリスナーの `type` と `event.type` が一致**  
　**適切なフェーズで登録されている（`capture` or `bubble`）**

- `addEventListener()` のデフォルト設定では **バブリングフェーズ** で実行される。
- **キャプチャリングフェーズ** で実行するには `addEventListener(type, callback, true)` の `true` を指定する。
- **バブリングを活用して、親要素で子要素のイベントを一括管理する手法** を **「イベントの委譲（Event Delegation）」** と呼ぶ。（パフォーマンス向上）

---

# **イベントオブジェクトの主なプロパティ**
| プロパティ | 説明 |
|-----------|------|
| `type` | 発生したイベントの種類（例: `click`, `keydown`） |
| `target` | **イベントが発生した最も深い階層の要素**（例: `div` 内の `button` をクリック → `e.target === button`） |
| `currentTarget` | **現在のイベントリスナーが登録されている要素**（バブリング・キャプチャリングの際に変化する） |
| `preventDefault()` | デフォルト動作をキャンセル（例: `<a>` の遷移を防ぐ） |
| `stopPropagation()` | イベントの伝播をストップ（親要素へのバブリングを防ぐ） |

---

# **イベントのデフォルト動作**

### **デフォルト動作とは？**
ブラウザーは、特定のHTML要素とイベントの組み合わせに対して、あらかじめ決められた動作を実行します。

### **デフォルト動作の例**
| **要素** | **イベント** | **デフォルト動作** |
|-----------|------------|----------------|
| `<a>` | `click` | ページ遷移 |
| `<form>` | `submit` | フォーム送信 |
| `<input type="text">` | `keydown` | テキスト入力 |
| `<button>` | `click` | `type="submit"` の場合、フォーム送信 |
| `<body>` | `contextmenu` | 右クリックメニュー表示 |

### **デフォルト動作の決定要素**
　　**要素の種類（フォーム、リンクなど）**  
　　**イベントの種類（`click`, `submit`, `contextmenu` など）**  
　　**`preventDefault()` の有無**  
　　**ブラウザーの仕様**
いくつかのコマンドでは使用方法表示（-h|--help）が標準エラー出力へ出力される？

こんにちは。
以下のように認識しておりましたが、そもそも統一的な規定があるのならば、探したいです。

1. ```man``` コマンドの出力は pager へ渡され（もしくは標準出力）、ただし使用を誤った場合は標準エラー出力です（終了ステータス 1）。
2. 一般のコマンドの使用方法を ```-h|--help``` で表示させた場合の出力は標準出力で（終了ステータス 0）、ただし使用を誤った場合は標準エラー出力です（終了ステータス 1）。

しかし後者に関し、いくつかのコマンドでは正常使用の出力も標準エラー出力（終了ステータス 2）となることに気がつきました（下記）。

```console
$ grep --help 2>&1 | less
```
Vue3.5のwatchやライフサイクルフックの実行タイミング

## はじめに
Vueのライフサイクルフックが呼ばれる順番はここで案内されている。
https://ja.vuejs.org/guide/essentials/lifecycle.html

watchは即時ウォッチャーと
https://ja.vuejs.org/guide/essentials/watchers.html#eager-watchers

遅延ウォッチャーなどがある。
https://ja.vuejs.org/guide/essentials/watchers.html#post-watchers

これらの実行タイミングは明記されていない。
Vue Playgroundで[試してみた](https://play.vuejs.org/#eNq1VW1rFEkQ/ivNcLArWWfvyN2XJQl3ih88OE9O79PtoZuZmk3rTPfY07OJLAuZWcGoiBIUURERRCNqFEQQEf0xTRL9F1Z3z86+xA0RIiRMd70+9VRVb9f5I47dTgpOw5mTEMVhS8JCkxEyF5sPIVsvb6r8jerj3wPV/6D61815TWWbyy3pLeFX5Z9U/lj1H2pN/lplG6r/zEhuq/ytPuSvVP+5vvb7+rzbJV/3OEt4CG7I2yp7uv3uxdbmPZXdVfk1kx4TX1GruYFWt9hKiNt3N7+sovHzz482dh6/t17TcW+o1axzmAaYpnDI17fWLqv86vb9Typb28s5X9+5tbF96YbK7qjsicouaXwTsBZTKTkjv3sh9c7PNx3KPAERMNl0Fo4PznN1a2ZdKItTSeTFGNDeWwLv/CJfaTqkczjiPoQoTJb48tElGvoorS+Q07zdDgH1NDABjIo0Oq0wNSF4qtMR1or0lXERtULjOWKtnSciTwtg8lj3ufrInOA18QSNJUlAprp+GsVcSNIlAgLSI4HgEanggFVKlU1uFW7d3PQEokGT6SGQxCQn8zpE9edDA2mJs9AErTAB1A70Jc2orx4i8wukq4s1wVxT18yMFZSDVq3YVKUr+BWM2NNV2rqwIqfmyASdAtp2zyWc4aqYwJqkKKYhiL9jSTFo02nYlFrXCkO+/KeRSZFCbSA3zf2G/FyC/W7g4aSABEQHmk6pky3RBuyGVh87dQJW8FwqcUDSEK33UP4DWHCqMVqzIynzEfaInUF73PSHsvbp5NiKBJYMitJAtWXP2OM0pHB0j9KHcGfdX40fUooslq3e/dj4tFPsMi51t2vGjvR6GLRLTOvwUu5X3VrvdxDNK1UjnB2BgAv4S3dcX80B/KHm39jHYPpuT/7E/DZZvU5iweMEn6adj88Gg2dEOHQ+BJTBSX2rGjIM8pIYvd0NciKNFkEUxAu4kFIB/iTFuvwJv1NSYGem+yHF5abEuB50BREZZK6OptEbIqp2NazGAKyNb8twOc7+91PXhur9b1lskCBME/yg+KxelBryW4gqKKsQDeJAMyUXmbcrlRb+gFwxT+TuslB4kLloFIFPcbxs88jMtzidMKr9KJKnghmjfSqag+7DdG5GOzOdnJFWja17AWtvDGMeJhn+l8/EPkMU1kP30aflu2BYl2Gg4k3aZ4zCeuA+/nN2pgNCP+74Ds+6v7m/zDq9r1AMwU8=)。

## 結論
まとめるとこう。

コンポーネントがインスタンス化される（v-ifがtrueになるなど）
↓
`watch { immediate: true }`（flushの値は関係ない）
↓
`onBeforeMount`
↓
`onMounted`
↓
refの値を変更する
↓
`watch: { flush: "sync" }`
↓
`watch: { flush: "pre" }`（デフォルトの挙動）
↓
`onBeforeUpdate`
↓
`watch: { flush: "post" }`
↓
`onUpdated`

## おわりに

`onMounted`した直後に必ず１回watchコールバックを実行する方法を探していたけど、なさそうだった。