Auto Rename TagはVSCodeの著名な拡張の1つです。
上記拡張のNoteにも記載があるのですが、実はこの機能がVSCodeのビルトインとして統合されています。
デフォルトで有効化されていませんがeditor.linkedEditing
という設定をtrueにすることで有効になります。
Auto Rename TagはVSCodeの著名な拡張の1つです。
上記拡張のNoteにも記載があるのですが、実はこの機能がVSCodeのビルトインとして統合されています。
デフォルトで有効化されていませんがeditor.linkedEditing
という設定をtrueにすることで有効になります。
更新処理を実行した後、対象以外のテーブルをジョインしてRETURNINGして欲しくなった。
まぁ、これに関しては、実装的に1つのクエリでやりたいことが2つ出てしまうのであまり良くないと思ったので、結局は更新処理と取得処理を分離した。通信に関してあまり詳しくはないが、仮にトランザクション中であれば接続貼りっぱなしだと思うので通信のRTTも気にならんだろうし。
ただ、JOINしてWHEREしたいケースにも利用できる(というか、どちらかというとそちらがメイン)。
FROM句を利用する。UPDATEにFROM句が使えるんだな。下記はPostgreSQLのリファレンスより引用し、RETURNINGを追加している。
UPDATE employees SET sales_count = sales_count + 1 FROM accounts
WHERE accounts.name = 'Acme Corporation'
AND employees.id = accounts.sales_person
RETURNING
employees *, accounts.*;
PostgreSQLを利用して、キューのようなものを作成したくなったところ、SKIP LOCKEDというものを知りました。
名前の通り、ロックされている行ををスキップしてくれるものです。
例えば下記のようなテーブルを作成してみます。
CREATE TABLE tasks (
id SERIAL PRIMARY KEY,
status TEXT NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO tasks (id) VALUES (1), (2), (3), (4), (5);
現状こんな感じ。
$ select * from tasks;
id | status | created_at
----+---------+-------------------------------
1 | pending | 2024-06-29 12:34:50.000000+00
2 | pending | 2024-06-29 12:34:51.000000+00
3 | pending | 2024-06-29 12:34:52.000000+00
4 | pending | 2024-06-29 12:34:53.000000+00
5 | pending | 2024-06-29 12:34:54.000000+00
ここで、下記のようなトランザクションを実行します。まだコミットしていないので対象の行はロックされたままです。
$ BEGIN;
$ SELECT id FROM tasks ORDER BY created_at LIMIT 1 FOR UPDATE;
id
----
1
この間にトランザクション外から下記のコマンドを実行してみます。
$ SELECT id FROM tasks FOR UPDATE SKIP LOCKED;
id
----
2
3
4
5
この様に、ロックされたid 1の行をスキップしました。
PostgreSQLのリファレンスにはSELECT - ロック処理句に記載があります。
こちらの機能はSQL標準ではないようですが、MySQLにも存在しています。おそらく8.0から。
タイトルからだとかなり読みづらいが、下記のようなことをしたい。こういった欲求は度々起こるが、その度調べては難しそうだったので諦めていた。簡単に言えばnpm scriptsの内部で引数を分離したいのである。
{
"scripts": {
"lint:fix": "eslint --fix",
"prettier:write": "prettier --write",
"format": "???"
},
}
上記のスクリプトがある前提で、下記を期待する。
$ npm format __tests__/index.test.ts
> npm lint:fix __tests__/index.test.ts && npm prettier:write __tests__/index.test.ts
例えばシンプルに下記のようにする。
{
"scripts": {
"lint:fix": "eslint --fix",
"prettier:write": "prettier --write",
"format": "npm lint:fix && npm prettier:write"
},
}
そうすると最後に引数がくっつくだけである。
$ npm format __tests__/index.test.ts
> npm lint:fix && npm prettier:write __tests__/index.test.ts
npmだけではそういうことはできなさそう だが、ここでnpm-run-allの存在を思い出した。もう6年前から更新されてない。
結論としてはnpm-run-allで今回の欲求は満たせた。Argument placeholdersという機能を利用すれば良い。
{
"scripts": {
"lint:fix": "eslint --fix",
"prettier:write": "prettier --write",
"format": "run-s 'lint:fix {1}' 'npm prettier:write {1}' --"
},
}
$ npm format __tests__/index.test.ts
> npm lint:fix __tests__/index.test.ts && npm prettier:write __tests__/index.test.ts
最後の --
はscripts側にないと想定通りに動作にはならない。
下記の条件を満たしていると、VSCodeのバージョンが1.90.0(2024-06-12時点での最新)以下で動作しない。
eslint.config.mjs
であるlanguageOptions.parserOptions
の project
および tsconfigRootDir
を設定しているimport.meta.dirname
を利用している ← これが原因原因としては、VSCode1.90.0の内部で利用されているElectron 29のNode.jsのバージョンが20.9.0であるため、import.meta.dirname
が利用できない。
import.meta.url
は利用できるため、下記のような回避策で解決できる。
import { fileURLToPath } from "url";
const filename = fileURLToPath(import.meta.url);
const dirname = import.meta.dirname ?? path.dirname(filename);
export default tseslint.config(
...,
{
languageOptions: {
parserOptions: {
project: ["./tsconfig.eslint.json", "./packages/*/tsconfig.json"],
tsconfigRootDir: dirname,
},
},
},
...,
)
Node.js 20.11.0で追加されている ので、Electron v30(Node.js 20.11.1)ではimport.meta.dirname
が利用可能になるはず。
yamlを編集していると候補が邪魔をしてきて鬱陶しかったので設定を入れた。
下記を記載すると、入力するだけで候補の表示がされなくなる。Macであれば ctrl-space
(入力ソースの変換と被っているが)で候補は表示される。
"[yaml]": {
"editor.quickSuggestions": {
"comments": "off",
"strings": "off",
"other": "off"
}
}
P.S.
1回上記の設定を入れた後に無効化しても全然候補が表示されなくなった。
今回参考にしたのは下記の記事。
brew upgrade後、gcloud
コマンドを叩くと下記のようなエラーが発生するようになった。
ERROR: gcloud failed to load. This usually indicates corruption in your gcloud installation or problems with your Python interpreter.
Please verify that the following is the path to a working Python 3.8-3.12 executable:
/Users/sa2taka/.pyenv/versions/3.11.1/bin/python
If it is not, please set the CLOUDSDK_PYTHON environment variable to point to a working Python executable.
If you are still experiencing problems, please reinstall the Google Cloud CLI using the instructions here:
https://cloud.google.com/sdk/docs/install
Traceback (most recent call last):
File "/Users/sa2taka/libs/google-cloud-sdk/lib/gcloud.py", line 106, in gcloud_exception_handler
yield
File "/Users/sa2taka/libs/google-cloud-sdk/lib/gcloud.py", line 183, in main
gcloud_main = _import_gcloud_main()
^^^^^^^^^^^^^^^^^^^^^
...(中略)...
ImportError: dlopen(/Users/sa2taka/.pyenv/versions/3.11.1/lib/python3.11/lib-dynload/_ssl.cpython-311-darwin.so, 0x0002): Library not loaded: /usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib
Referenced from: <...> /Users/sa2taka/.pyenv/versions/3.11.1/lib/python3.11/lib-dynload/_ssl.cpython-311-darwin.so
Reason: tried: '/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib' (no such file), '/usr/local/lib/libssl.1.1.dylib' (no such file), '/usr/lib/libssl.1.1.dylib' (no such file, not in dyld cache)
エラーの上部に解決策が色々出てるが、原因は下部のほうにある openssl@1.1
がないことだ。どうやら brew upgrade
を叩いた際に消えたようだ。
とりあえず openssl@1.1
をダウンロードすることで解決できる。
$ brew install openssl@1.1
一般的なマークダウンでは>
が引用であるが、Notionではトグルに割り当てられている。
/quote
とすることで引用にできるが、それ以外に"
または|
がショートカットとして割り当てられている。確かに|
は一般的な引用のスタイルだし、わかりやすいかもしれない。
TypeScript ESLintはTypeScriptの型情報を利用して、よくあるミスを洗い出してくれるいい子ですが、そのかわり1回TypeScriptのパーサーを挟むので重い・遅い・メモリを食うという状況になります。
重すぎるので今までCI以外では切っていたんですが、Flat Config化するにあたり、せっかくなら普段のVSCode上でエラーも出したいしということでTypeScript ESLintを全体有効化したところ、設定が誤っていて今までモノレポ環境のLintでTypeScript関連のルールが動いていなかったことが判明。エラーが2つぐらいでるようになったのは良いのですが、何やったってCIがメモリエラーで死ぬ。何なら32GBある私のPCもメモリエラーが吐かれる。
下記のようなエラーですね。
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
調べたところ、ちょうど今日解決策がissueに投稿されていました。
EXPERIMENTAL_useProjectService
というプロパティを設定すればよいようです。
flat configであれば下記のようにparserOptions
を設定しましょう。
export default [
{
languageOptions: {
parserOptions: {
...,
EXPERIMENTAL_useProjectService: true,
},
},
}
]
EXPERIMENTAL_useProjectServiceは名前の通りまだexpreimentalな機能です。
TypeScript ESLintが重い理由はts.CreateProgram
を利用しているからです(多分)。
で、上記を有効にすると、こんな感じでASTを取得します。
const program = service
.getDefaultProjectForFile(scriptInfo!.fileName, true)!
.getLanguageService(/*ensureSynchronized*/ true)
.getProgram();
これがなぜ早くなるのか、正直全くわかりませんが実際にOOMが解決されるのでなにか意味があるのでしょう。
Copilot3.5では無理でしたが、Claudeで聞くといい感じに答えてくれます。全然情報が無いですね…。
私のJS Test Outlineもts.Program利用しているので、ProjectServiceの利用を検討してみようかしら。
最近よく「一瞬だけこのブランチに移動して、その後もとに戻る」という操作を行っている。しかし、びっくりするぐらい短期力に難がある私にとって3分前に切り替えたブランチ名は忘れるのである。
調べると最後に触っているブランチへ戻る方法があった。
$ git switch -
# 上は下記の糖衣構文。-1の部分を2とか3とかにすればもっと遡れる。HEADみたいなもんすね
$ git switch -@{-1}
またreflogにもログが残っている。
$ git reflog | grep switch
12345abce HEAD@{0}: checkout: moving from master to release
参考:
https://qiita.com/ginpei/items/2e0cd22df0670b3a1c3f
https://ginpen.com/2022/12/09/git-back-to-last-branch/
https://zenn.dev/yajamon/articles/422ecab49804f9
私は、何らかの人間に対する計測時にハックされる可能性を必ず考慮する。
例えば給料の査定(私自身にそんな権限はないが)だったりもそうだし、生産性を上げるときの計測対象なんかは最近専ら議論している。
こういった話をした時にチームメンバーから教えていただいたのが、グッドハートの法則。
グッドハートの法則は「指標が目標となると、それは良い指標ではなくなる」と説明されている。これだと、巷で噂のKPIは良い指標ではないのかと突っ込みたくはなるが、言いたいことはそうではないと思う。裏まで読むと「指標にすべきではない指標が目標となると、それは良い指標ではなくなる」、言ってしまえば目標とすべき指標はちゃんと選べよということかもしれない。
例えば、生産性の目標としてPR数を指標とした。PR数が上がれば生産性が上がったよねとする。そうなると、俺は通常より細かい単位でPRを作る。そうすれば生産性が上がるから。本当の目標は「生産性を上げる」なのに「PR数を作る」という、俗に言うと手段と目的が入れ替わっている状態となる。
これじゃ駄目だよねという話。
複数の指標を測る・加えて一部の指標を定性的な目標にする、等少なくともハックできないようなものにする。または、目的 = 指標(目的 ∈ 指標)となるような指標を選択することが回避に大切だと思う。
例えば生産性を測るためにFour Keysを利用する。この場合目的 = 指標とは言いづらいが、統計的に有為であるため問題はないといえる。
具体例としては コブラ効果 などもその例だろう。寓話っぽくて好き。
また、キャンベルの法則という似たような法則もある。
言語処理の文脈で、度々Unicode正規化という言葉を聞く。言葉や処理自体は知っていたが、いくつか種類があるようなので改めて調べてみた。
Unicode正規化(ユニコードせいきか、英語: Unicode normalization)とは、等価な文字や文字の並びを統一的な内部表現に変換することでテキストの比較を容易にする、テキスト正規化処理の一種である。
具体的に、正規化には4種類ある。
末尾のD・CはそれぞれDecomposition(分割)・Composition(結合)である。Dの場合は正規化した上で分解したまま、Cの場合は分解した後結合する。
Kの有無だが、これは正準等価(K無し)・互換等価(K有り)の違いらしい。具体的には調べていないが、正準等価に比べ互換等価の方が緩く分解されるらしい。
JavaScriptにおいてはString
にnormalize
メソッドが生えているため、それを利用することでノーマライズが可能である。
$ node
> const char = "ギ"
undefined
> char.normalize("NFD")
'ギ'
> char.normalize("NFC")
'ギ'
> char.normalize("NFKD")
'ギ'
> char.normalize("NFKD").length
2
> char.normalize("NFKC")
'ギ'
> char.normalize("NFKC").length
1
SPACEという生産性のためのフレームワークを知った。
生産性のフレームワークは有名所だとFour Keysがあるが、SPACEは下記の5つの指標で構成されている。
Four Keysと比べると、人の満足度、コミュニケーション的な部分が加わっている印象。
システムの健全さを表す指標がFour Keysなら、チームの健全さを表す指標がSPACEなのかな、と感じた。
ちなみにForu KeysやこのSAPCEをまとめて DPE(Developer Productivity Engineering) と呼ぶこともあるらしい。
JavaScriptにおける剰余の正負の結果を毎回忘れる。 常に被除数と同一 と覚えればいいと学んだ。
被除数はすなわち「割られる数」であり a % b
において a
である。
$ node
Welcome to Node.js v20.5.0.
Type ".help" for more information.
> 17 % 7
3
> 17 % - 7
3
> -17 % 7
-3
> -17 % -7
-3
Wikipediaに言語ごとにまとまっていて非常に良かった。
autoImportFileExcludePatterns
というフラグがある。これを設定することで、自動インポートの対象から省かれDX(Developer eXperience)が向上する。
例えば、User
というよくあるクラス名は既存のライブラリからもExportされていることが多い(Sentry
や DataDog
など)。
これらを指定すればそれらのライブラリからの自動インポートを省いてくれる。
弱点としてはVSCodeにしか対応していない(正確に言えばTS Serverのオプションなので設定さえすればVimとかでも問題ないとは思う)のと、ライブラリごと省かれてしまうこと。
どうしても回避したいなら独自のTS Language Server Pluginを書けば良いと思うが…。
ちなみにTypeScript4.8以降の機能。
https://devblogs.microsoft.com/typescript/announcing-typescript-4-8-rc/#exclude-specific-files-from-auto-imports
文字列検索の文脈でTrie(トライ)というデータ構造を知った。retrieval
から取られたようだ。
検索文字列の辞書がある場合、その辞書の長さに関わらず一定のオーダーで検索できるのが強みらしい。
画像周りが正直面倒くさ過ぎたため、MDXでなんとかできれば嬉しい。
内部的には remark
を使っているらしい。ちなみに昔僕が使おうとしていたのは marked
で、現在使っているのが markdown-it
。
https://nextjs.org/docs/pages/building-your-application/configuring/mdx
選択範囲に対して、行番号を右クリックすることで、Permalinkが取得できる。
TILはToday I Learnedの略で、今日学んだことを振り返る意味がある。
GithubにTILリポジトリを作り、Markdownか何かを作るフレームワーク的なものが広がったらしい。
Slackのtimesチャンネルによく「こんなのあるんだ」的なのを呟いていたが、振り返りづらすぎるため、僕のBlogサービスにTIL的な機能を載っけてみる。
ほぼブログみたいなもんだが、もうちょい腰を据えずに自分向けの記事を書いていくつもり。