Safari は回転制御できない
こんな機能見つけました
https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/lock

モバイル端末の回転を制御できるようです
ゲームなど一部のアプリだと縦長か横長どっちかの表示のみだったりします
でも Web だとそれができなくて不便です
viewport 固定で横長専用とかしたいのですけど

それがこれをつかえばできる!と思ってました
でも Safari (iOS) は非対応でした
モバイル端末考えると iOS シェアは多いですし Android だけできてもなぁという気分です

これに限らず Safari って独自の使用があったり変な動きしたりと扱いづらいです
新機能の実装も Firefox のほうが早いことが多くて全部で動くものとなると Safari がネックになってることも多いです

Win7 のサポートが終わって IE 対応がほぼなくなると Safari が第二の IE になるようにしか思えません……
一番の問題は iOS で Chrome など別のブラウザ入れてもエンジンは Safari の Webkit 固定なんですよね
Go → Rust てよくみるよね
Discord も Go → Rust に切り替えたらしいです

https://blog.discordapp.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f

けっこうこの移行よくみかけますね
最近だとネイティブにビルドできるメジャーなものといえばだいたいこの 2 つだからかな

C/C++ は複雑で避けられがちですし D はまだ生きてたのって感じですし
.NET 系は Core は Linux などで動くとはいってもネイティブとはちょっと違いますし
同じく Java 系も

個人的には Go は興味なくて Rust は興味あるので Rust に移行するプロダクトが多いのは嬉しいことです

そういえば deno も当初は Go で実装していて どうして Rust にしないの? みたいなこと言われて Rust にしたんでしたっけ
そんな deno も予定では 2 月末に 1.0 でるらしいです
完全 Web 互換らしいのでリリースしたら使ってみようかと期待してます
ツリー構造の要素をひとつずつ返してくれるジェネレータ
function* treeIter(root) {
yield root
for(const child of root.children || []) {
yield* treeIter(child)
}
}
const tree = {
name: "root",
children: [
{
name: "item1",
children: [
{
name: "11",
children: [
{
name: "111",
children: [],
}
],
},
{
name: "12",
children: [],
},
{
name: "13",
children: [],
}
],
},
{
name: "item2",
children: [
{
name: "21",
children: [],
}
],
},
],
}

Array.from(treeIter(tree), x => x.name)
// ["root", "item1", "11", "111", "12", "13", "item2", "21"]

JavaScript でタプル
必要性はともかく変更不可版 Array ということでこれでよさそう
中身同じでも等しいものにならないのが不便かも

class Tuple extends Array {
constructor(...a) {
super()
this.push(...a)
Object.freeze(this)
}
}

作ったタプルをすべて保存しておいて同じ中身なら既存のを返せばできそうだけどメモリ的につらそう
WeakSet を forEach できたらいいのに
JSON 比較
JSON を比較したいとき文字列比較だと オブジェクトの順番の違いでも違うもの扱いされる
オブジェクトや配列を再帰的にチェックしていくのは面倒
片方のプロパティ全部をもう片方と全部比較しても もう片方のほうにしか無いプロパティもあったり 考慮することが意外とあってコードも長くなる

短く書きたかったので オブジェクトは Object.entries の形式化してソートするだけ
比較は JSON.stringify した文字列比較に任せる方針なもの作ってみた

const rec = v =>
(v instanceof Object && !Array.isArray(v)) ?
Object.entries(v).map(x => [x[0], rec(x[1])]).sort((a, b) => a[0].localeCompare(b[0]))
:
v

const jsonDiff = (a, b) =>
JSON.stringify(rec(a)) === JSON.stringify(rec(b))

jsonDiff({a: 1, b: 2}, {b: 2, a: 1})
// true

JSON.stringify({a: 1, b: 2}) === JSON.stringify({b: 2, a: 1})
// false

JSON を比較するくらい標準機能にあってもいいと思うのに
SQL で列名が被って困る
SQL の列名は同じ種類の ID なら同じ名前にしておけば USING(xx_id) で JOIN できたり便利なので 列名を一意にしようなんて思ったことはありませんでした

しかし 「SELECT * FROM ~」 のように全取得してると LEFT JOIN で JOIN 先にマッチする行がないと id が null になってしまう問題に困りました
同じ列名なのでオブジェクトや連想配列やディクショナリとして取得するとあとの方の null で上書きされてしまうのですよね
「*」 を使わず全部書けば解決ですが 長いです
ワイルドカードで除外が選べれば助かるケースはかなりあるのですが SQL では対応してません
それに SQL って全然更新されないので JavaScript などのように待てば便利なる期待もありません
せめて 「select a.* as a__*」 で a__ プレフィックスつけてくれるみたいなのができたらよかったのですけど

それで思ったのが最初から列名を 「tablename__columnname」 みたいなのにしておくことです
見た目はいまいちですが JOIN が入ってくると列名が被る可能性があって 結局 WHERE や SELECT で 「tablename.columnname」 のようにテーブル名も含めて書くならあんまり変わりません
とはいえやっぱり長いし 実際に 「tablename.columnname」 と書くときはエイリアス使って 1, 2 文字のテーブル名です
なのでエイリアスを含めた 「tablealias__columnname」 にしておくのはありな気がしました
列名指定のためのエイリアスが不要になりますし

CREATE TABLE foo (
f__id integer,
f__name text,
PRIMARY KEY (f__id)
);
CREATE TABLE bar (
b__id integer,
b__name text,
b__f_id integer,
PRIMARY KEY (b__id)
);

SELECT * FROM foo LEFT JOIN bar ON f__id = b__f_id WHERE f__id < 10;
JavaScript int max
// signed int32 max
-1 >>> 1
// 2147483647

// unsigned int32 max
-1 >>> 0
// 4294967295

// number max
Number.MAX_SAFE_INTEGER
// 9007199254740991
サーバ使えない環境で proxy
長いクエリがある URL に短縮 URL を作って リダイレクトせず短縮 URL のまま表示する
サーバサイドも使えれば長い URL のページへ proxy するだけで済むので単純
静的ファイルのみしか使えない場合はどうしようかと考えたら全画面 iframe 使うだけだった

<!doctype html>

<style>
body { margin: 0; }
iframe {
display: block;
width: 100vw;
height: 100vh;
border: 0;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<iframe src="page.html"></iframe>

src の page.html のところに長い URL を設定する
iframe だけのページを iframe の URL 変えながらたくさん作るのも面倒なのでマッピングのデータの json をロードして今のページに対する長い URL を動的に作るほうがいいかも
ページ数分の大きめな json を毎回ロードすることになるけど キャッシュされればそこまで困るほどでもなさそう

JSONP ふうに iframe への設定も含めとくとか

!function(values) {
document.querySelector("iframe").src = values[location.pathname]
}({
"/azj4": "/foo/bar.html?longlonglong=query",
"/bj9c": "/long-url.html",
// ...
// ....
})
Chrome でたまにあるアップデートできない現象
何が悪いんだろう?

chrome://settings/help

でアップデートありになってアップデート完了して再起動ボタン押したのに同じバージョンで起動される
一度起きると何回繰り返しても一緒
手動再起動で Chrome を終了して Chrome のプロセスがないのを確認してから再起動してもだめ
タスクスケジューラから GoogleUpdate を手動実行してもだめ

とりあえず new_chrome.exe 使えば新しいバージョンを使えるけど 普通に起動していようにアップデート完了させたい

C:\Program Files (x86)\Google\Chrome\Application\new_chrome.exe
Twitter で見かけた筆算の問題を力技でやってみた
話題になっててまとめられてたツイートでこんなのがありました
https://twitter.com/aty_carbuncle/status/1224323674372657156

うーむ 難しそうですね
考えるのが面倒になってきますね

……総当りでやればいいや

const f = (a, b) => {
const s = String(a * 10 / b)
if(!(s.length === 3 && s[2] !== "0")) return
const [x, y, z] = Array.from(s, e => e * b)
if(!(x % 10 === 6 && String(x).length === 3 && String(y).length === 2 && String(z).length === 2)) return
const xx = ~~(a / 10) - x
if(!(String(xx).length === 2)) return
const yy = xx * 10 + (a % 10) - y
if(!(String(yy).length === 1)) return
return true
}
for(let i=1000;i<10000;i++){
for(let j=10;j<100;j++) {
f(i, j) && console.log(i, j, i/j)
}
}
1365  14  97.5

その場の勢いで雑につくったものなので変数名とかはテキトー
結果は無事正解でしたが ほんとにひとつしか当てはまるものがないんですねー
中1でこれはすごい
Chrome で表示されるインスタンスの型名
Chrome だと

const x = class {}
new x()
// x {}

のように型名が変数名から推測されて表示されます
プロパティ名を使えば変数名に使えない文字列も使えます

const tmp = {}
tmp["a123@*+<>%$#ABC"] = class {}
const c = tmp["a123@*+<>%$#ABC"]
new c()
// tmp.a123@*+<>%$#ABC {}

オブジェクトの名前の tmp も入ってしまいますが結構便利です
やりたいことは動的に名前をつけることで いざやってみると

const tmp = {}
const random = "c" + ~~(Math.random() * 100)
tmp[random] = class {}
const c = tmp[random]
new c()
// tmp.<computed> {}

静的に判断しているようで変数になっていればすべて <computed> になりました

この機能を活かせるところは少なそうです
そもそも Chrome のみで Firefox では全部 Object 表示なので そこまで積極的に使っていくべきとも言えないです
オーバーロード的なことするときの書き方
こういう関数があります

const fn = (target) => {
if (!target) {
for (const item of getAll()) {
something(item)
}
} else {
something(target)
}
}

引数 target が指定されていたらそれを something 関数に渡します
指定されてなければ getAll で全部を取得した上で for 文で全部を something に渡します

引数があればそれを なければ全部を対象になにかの処理をするというものです

something 関数程度ならこれでいいのですが something が長くなってくると同じものを 2 箇所に書きたくないです
同じものを 2 回書きたくないなら関数にまとめてしまうのが簡単です

const fn = (target) => {
const f = (arg) => { something(arg) }
if (!target) {
for (const item of getAll()) {
f(item)
}
} else {
f(target)
}
}

シンプルなもののはずなのに内部に関数もあったりでごちゃごちゃしてきた感じがします
毎回 1 回余分に関数呼び出しも入りますし もうちょっと別の方法を考えたいです

関数呼び出しを使わない方針で考えると something 部分は固定でそれより前に処理する対象を 1 つの変数に入れておくと場合分けがあっても 1 つの記述で済みます
今回は一方では for 文で複数回実行するので
for 文の中に書く前提で target が渡されたらそれ単体の配列にします

const fn = (target) => {
const targets = target ? [target] : getAll()
for (const t of targets) {
something(t)
}
}

短くなりましたが target 指定のほうがメイン(の想定)なのにわざわざ配列化するのは無駄な感じがします
それに本来この関数がやりたい something が for の中で常にループするのでやりたいことがパット見分かりづらい感じもします
作り的にはオーバーロードにあたるもので その機能がある言語でのやり方を考えてみます
それらは別々の関数になっていて 引数なし版では for 文の中で引数あり版の関数を呼び出すはずです
その考え方でやってみると

const fn = (target) => {
if (!target) {
for (const item of getAll()) {
fn(item)
}
return
}
something(target)
}

忘れがちな return があったりさっきのより長くなってるのが気になりますが 一番アリかなって気もします
前半後半で分けて見ると 前半は引数チェック的なもので この関数で本来やりたいことじゃない部分
後半が本来やりたい部分で something に引数の target を入れて実行となってます

再帰関数呼び出ししてるので 1 つ前のコードではなくした関数呼び出しをしてしまってますが その関数がやりたいコードを直接実行するようにして それより前に例外的な場合は引数修正して再実行という考え方がしっくり来ました
その関数がやりたいことが for の中やローカル関数内に押し込められるとやりたいことがわかりづらくなりますからね
先に取り出す元を書くべきだと思う
JavaScript 書いてて気になったこと

import { foo, bar } from "./module.js"

const { x, y } = obj

補完できない

VSCode などでこういったコードを書くとき {} の中では取り出すオブジェクトなどから変数名を候補に出してくれます
長い名前だと候補が出てくるのはありがたいです

ですが コードを前から順に書いていくと取り出す元となるものがわからないです
module.js が先にわかればその中に foo があることがわかるので f を打てば foo を候補に出せます
しかし どこからロードするかわからないときに f を打っても foo を出すのは難しいです

候補から補完する機能を使いたいなら取り出すものは一旦書かずに 先にどこから取り出すかを書いてから戻ってくるという面倒な書き方が強制されます
コードの見た目から動作を推測するという意味では今の JavaScript のコードは良いと思いますが エディタの補完機能とは相性よくないです

ただ Python は先に from を書くので順番的には理想どおりのはずなのですが 何してるのかや仕組みがわかりづらくて JavaScript のほうがよく見えるのですよね
先頭セミコロンは ! でいいかも
JavaScript でセミコロン使わない場合 「(」や「[」で始まる場合に文の結合を防ぐため文頭に「;」を書く方法があります
まず console 以外で「(」や「[」で始める書き方がほぼしないのでこの 1 年だと特に書いた覚えないですが極稀にあります

先頭セミコロンってやっぱり見た目に違和感があるので他のものにできないか考えてみると「;」の代わりに「!」でいいんじゃないかと思いました
! は前の文とつながらないのでそこが切れ目になります
「(」や「[」から始める場合は式なので構文的に問題はないです
また 評価結果の値は使われないもので ! で boolean キャストと反転しても困りません

[1, 2].forEach(fn)

![1, 2].forEach(fn)

基本的に先頭セミコロン入れる必要があるところはわかりづらい変なことしてるところと言ってもいいくらいなので ! を入れて強調しとけばいいと思います

一応 代入式など ! を入れると使えないものもあります
ただ 「(」から始める代入式とか見づらいものになるのでむしろそういうのを使わないためにも ! でいい気がします
分散処理
分散的な処理って LB 的な存在がインスタンスに処理を押し付けてくタイプのが多いイメージ
分散先のインスタンスの負荷を見て適切に分散ってちゃんとやるの結構難しいと思う
2 つに分散する場合で単純に交互に処理させてたら 偶数番目のほうが重い処理になってたら片方に負荷が集中するし
それにトラブル起きて動かない状態になっててもそれを検出できるまではジョブを送ってしまう

そう考えてると一箇所のキューでジョブをためて分散処理する各インスタンスがジョブを取りに来て処理する作りのほうがいいのかなって思う
押し付けられるわけじゃないから余裕ある状態になったら取りに行けばいいし 処理を行えない状態ならジョブを取りに行かなければいい
キューに溜まってる量で負荷レベルがわかるってメリットもある

単純に分散先にジョブ送るよりも複雑にはなるけど メリットも大きい気がする
こういう仕組みのものってこれと言って見ないけど何か無いかな
PostgreSQL のユーザとグループ
PostgreSQL だとユーザもグループもロールで管理される
ログイン許可すればユーザ扱いでログインを許可しなければグループ扱い
テーブルの所有者のロールをグループにしておけば ユーザをそのグループに所属させてテーブルへの権限を与えられる
グループに所属させる GRANT コマンドは「GRANT グループ名 TO ユーザ名」でグループをユーザへ GRANT (付与)

CREATE ROLE "test_group";
CREATE ROLE "test_user1" WITH LOGIN PASSWORD 'PASSWORD';
GRANT "test_group" TO "test_user1";

CREATE TABLE kv
(
key text NOT NULL,
value text,
CONSTRAINT common_setting_pkey PRIMARY KEY (key)
);
ALTER TABLE kv OWNER TO "test_group";

postgres=# \du
ロール一覧
ロール名 | 属性 | 所属グループ
------------+----------------------------------------------------------------------------+--------------
postgres | スーパーユーザ, ロール作成可, DB作成可, レプリケーション可, RLS のバイパス | {}
test_group | ログインできません | {}
test_user1 | | {test_group}
PL/V8 みつけた
sql ファイルでちょっと複雑な処理したいけど SQL でできるの?
→ぐぐったらできそうなコードがあるけどどう動かすのか調べてみたら PL/pgSQL

DO statement で使えるぽいけどあんまり使いたくない
他になにかないのかな
→PL/Python があった

良さげだけど Python のインストールとか準備面倒そう
Python あるなら JavaScript もあるんじゃないの?
PL/V8 があった

11 時点のドキュメントだと Python や Perl は PL/* に載ってるけど V8 はない
まだマイナーどころかも

JavaScript でやるなら node-postgres を使って Node.js でやればいいんだけど ちょっと使った感じではそれらを準備するより楽に使える
Node.js で使うとコネクションとか非同期クエリ実行とか色々考えるところや面倒なところあり
PL/V8 だと DB 内で処理されるわけだからクエリは同期的だし 面倒な準備も不要
psql で接続して SELECT や INSERT 文の代わりに JavaScript 書く感じ
普通に Node.js でやるよりはいいかも

それに その場での実行だけじゃなくて関数も作れる
複雑な条件の SQL 処理は全部事前に関数を作っておいて クライアントでは関数呼び出すだけで済むようにすると便利そう
複数回 SQL を実行して結果をまとめたりするのを Node.js でやるよりは PostgreSQL 側でやってしまったほうが無駄な通信も減らせる
PostgreSQL は JSON でデータ返せるから JavaScript で処理した結果を返すのにも向いてる
なにより SQL ではやりたいことの関数名と引数だけで済むほうが Node.js 側がスッキリする

ただ PL/V8 内の SQL の実行は関数呼び出しになるので if 文で分岐や変数埋め込みしたい程度ならあんまり見やすくならない
SQL を直接書ける PL/pgSQL のほうが見やすくかけそう
クエリ結果のデータを処理する部分で JavaScript 使いたいくらいじゃないとメリットは少ないかも
JavaScript 関連のツールの評価
https://news.mynavi.jp/article/20191231-947217/

ユーザ数と満足度から JavaScript 関連技術で使うべきと避けるべきを分類してるみたい
拡大しても小さくて画像ファイルに直接アクセスしないと見づらいので直接 jpg の URL⇩
https://news.mynavi.jp/article/20191231-947217/images/002l.jpg

最初に思ったのはなぜ express がそこにいるの?って思ったけどなんだかんだユーザ数は多いからなぁ
個人的には今新しく作るときに express は選択肢にならないし angular と同じ場所の再評価すべきだと思う
最近はほぼ更新されてないし 5.0 もずっと放置されてた気がする
まぁ express はほとんどミドルウェアだよりで express 自体を深く使う人はあんまりいなそうだしそういう意味では満足度が低くはならないのかも

ASSESS のところは Nuxt とか Koa とかもあるし 2000 より右側なら十分選択肢だと思う
それより左は purescript や clojurescript や elm みたいに人を選ぶもので あえて使う人には満足度高いだろうけど多くの人には向いてないって感じ

AVOID にいるのは NW.js は electron にほぼ置き換わってしまったし meteor は一時期話題になってたけどそれ以降全然聞かなくなってまあ妥当かなって思う
以前少しだけ meteor 使ってみたけど 問題あって動かなかったり作り方もそんなに興味持てなくて サーバも JavaScript で作るからといってこれ選ぼうとはあんまり思わなかったくらいだし
Cordova はいつか使ってみようかなくらいには興味はあったものの 位置的にもあんまり満足度高くないみたい
モバイルで Web 技術使うなら React Native になるのかなー

再評価すべきな場所に 1 つだけある angular
angular.js の頃はそれなりに記事も見かけたけど angular になってからは全然見なくなって 稀に見たと思えば愚痴のような記事ばかり
聞いてる感じだと 全部入りのような高機能だけど冗長なコードが多かったり見づらかったりとからしい
React や Vue みたいに部分的に気軽に使えるものとは違うみたいだし angular だと他に置き換えるのも大変みたいで仕方なく使ってるのが多いのかも
ページを開いた時刻を知りたい
ページを開いた時刻を知りたいことがありました
devtools の Network タブに書いてるかなと思ったのですが リクエストからレスポンスまでの時間などはありましたがリクエスト時のタイムスタンプはありませんでした
レスポンスのヘッダーに時刻が含まれるケースもありますがサーバ次第で このときのページではそういった情報はありませんでした
ほとんどのサイトはなにかのエラーや警告がコンソールに出ているので そのタイムスタンプで判断できるのですが このときのページではコンソールには一切何も表示されていませんでした

ちょっと裏技的なテクニックで「fetch("")」 を実行すればリクエストが送られるので Network タブのリクエスト発生時刻を表すグラフの部分が広がります
そこの右端が今のはずなので 150000ms になってれば今は開いてから 15 秒だから 15 秒前は……と一応はわかります
ただ はっきりした時刻として取得できるわけではないので目安程度です

正確なタイムスタンプを取得できる方法はないものかと探していると 以前どこかでページ開いた時刻が何かの変数に入ってると見たはず と思って探してみると

performance.timeOrigin

でした
小数でマイクロ秒まで保存されています

その他 リクエスト開始など細かいイベントごとの時刻情報を performance.timing で見ることができます
timeOrigin はこれらより先にきます

const r = Object.entries(Object.getOwnPropertyDescriptors(PerformanceTiming.prototype))
.filter(([k, v]) => typeof v.get === "function")
.map(([k]) => [k, performance.timing[k]])
.sort((a, b) => a[1] - b[1])

console.table(r)
"redirectStart"               0
"redirectEnd" 0
"secureConnectionStart" 0
"navigationStart" 1577883464480
"fetchStart" 1577883464480
"domainLookupStart" 1577883464527
"domainLookupEnd" 1577883464527
"connectStart" 1577883464527
"connectEnd" 1577883464532
"requestStart" 1577883464532
"responseStart" 1577883464547
"responseEnd" 1577883464548
"unloadEventStart" 1577883464552
"unloadEventEnd" 1577883464552
"domLoading" 1577883464555
"domInteractive" 1577883464571
"domContentLoadedEventStart" 1577883464571
"domContentLoadedEventEnd" 1577883464571
"domComplete" 1577883464609
"loadEventStart" 1577883464609
"loadEventEnd" 1577883464609
PostgreSQL で date $1 はできない
プログラムから SQL を実行するときに変数を埋め込むことができますが 使える場所と使えない場所があります

select date '2020-01-01 10:20:30'

のようなリテラルの場合は date を前に書くだけで date 型にキャストされますが ここを $1 にすることはできないです
date($1) や $1::date でキャストする必要があります

実際の値で SQL を書いてから変数化するとハマりやすいんですよね

/// c は pg.Client

> c.query("select date '2020-01-01 10:20:30'").then(x => console.log(x.rows)).catch(console.error)
// [ { date: 2019-12-31T15:00:00.000Z } ]

> c.query("select date $1", [new Date()]).then(x => console.log(x.rows)).catch(console.error)
// error: syntax error at or near "$1"

> c.query("select date($1)", [new Date()]).then(x => console.log(x.rows)).catch(console.error)
// [ { date: 2020-01-05T15:00:00.000Z } ]

> c.query("select $1::date", [new Date()]).then(x => console.log(x.rows)).catch(console.error)
// [ { date: 2020-01-05T15:00:00.000Z } ]
V8 は関数の結果をキャッシュするの?
ネットを見ていて V8 の説明に最適化で結果をキャッシュして同じ場合は再実行しないみたいなことを書いてるのを見かけました
同じ処理というと関数を指してるように思います

関数でも外部の値を使う場合は結果が変わる場合もあるので 引数のみで結果が決まる場合のみ高速化できるように思います
外部の値が変わってないならキャッシュしたままということもできそうです
ということでこういうコードを用意しました

let x = { a: 1 }

function a(p, q) {
return p + q + x.a
}

function b(p, q) {
const x = { a: 1 }
return p + q + x.a
}

console.time("a")
for(let i = 0;i<100000;i++) {
a(10, 20)
}
console.timeEnd("a")

console.time("b")
for(let i = 0;i<100000;i++) {
b(10, 20)
}
console.timeEnd("b")

a の方はグローバルスコープの x を参照しますが b の方は関数スコープ内の x を使います
つまり a は同じ引数でも結果が変わるかもしれませんが b は固定です
最適化で結果のキャッシュがされているなら b のほうが早いはずです
もし a が使う x が変化しないから a も最適化できていれば 一緒になるはずです

やってみると

a: 2.569091796875ms
b: 3.18212890625ms

b のほうが遅いです
そうなると最適化で実行結果のキャッシュは行われず b のほうは毎回 x のオブジェクトを作ってるから a のほうが速いと考えられます
いつもながら V8 の最適化は複雑で何したら速くなるかがわかりづらいですね
UA でブロックするのは仕方ないと思うの
こんな記事見かけました
https://qiita.com/NumLocker/items/61da0ce5bc65cbb3c7ff

UserAgent が Vivaldi なら動かないようにしてたサービスがあったそうです
私自身 Chrome と Vivaldi の両方を使っていてブログ関係のサービスは Vivaldi で使ってます
ですが ウェブページを作る側からするとこれは仕方ないものだと思ってます

ちゃんとしたサービスほどちゃんとサポートブラウザが決められていてそれで動くように確認してます
だいたいは IE と Chrome あたりでしょう
そこにマイナーは Vivaldi とかまで入れるのはコストのほうが大きいので普通はサポートしないです
しないなら何もしなければいいのですが 変に見えてしまう以上 動きがおかしかったらブラウザじゃなくウェブページ側にバグってるよって報告されるわけです
その原因がブラウザで サポート外のブラウザだからだとしてもユーザはまずウェブページの問題と思うでしょう
それなら最初からサポートしてませんって表示してしまうのが楽です

それでも見たい場合 UserAgent を偽装すればいいだけですし わざわざ偽装してるくらいなのでちゃんと動かなくても自分が無理やり見てるせいですよーと思ってもらえます

Vivaldi なら中身 Chrome だからそう動かないことなんて無いと思うかもですが出た当初はひどいものでした
今は devtools とかを除けば割と安定してると思いますが 昔は画面崩れるとか JavaScript が一部動かないしとか問題ばかりでした
JavaScript が動かないというよりもブラウザの挙動のほうが優先されて一部の操作を受け付けないみたいな感じだったかも
あと URL バーあたりもなにかあったような

まあ Google のテキストボックスがずれるのはただの嫌がらせだと思いますけどね
Youtube で空 div を出してパフォーマンス落ちるようにしたとかいう話もありますし
そういえば Firefox でだけ Google Maps がおかしなことになるのもあったっけ
HTML のクリックした単語を取得って難しい
クリックした単語を取得しようと思ったのですが思いの外難しいです
ここでは英単語のようにスペース区切りだけを扱って日本語を形態素解析してーとかいう話は無しです

まずクリックした場所の文字を判定する方法
単語ごとに span タグでわかれていないと長い p タグの中からどうやって判定するんだろう?
というところですが これは document.getSelection() を使えば Node とクリックした場所の offset が取得できるので簡単です

困るのはタグが挟まってる場合です
単語の途中で一部だけを色を付けたいとかそういう用途で単語の途中でタグが入る場合があります
タグの前後にスペースがないならつながった文字とみなせば良さそうですが div の場合は改行なのでスペースがなくても区切るべきです
しかし これは div に限ったものではありません
HTML の表示は CSS で変えれるので span でも改行してるかもしれませんし タグが挟まるとつなげてよいかの判断が難しいです

自分で用意した HTML のみが対象ならやりようはありますが任意の HTML でやろうとすると結構難しいです
特殊な場合は扱わないと割り切って タグ内だけで判定したり デフォルトが inline のタグかつ前後にスペースない場合のみ結合した上で判定するくらいがいいのかもしれませんね
Node.js だとリクエストの処理強制終了がめんどう
リクエストごとにプロセスが存在して独立してるよりも 全リクエストを 1 つのプログラム中の処理として処理できる Node.js のほうが好きですが リクエストの処理を強制終了するのが難しめです
個別のプロセスならそれを kill するだけのシンプルな作りで済みます
それも基本は自分で制御することはなくて タイムアウトだけ指定しておけば Web サーバがやってくれることがほとんどです

Node.js だと Web サーバ自体をコード書いて作るから タイムアウトの処理も自分で書くことになります
と言ってもレスポンスとしてエラーを返すだけなら簡単です
ただ それだとレスポンスはエラーと返しつつも処理は続行されていて見えないところでリクエストの処理が完了してることもあります
ユーザにはエラーが返ってるけど内部では処理が続いていて完了してるのが困るという場合は処理自体もキャンセルが必要です

Node.js の処理的にはコールバック関数を実行してるだけなので プロセスの kill のように そこから始まる処理のツリーを全部停止みたいな便利なことはできません
できることはキャンセルフラグを用意して 処理の合間に確認してキャンセルならそこまでの処理をキャンセルする処理をして残りの処理はやらないくらいです
これでも十分面倒です

プロセス kill でも途中で終わるだけで戻す処理はなくて完璧ではないので単に以降を処理しないだけでいいかもしれません
DB のトランザクションでもない ファイルの書き込みや削除だけなら途中までの状態で終わります
ファイルを削除して新しいファイル作るという処理で削除だけで終わってるとかありえますからね

それに POST のロード中にブラウザのキャンセルボタン押してもキャンセルしたことは サーバでわからないので画面ではキャンセルされたけど実際には登録済みなんて普通にあるので プロセス kill みたいなことは無理という扱いで無視してもいい気もします
やらなくて良い処理をやってるのでちょっと重くなるかも程度ですし
Chainer 終わったみたい
https://preferred.jp/ja/news/pr20191205/

ネットのニュースで上位にあったから軽く読んでみて 「ある会社が chainer から pytorch に移っただけでなんでそんなに話題なんだろう?」 と理解できなかったので はてぶとかのコメントを見てたら chainer 終了というのがいくつか
それで調べてみたらこの preferred networks って会社は chainer 作ってるところだったんですね……

Chainer のアナウンスでも v7 が最後のメジャーリリースになってました
https://chainer.org/announcement/2019/12/05/released-v7-ja.html

ディープラーニングとか機械学習系って個人でやってみてもあんまり楽しいものでもないので ほぼ使ってないのですが一時的に機械学習系を使っみたことがありました
そのときは使ったのが Chainer でした

そのころ話題のディープラーニングフレームワークはだいたいこの 4 つでした

◯ TensorFlow
◯ Keras
◯ Chainer
◯ PyTorch

他にも MXNet とか Theano とか色々ありましたが プログラミング言語や Web フレームワークでもマイナーどころを探せばいっぱいありますが特別理由でもないとあえてそれらを使う必要はないので ここでもこの 4 つから選びました

Keras は他とはちょっと違って TensorFlow などのラッパーで それらを簡単で扱いやすくしてくれる初心者向けみたいでした
なので最初だしとこれでいいかと思ったのですが 思いの外情報がなくて ネットでも Chainer 使ってみたとか TensorFlow 使ってみたとかで Keras はあまりみませんでした
なので優先度を下げてほかを見ると Chainer と PyTorch は似ていて PyTorch は Chainer の一部をフォークしたものだそうです
TensorFlow か Chainer 系で考えると TensorFlow はサンプルを見てみてもよくわからなかったので Chainer か PyTorch にしました

PyTorch のほうが新しいし こっちに移ってる人も多いらしく PyTorch を考えていたのですが Chainer は日本製のようです
前提知識と基本用語がわかってるなら英語でもいいけど それらがないならやっぱり日本語のほうがいいかなーと Chainer にしました
ただいざ使おうと公式サイトやドキュメントを見ても英語です
日本製どこいった……とか思いながらもう少し探しても日本語での情報はあまり見つけれませんでした
一応日本語版ドキュメントもあったと思いますが 古いバージョンかつ完全なものではなく 海外製で日本語でもそこそこ使われてる OSS と同じようなレベルです

これなら やっぱ PyTorch でいいかなぁと思ってもう少し調べていたら Chainer は numpy で使えますが PyTorch は独自の型でした
そのあたりが Chainer のほうがわかりやすかったので Chainer にしました
numpy は機械学習によらず使える便利なライブラリで少しは知っていたので全く新しい PyTorch のより楽かなってところです

そんなわけで使ってみた Chainer ですが ネットに落ちてるサンプルのネットワークを使ったりちょっとコード変えてみたりくらいで 結局使ったことで何かの役に立ったわけでもないです
ちょっとは知識がついたのでいつか必要になったときには Chainer でいいかなくらいに考えてはいたのですが 使う機会もなく終了してしまいました
less は gzip ファイルも見れた
めったに見ないけど消すわけにもいかないテキストファイルがそこそこなファイルサイズをとってたので gzip しとこうかなーと考えてました
ただ圧縮するとみるとき不便なのが困るところです

gzip を less で見るならまず展開必要なのでこういうの?

zcat file.gz | less

zless とかないのかなって調べてみると普通にありました

さっそく試してみようと zless を使ったはずが……癖で z なしの less コマンドで開いてしまいました
なのに見えてます!
間違って普通のテキストファイル開いたのかなって確認しましたが gzip のファイルでした
less は gzip されていても自動で展開してくれるみたいですね

なら cat は? と思って試したら cat は gzip だとバイナリが表示されました
zcat が必要みたいです

less はユーザが見るために限られるのでバイナリ開くメリットないですが cat は結合や別のコマンドの標準出力に送るために使うから勝手に展開はしないんだと思います
tailwindcss 便利かも
https://tailwindcss.com/

ちょっとした align とか margin/padding とか flex の方向とか
lit-html や hyperhtml で HTML 中に styleMap とか使って直接書こうかなって思うくらいなのも多いし入れとくと便利なのかも
ただこういうのって事前に大量のスタイル定義されるから重そうなのが気になるところ

ちゃんと見てないけど JavaScript でビルドとかあるし 使ってないのは含めないみたいな機能あるのかな
あればすごく良さそうなんだけど
でも JavaScript で文字列結合などからも追加できるから使ってるかを静的に判断するのってかなり難しそうだし無いかな
ライブドアブログのカレンダーが
カレンダーがタグの input より z-index 小さくて裏側にいる
そのせいで一部隠れて日付が選べない場所がある
最近変更多いけど 何もしないでくれるのが一番なんだけど……

これに限らず カレンダーとか input 系って極力ブラウザデフォルトを使ってほしい
こういう問題が起きないのもそうだし 独自のってだいたい使いづらい
特に初めて使うとき

ブラウザデフォルトは基本のものだし多くのところで使われてる
多少使いづらくたって そのブラウザや OS を使ってる人からすれば一番慣れてるもの
細かな使い勝手よりも慣れが一番強いと思う

あとタブレットを使うとき
スマホ表示じゃなくて PC 表示にすることが多い
それでも入力はタッチなんだから入力操作は PC じゃなくてスマホと一緒にしてほしいと思うはず
こういうときライブラリじゃなくてブラウザデフォルト使ってるのが有利だと思う
new を使わない
クラス構文使うと new 必須にされるのが地味に鬱陶しい
普通に関数の場合は new コンテキストじゃなければ中で new したのを返せばいいけどそれもできない

function Foo(a) {
if (this === window || !this) return new Foo()

this.value = a
}

構文を使わなくしたり ラップしたり

const unew = (ctor, proto) => (...a) => {
const ctx = { __proto__: proto }
return ctor(ctx, ...a) || ctx
}

const F = unew(
(self, a, b) => {
self.value = a
self.value1 = self.m(b)
},
{
m(x) {
return this.value + x
},
p() {
return this.value1
},
}
)

F("a", "b").p()
// ab

const unew2 = cls => (...a) => new cls(...a)

const G = unew2(
class {
constructor(a, b) {
this.value = a
this.value1 = this.m(b)
}
m(x) {
return this.value + x
}
p() {
return this.value1
}
}
)

G("a", "b").p()
// ab
分割数制限ありの split は無駄な分割処理はしてない
「残り」を取得できなくて使えない split だけど 一応全分割してるわけじゃなくて必要なところだけしか処理してないので使えるときは使ったほうがよさそう

"a b c".split(" ")[0]
// a
"a b c".split(" ", 1)[0]
// a

console.time(1)
for(let i=0;i<100;i++) "a b".repeat(100000).split(" ")[0]
console.timeEnd(1)

console.time(2)
for(let i=0;i<100;i++) "a b".repeat(100000).split(" ", 1)[0]
console.timeEnd(2)

// 1: 640.7880859375ms
// 2: 14.295166015625ms
v8-compile-cache
yarn のコード見てたら v8-compile-cache っていうのを使ってるみたい
https://github.com/yarnpkg/yarn/blob/v1.19.2/bin/yarn.js#L15

https://github.com/zertosh/v8-compile-cache
https://nodejs.org/api/vm.html#vm_vm_executing_javascript

パースとコンパイルした状態のキャッシュを保存しておいてそれを読み込むことでパースとコンパイル分の時間が短縮される……のかな
サーバみたいな常駐系と違って yarn みたいななにかしてすぐ終了するコマンドラインツールだと コマンド実行のたびにモジュールロードしてコンパイルしてとなって時間かかるから そこを省略できるなら効率良さそう
モジュールが多くて重いコマンド系ツール作るときに使ってみるのありかも
yarn create が Windows だとエラーになる
yarn create を使ってみたらエラーが発生
ドキュメントにある例の "yarn create react-app my-app" コマンドで起きることを確認

エラーは 'C:\Program' が見つからないとかそういう感じのやつ
エラーメッセージを見る限りは単純にパスのクオート漏れ
yarn が内部で実行するコマンドで Node.js のパスを指定する部分で起きてる
Node.js の exe が Program Files 以下にあると使えないぽい

ソース軽く見た感じだと exec じゃなくて spawn を使ってるし自動でクオートされてそうなんだけど
一応バージョンを最新まで上げてみたけど変わらなかった

Windows だと標準インストーラでも Nodist でも Program Files 以下になるからほとんどの人が動かない気がするのに結構前からこの状態
Windows で yarn create 使うような人がそもそも少ないのかも

仕方ないので 私は npm init で代替
Nodist で npm をインストールできない
npm で使おうとした機能が使えなくて npm バージョンを見たら 4
最新は 6.13 だから結構古め

せっかくだから Noidst も一緒にアップデートして Nodist を今の最新の 0.9.1 にした
それから npm をインストールしようとしたら インストールできない

ダウンロードのプログレスバーが途中のところで進まなくなって その後中断される
エラーとかのメッセージは何もなし
バージョンのフォルダは作られてるけど中身が空っぽの状態
実行するファイルがないので 「npm --version」 とか実行してもエラーになる

Chrome で直接ダウンロードするファイルをダウンロードしてみたら普通にダウンロードできた
なんなんだろう?
バグ?

Nodist は独自の管理データは持ってなくて直接フォルダをみてるだけみたいなので とりあえず自分でダウンロードした npm を直接フォルダに配置すれば普通に使えた
配置する場所は

C:\Program Files (x86)\Nodist\npmv

ここにバージョン名のフォルダを作って中にダウンロードした tar.gz を解凍した中身をいれる
npm をダウンロードする場所は 6.13.1 だとここ

https://codeload.github.com/npm/cli/tar.gz/v6.13.1
win10 のファイルダイアログが変わった
win10 を 1909 にしてからファイルやフォルダを開いたり保存したりするダイアログが微妙に変わった気がする
アドレスバーが縦に広かったり色も微妙に違うような気がする
気になったのが最近だから 1909 からのはず たぶん
Amazon で見てる本の図書館蔵書情報を調べるツール
ネットで見かけた便利ツール
Amazon で本を見てたら図書館にあることを教えてくれるみたい
https://sonohon.com/

図書館なんて小さい頃以来言ったこと無いなーとか思ってたけど 考えてみたらどうやってそんな情報とって来てるんだろう?
ちょっと気になったのでソースコードを覗いてみました
API 呼び出ししてるみたいで外部サービスを使ってるみたいです
拡張機能自体は API 呼び出しの結果を表示するだけの小さめのシンプルなものみたい

そもそも Chrome ストアの説明の最後の注意書き見たら
「APIの仕様上で1000リクエスト/時という制限があるため、利用時間帯によっては検索が実行されない時があります。」って書かれてました

それを見て 今度は 各自が API キー取らずツール作成者のキーを使い回すの?と疑問が
それだとユーザ数増えたらすぐに 1000 とか超えそうだけど

ソースを見たところ 3 つの API キーが埋め込まれてました
オプションに 1 つ(設定用?)
バックグラウンド処理に 2 つ(ここがメインの情報取得用みたい)
この 2 つはランダムでどっちかを使うようです

API 制限あるとやりたくなるやつですが 1 アプリがいくつも使っていいのかなと思ってやりづらいやつです
どうせ複数使うなら中途半端に 3 つじゃなくて 20 近くは作っておけばいいのに 2 つだけなのはあんまりユーザ以内想定なのかな
Atom って生きてるの?
Facebook が VSCode をデフォルト開発環境にするみたい
最近はエディタ戦争が終わって VSCode の一強感

最近全く聞かないけど Atom ってどうなってるんだろう?
そういえば Atom って Github が作ってるんだっけ
で Github ってマイクロソフトのものになったわけでマイクロソフト製エディタが VSCode
Atom 続ける必要ないんじゃ……
両方使ったことあるけど Atom のほうが良かったところなんて特に記憶にないし
Python のコンストラクタ
__init__ メソッドに書けばいいって思ってたけど 正確にはコンストラクタじゃないみたい
そういうことを書いたのを時々見かける
コンストラクタのあとに __init__ が呼び出されるとか

じゃあ コンストラクタってどれ?と思ったけど普通に class に書いてるブロックか
このブロック メソッド定義だけというわけじゃなくて 関数みたいな感じで普通に Python の文を書けるし

class C:
foo = 1

if foo == 1:
bar = 2
else:
bar = 4

となると

class Foo:
a = 1

def __init__(self, x):
self.b = x

foo = Foo(10)
print(foo.b)
# 10

は JavaScript 的にはだいたいこういう感じ?

// これを継承したクラスには constructor を書かない
class Class {
constructor(...a) {
return this.__init__(this, ...a)
}
}

class Foo extends Class {
a = 1

__init__(self, x) {
self.b = x
}
}

const foo = new Foo(10)
console.log(foo.b)
// 10

JavaScript の class 構文はブロック内に任意の文は書けないので Python みたいに if とかは使えないけど
C# で static とインスタンスのメソッド呼び出し
久々に C# 使って
static メソッドってどう呼び出せるんだっけ?
PHP の self:: (だったかな?) みたいな直接クラス名書かずに参照できたっけ?
と思って調べたら普通に何もなしでメソッド名だけで呼び出せた

でもたしかインスタンスのメソッドも this 省略できた気がする

> class A
. {
. static int foo() { return 1; }
. int bar() { return 2; }
. public void method() { Console.WriteLine(foo()); Console.WriteLine(bar()); }
. }
> new A().method()
1
2

foo() と bar() どっちも使える
ただ 呼び出し時に this のメソッドなのか static メソッドかわからないのはやっぱり分かりづらい気がする
this は書いてあってほしいけど static って this コンテキストと関係ない普通の関数みたいなものなので こっちは 「A.」 みたいなのなくてメソッド名だけでも良さそうかな
C# ってグローバル関数がなくて全部クラスのメソッドだからグローバル関数風に修飾なしで呼び出せなくて 関数名だけで呼び出ししてたらローカル関数か そのクラスの static メソッドって判断できるだろう (一応例外的な using static があるけどほぼ使わない)
React って親でクラス指定できないの?
WebComponents だと CustomElement がコンポーネントの実体としてあるので そこに属性を設定できます
class をつけることもできて ShadowDOM とのスタイルは親側での指定が優先されます

<component-foo class="abc"></component-foo>

内側で :host に指定したものより優先度が高いので コンポーネントを使う親側で上書き可能です
margin なんかはコンポーネント側で決めるのではなくて 使う側での配置によって決めたいので良い仕組みだと思います

React でもそういう感じでコンポーネントのスタイルを使う親側で指定しようとしたのですが そういう仕組みはなさそうです
コンポーネントの実体は DOM にないので className を指定してもそれはプロパティに渡されるだけです

const App = () => {
return (
<Foo className="abc" />
)
}

自分でコンポーネント内の DOM に props.className を指定しないとダメです

const Foo = props => {
return (
<div className={props.className}>Foo component</div>
)
}

基本全部のコンポーネントでやることになるのでけっこう面倒です
ルートコンポーネント以外にもつけることができる自由度はありますが 普通にそんなことしないのでただ面倒なだけに感じます
自動でやってくれる仕組みはないものですかねー
意外とランク上の方にいた
メインの方のブログは結構前から ★4 になってます
MAX が 5 なので半分より上ってくらい
めったに更新されないブログとかもあるから更新頻度的には 4 くらいで普通なのかなと思ってました
4 の中でもランクは 1500 位くらいでかなり下の方ですし

ですが なんとなく普段見ないカテゴリごとを見てみると けっこう上の方にいて驚きました

blogrank

さすがに開いて一番最初に見えるところにあるなんて思ってなかったので リンク先を確認しましたがあってます

「IT・家電」 カテゴリで 4 位
プログラミングっていうカテゴリもあったのですが 他の選択肢に Windows とか Linux とか Web デザインとか ソフトウェアもあってプログラミングだけでもないかなぁと思って総合的な 「IT・家電」 カテゴリにしてます
ちなみにこっちのサブブログはプログラミングですが閲覧数がほぼないのでランク外です

プログラミングとかも合わせた 「IT・家電(総合)」 でも 16 位でした

★4 の下の方なのに? と驚いたのですがライブドアってそういえば IT 系とかプログラミング系ってあんまり見ないです
まとめブログとかアニメ・ゲーム系が多いと思います
そのあたりの有名ドコロが ★5 で その他のカテゴリだと ★4 でも結構上の方になるみたいですね

その ★4 と言っても記事ごとに見るとなんでこれが?って思うのにアクセス数が多くて自分では役立ちそうっていうのはあまり閲覧数が無いです
JavaScript メインのはずなのに Windows と Linux とか C# とかそのあたりのが人気ですし……

ところでアイコンがデフォルトのままになってますがどこを参照してるのでしょう?
ライブドアのブログアイコンは一応ファビコンと同じのを設定してるのですけど……
0 == 0.0
PHP で 0 === 0.0 が違うってのを見て 「え?そうなの!?」 と思ったので調べてみた

◯ PHP

<?php

var_dump(gettype(0));
var_dump(gettype(0.0));
var_dump(0 == 0);
var_dump(0 === 0.0);
string(7) "integer"
string(6) "double"
bool(true)
bool(false)

int と float (double) が別の型
型が違うから === だと false

◯ Python

他の言語も

> type(0)
<class 'int'>
> type(0.0)
<class 'float'>
> 0 == 0.0
True
> 0 is 0.0
False

Python でも == は同じで is になると False
is は型を見てるわけじゃなくてオブジェクトの参照比較
0 と 0.0 は別のオブジェクトになってるってこと

◯ Ruby

   0.class
=> Integer
0.0.class
=> Float
0 == 0.0
=> true
0 === 0.0
=> true
0.eql?(0.0)
=> false
0.equal?(0.0)
=> false

Ruby は === でも true だったけど eql? と equal? メソッドでも比較ができて
こっちは厳密に比較されるようで false

◯ JavaScript

> typeof 0
'number'
> typeof 0.0
'number'
> 0 == 0
true
> 0 === 0
true

JavaScript は全部 number 型で float 型とかないので 型比較も行う === を使っても true
見分けるのは不可能
これも true ⇩

new Uint8Array(1)[0] === new Float32Array(1)[0]
// true

JavaScript に慣れてるせいで PHP のに驚いたけど number がまとまってるのは少ないし false になるほうが普通なのかな
だけど値比較なら true になるべきだし int と float で同じ値でも型が違うだけで false になるほうが不便そう
== 使えばいいといえばいいんだけど 文字列とかでも変換されて比較されるから予想外なものでも一致しそう
キャストして === がたぶんベストなんだろうけど 数値比較のためだけに毎回キャストするのもなぁ
オブジェクトにまとめる基準
どこかで聞いたような考え方
メソッドの名前が 動詞+対象 になってるのはダメ
対象のメソッドとして動詞がくるようにオブジェクトにまとめるべき みたいの

例えば

moveBox
setCount
removeElement
showWindow

みたいなメソッドがある場合

box.move
count.set
element.remove
window.show

にする
box や count のオブジェクトにまとめる

something.moveBox() を somthing.box.move()

にできるように box をオブジェクト化してそれをプロパティとして持つ

なるほどなー と思ったけど実際にそこまでやるとなると難しいことも多い気がする
厳密なというかしっかりとしたオブジェクト指向にあんまり興味ないので 適当にまとめたい部分をまとめるくらいにしか使ってないけどちゃんとオブジェクトにまとめるならわりと納得できる考え方
気が向けば試してみようかな
クラスか関数か と require か import か
クラスか関数か はコレ⇩

// class
class Foo {
constructor(value) {
this.value = value
}
bar() { return this.value + 1 }
baz() { return 0 }
}
const a = new Foo(100)
a.bar()


// function
const foo = value => {
return {
bar() { return value + 1 },
baz() { return 0 },
}
}
const b = foo(100)
b.bar()

簡単に違いをまとめると

パフォーマンスはクラスのほうが prototype にまとまるので上
クラスだと最近のプライベートプロパティ機能を使わなければデータは全部見えてる
関数のほうだと return オブジェクトに含まなければ見えない

require の視点でみると関数のほうが楽

// function
const module1 = require("module")(options)

// class
const module2 = new (require("module"))(options)

new が必要なのでカッコが追加で必要になる
カッコいれないと require 自体を new することになる
いったん変数に入れてもいい

const Module = require("module")
const module3 = new Module(options)

node_modules では一旦変数に入れず require と同時にオプションを入れてインスタンスを作ってるものも多い
モジュールのインスタンスをモジュール名にしたいときはコンストラクタの名前に迷うし

でも import になると 式じゃないので取得してそのまま呼び出せない

import Module from "module"
const module4 = new Module(options)

require からの書きやすさ的な関数のメリットはなくなるし クラス構文の流行りもあって今後は new が必要なのが増えるのかも
make-promises-safe
make-promises-safe というパッケージを使うことを推奨してるものがあったので どんなのだろうって見てみたら たった 15 行のコード
中身は Node.js で unhandledRejection が起きたときに強制終了させるというもの
Promise が reject されたのにそれを catch してないのは実装ミスでメモリリークにつながるからそれを防ぐためのものらしい
使い方はトップレベルで一回インポートするだけ
それで process.on を使ってリスナ登録される

設定可能な部分は
◯ 強制終了の手段に process.exit か process.abort かを選べる
◯ rejection の reason をログ出力するのに使う関数を設定できる (デフォは console.error)

くらい
コード見た感じだと非同期のログ書き込みだと process.exit のほうが先に行われて書き込みできなそう

あえてライブラリを npm から入れなくても自分でこう書いとけば十分

process.on("unhandledRejection", reason => {
console.error(reason)
process.exit(1)
})

これでリポジトリにスターが 400 近くあるのはちょっと驚き
HTTPS じゃない HTTP2
HTTP2 って全部 HTTPS の暗号化通信になってると思ってたけど Node.js のコードで tls オプションなしに使ってるのがあった
そんなことできたっけと思って調べてみたら

https://nodejs.org/api/http2.html#http2_http2_createserver_options_onrequesthandler

『Since there are no browsers known that support unencrypted HTTP/2, the use of http2.createSecureServer() is necessary when communicating with browser clients.』
日本語:暗号化してない HTTP/2 をサポートしてるブラウザはないのでブラウザのクライアントと通信するなら createSecureServer を使う必要があります

というわけでブラウザが対応してないけど サーバとして作ることはできるみたい
作れるってことは仕様というか規格はあるんでしょうね

開発用に使うなら 暗号化通信とかいらないし 自己署名の証明書使ったときの危険ですページも邪魔だから 暗号化なしの方使いたいんだけどな
ブラウザが対応してないなら 結局使えないし不便
いつも思ってるけど HTTPS 通信って全部のサイトにいらないのに すべて HTTPS 化しようとしてるのホント迷惑
Node.js でロックぽいことする
Web サーバとバックグラウンド処理を両方やってるとき 共有してる変数の状態が中途半端な状態のものを使って処理してレスポンス返すのを防ぎたい
バックグラウンド処理の途中では Web サーバのリクエストが来ても待機してバックグラウンド処理を実行してないときに Web サーバの処理をしてレスポンス返したい

共有してる変数に Promise を入れてバックグラウンド処理が始まると未解決の Promise をセット
終わったらそれを resolve
リクエストがきたときは 最初にその Promise を await すれば良い

let count = 0
let waiting = null

let lock_count = 0
let resolve = null

const lock = () => {
lock_count++
console.log("LOCK+", lock_count, count)
if(!waiting) {
waiting = new Promise(r => resolve = r)
}
}

const unlock = () => {
lock_count--
console.log("LOCK-", lock_count, count)
if(lock_count === 0) {
resolve()
waiting = null
}
}

const wait = ms => new Promise(r => setTimeout(r, ms))

// バックグラウンド処理
setInterval(async () => {
lock()
await wait(Math.random() * 5000)
count++
unlock()
}, 3000)

// Web サーバ
require("http").createServer(async (req, res) => {
await waiting
res.end(String(count))
}).listen(9123)

コレくらいにシンプルだといいけど Web サーバでリクエストを処理するときに 最初以外のバックグラウンド処理の待機以外で 途中に await が混ざると await 後はまたバックグラウンド処理を始めてる可能性あり
await が入るならリクエスト処理中はバックグラウンド処理を始めないようにバックグラウンド処理側でもリクエスト処理の await 入れたほうが良さそう
ここまで来ると複雑だし いい感じのライブラリ探してそれに任せたほうがいいかも
[...array] の挙動を変える
let a = [1, 2, 3]
let b = [4, 5, 6]

console.log([...a, ...b])
// [1, 2, 3, 4, 5, 6]
console.log(a.concat(b))
// [1, 2, 3, 4, 5, 6]

let a = [1, 2, 3]
let b = [4, 5, 6]

a[Symbol.iterator] = function*() {
for(const value of this.values()) {
yield value * 10
}
}

console.log([...a, ...b])
// [10, 20, 30, 4, 5, 6]
console.log(a.concat(b))
// [1, 2, 3, 4, 5, 6]
他のタブを閉じるが消えてたらしい
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1216629.html

78 で消えて canary 80 で復活してるとか
見覚えはあったけど使ったこと無いし消えてること気づかなかった
要らないと思うんだけど すぐ復活するほど需要あったんだ
「右側を消す」っていうのがあるし、ほしいタブを最左に持ってきてから右側消せばいいような

ヘビーユーザーになると残すタブがいっぱいで後で見そうならとりあえずおいとく
全消しなんてありえないってのが多いと思う
ライトユーザーだと最低限のタブだけにして見終わったらどんどん消していきたいという気持ちなのかな?
私の場合は調べ物の用途ごとにウィンドウ分けてるから作業終わったらウィンドウ単位で閉じてる
Python の id
オブジェクトの参照を表す数値が見える

print(id("a")) # 140576450230568
print(id("b")) # 140576471436904

a = "a"
b = "b"

print(id(a)) # 140576450230568
print(id(b)) # 140576471436904

ab1 = a + b
ab2 = a + b
ab3 = ab1

print(id(ab1)) # 140576448953400
print(id(ab2)) # 140576448953456
print(id(ab3)) # 140576448953400
print(id("1")) # 140576448952896
print(id("2")) # 140576448952952

s = "1"
t = "2"

print(id(s)) # 140576448952896
print(id(t)) # 140576448952952

st1 = s + t
st2 = s + t
st3 = st1

print(id(st1)) # 140576448953512
print(id(st2)) # 140576448953568
print(id(st3)) # 140576448953512
print(id(1)) # 10914496
print(id(2)) # 10914528

x = 1
y = 2

print(id(x)) # 10914496
print(id(y)) # 10914528

xy1 = x + y
xy2 = x + y
xy3 = xy1

print(id(xy1)) # 10914560
print(id(xy2)) # 10914560
print(id(xy3)) # 10914560
print(id(123456789)) # 139698002811888
print(id(987654321)) # 139698002809552

p = 123456789
q = 987654321

print(id(p)) # 139698002811888
print(id(q)) # 139698002809552

pq1 = p + q
pq2 = p + q
pq3 = pq1

print(id(pq1)) # 1111111110
print(id(pq2)) # 1111111110
print(id(pq3)) # 1111111110

数値は足しても同じ値は同じになってるけど 文字列は結合したときに同じじゃない