2020-04-07 昼下がりの気分転換

昼下がりは、人間、頭がぼーっとするようにできている。

最近は13時ごろに15分の昼寝をしている。寝る前にコーヒーを飲んで、起きるころにカフェインが効いて、シャキっと目が覚めるように工夫。在宅勤務のうれしいところは電気を消したり、服を着替えたり、昼寝のために環境を整えることができること。

昼寝をしても、ぼーっとしたり、なんか気分が乗らないなぁ、というときは10分間の休憩を入れて、英語の音読と筋トレをやっている。声を出したらやる気が出てくるみたいなのを何かの本で読んだんだけど、思い出せない... ただ大きい声を出すだけだと不審者なので、英語の勉強を兼ねて、英語の文章の音読をやっている。使っている教材はアルゴリズム音読というやつ。

1日10分で4技能が身につく アルゴリズム音読

1日10分で4技能が身につく アルゴリズム音読

筋トレもやる気につながるというのを何かの本で読んだのだけど、これも思い出せない... 筋トレはランニングのフォームの改善につなげるためにお尻と足の筋肉を鍛える以下のツイートのやつとワイドスクワットをやっている。

2020-04-06 ねぎま鍋と蕎麦

月に一度、ご褒美に外食で美味しいものを食べることを生きがいにしていたのだけど、新型コロナウィルスのせいでそれができなくなってしまった...
代わりに生産者を応援するのも兼ねて、週に一度、ちょっぴり高級なものを買ってなにか作ることにした。

先週の金曜は、ねぎま鍋を作った。ねぎま鍋は、江戸時代にマグロがたくさん獲れて、余って捨てられていたトロの部分を美味しく食べることができないか、という江戸庶民の知恵から生まれた。トロは今となっては高級食材だけども、脂っこいものが当時の人の舌に合わなかったり、保存が効かないという理由で捨てられるか、肥料になっていたらしい。
人間の味覚は時代と共に変わっていることを表すエピソードだなぁ...

ねぎま鍋の由来を鑑みると、もっと庶民的な(もはやマグロではない)カジキあたりで作ってみようかと思ったのだけど、そもそもの週に一度、高級なものを買って楽しもうという趣旨を貫いて、メバチマグロの赤身と本マグロの中トロのサクを買った。

作り方は簡単で、以下の通り。

  1. ネギをぶつ切りにして火で炙って焦げ目をつくる
  2. めんつゆ(ストレート)400mlに醤油 大さじ2と酒 大さじ2をいれて、中火にかける
  3. マグロを一口大に切る。脂が多い部分は火にかけると形が崩れやすいので、太めに切る
  4. つゆが沸騰してきたら、ネギとマグロ、あれば木綿豆腐をいれる
  5. ひと煮立ちさせたら、セリ、クレソンをいれる。この2つは火が通りやすいので、数十秒ぐらい火に通せばOK。火を通しすぎるとシャキシャキ感がなくなって美味しくなくなる

マグロの臭みが気になる場合は七味や山椒をかけるとよい。

ねぎま鍋の主役は実はマグロではなく、ネギだったりする。マグロの旨味が溶け込んだつゆを吸ったトロトロのネギが最高なんです。

〆にマグロと焦がしたネギの旨味が溶け込んだつゆで、蕎麦をやるのもおすすめ。
今回の〆は具が入ってないですが、適当な野菜を火で炙ったり酒煎りにして、つゆに浸して具にするとおいしいです。自分のオススメは、しめじとネギの白い部分のぶつ切り、あるいはしめじとピーマンの組み合わせ。冷蔵庫にある余った野菜で色々トライしてみるのも面白いと思います。
マグロの匂いが気になる場合は、刻んだ三つ葉を上からたっぷり載せて、三つ葉そばにするのもオススメです。

Dart あるいは Firebase Admin SDK のない言語でユーザー管理

Dart で Firebase Auth のユーザー情報を取得したり、ユーザーを削除したかったのだけど、Firebase Admin SDKDart では提供されていなくて困った。REST API の仕様も正式に公開されていない。

調べたら、Firebase Auth の認証機構は Google IdentityToolkit と統合されていて、IdentityToolkit の REST API を使うことで Firebase Admin SDK 相当の操作ができることがわかった。 IdentityToolkit のクライアントは googleapis のパッケージで提供されているので、それを利用すればOK。

ユーザー情報の取得

import 'package:googleapis/identitytoolkit/v3.dart';
import 'package:googleapis_auth/auth.dart';
import 'package:googleapis_auth/auth_io.dart';

void main() async {
    final credentials =
        ServiceAccountCredentials.fromJson("service_account.json の内容");
    final httpClient = await clientViaServiceAccount(
        credentials, ['https://www.googleapis.com/auth/identitytoolkit']);
    final identityToolkit = IdentitytoolkitApi(httpClient);
    final relyingParty = identityToolkit.relyingparty;
    final request = IdentitytoolkitRelyingpartyGetAccountInfoRequest()
      ..localId = ["UID"];
    final response = await relyingParty.getAccountInfo(request);
    print(response.users[0].name);
    print(response.users[0].email);
}

ユーザーの削除

import 'package:googleapis/identitytoolkit/v3.dart';
import 'package:googleapis_auth/auth.dart';
import 'package:googleapis_auth/auth_io.dart';

void main() async {
    final credentials = ServiceAccountCredentials.fromJson("service_account.json の内容");
    final httpClient = await clientViaServiceAccount(
        credentials, ['https://www.googleapis.com/auth/identitytoolkit']);
    final identityToolkit = IdentitytoolkitApi(httpClient);
    final relyingParty = identityToolkit.relyingparty;
    final request = IdentitytoolkitRelyingpartyDeleteAccountRequest()
      ..localId = "UID";
    await relyingParty.deleteAccount(request);
}

2020-03-30 一日の過ごし方

コロナウィルスの感染拡大で先週の金曜から再びリモート体制。

リモートワークは意識的にオン・オフを切り替えたり、心身を整える必要がある。以下の記事を参考に、自分も仕事を始める前の散歩と昼食後の仮眠をやっている。散歩は特におすすめで、外に出てしばらく太陽の光を浴びることでシャキッとする。あとは自分なりにオン・オフを切り替える儀式のようなものが必要だと考えていて、自分は服をちゃんと着替えるというのをそれにしている(他にもハチマキを付けるとか色々ありそう)。

note.com

作業はずっと集中し続けると後でくる反動がキツいので、40分集中・10分休憩のルーティンをまわしている。40分の集中にちょうどいいのが、チャイコフスキー交響曲で、はじめはゆっくりのテンポで慣らして、終楽章のアップテンポで追い込める良さがある。4番、5番、6番をリピートして聞いている。だんだん飽きてきたので、レパートリーを増やしたい。

タイプセーフに Future.wait したい

最近、お仕事で Dart を書いている。Dart では非同期処理を JavaScript の Promise に似た Future という概念で扱うことができて、複数の非同期処理を扱うには、JavaScript の Promise.all と同等な Future.wait という API が用意されている。

Future.wait の引数の配列の Future の型が同じ場合は問題ないが、異なる場合は共通の基底クラスにキャストされて型情報が失われてしまう(TypeScript の Promise.all でも同じはず)。

例えば、以下のようなコードで、callFooFuture<Foo>, callBarFuture<Bar>を返すとすると、results の推論された型は List<Object> になる(FooBarが共通の親を持っている場合はObjectではなく、その親になる)。

final results = await Future.wait([callFoo(), callBar()]);

こんなかんじでダウンキャストすればいいんだけど、Future オブジェクトの数が増えてくるとうっかり間違えて実行時エラーを起こしてしまいそう。

final foo = results[0] as Foo;
final bar = results[1] as Bar;

いまいまは、await しているスコープであらかじめ変数を宣言しておいて、各 Future オブジェクトの then で代入するのがいいかなぁ、と思っている。Future.all を await した結果は使わず、ただ待つだけ。

Foo foo;
Bar bar;

await Future.wait([
  callFoo().then((f) { foo = f; }),
  callBar().then((b) { bar = b; }),
]);

2020-03-22 胃腸炎から復帰

7日の夜に胃腸炎になって、しばらく省エネモードで生きていた。この日は久しぶりに身体の調子がいいかんじだった。
腸炎、前日の昼に食べたカキフライがよくなかったのか(少し生っぽいというか、磯臭いかんじだった)、夜に食べたあぶりレバー・センマイ刺しがよくなかったのか、それとも当日の昼に食べた焼き肉がよくなかったのか(無意識でトングで取り皿にお肉を運んでいた気がする。箸で取りましょう...)。去年の今頃も、生焼けのとんかつを食べて胃腸炎になっていた。年を重ねるごとに無理をすると(胃腸炎になる前から、体調がいまいちだった)一気に体調を悪くする確率が高くなっている気がする。意識的に養生する必要がある。

前々日にランニングを再開したのだけど、しばらく走っていなかったから足の筋力が落ちて、この日も筋肉痛が残っていた。ランニングはお休み

この日も恒例の朝活で外苑前へ。ここ数回はすぐに定員が埋まる。多分、コロナで朝活も自粛されていて、そこから人が流れているのかな。もくもく Elasticsearch の素振りをしていた。

終わった後は髪を切りに渋谷に行ったのだけど、4人待ちで1時間近く待つ必要があったので諦める。CONROWでグリーンカレーガイヤーンを食べて、本屋に少し寄って、帰宅。
家の最寄り駅に着いたところで、この前、ランニング中によさそうな美容院を見かけたことを思い出し、向かう。入ったら、すぐに切ってもらえた。担当してくれた人がやたら会話テクの高い人で、普段の仕事の話、作っているアプリの話、お子さんがハマっているYouTuberの話など。話している間にあっという間に終わった。前のところより、少しだけ高いけど、カットの手際がよくて気持ちいいし、仕上がりもよかったので、次もここにしようかな、という気持ち。渋谷にいく理由がまたひとつ減ってしまった。

家に帰って、3月場所の千秋楽を見る。朝乃山が貴景勝に勝って、大関昇進をほぼ確実にしたのがうれしかった。今場所はコロナウィルスの影響で無観客の異例の場所だけれども、千秋楽の取り組みが終わった後の式事?も普段と違って新鮮だった。普段は中継されない出世力士手打ち式や神送りの儀式が見れたり。相撲の神事としての面が強く出た場所だったと思う。

2020-02-29 もつ焼きばん

起きて、本を読んだり、コードを書いたり。BLUE GIANT SUPREME の最新刊が配信されていたので読む。今回も非常に良かった。思えば遠くに来たもんだ、的なエピソードで読者の心を揺さぶりにくる。

BLUE GIANT SUPREME (10) (ビッグコミックススペシャル)

BLUE GIANT SUPREME (10) (ビッグコミックススペシャル)

  • 作者:石塚 真一
  • 発売日: 2020/02/28
  • メディア: コミック

昼前にリングフィットを17分、フィットボクシングを35分。さらにジョグ。流石にワークアウトを3種類やるとちょっときつい。トータル一時間程度に済むようにバランスよくやっていく。

夕方に祐天寺のもつ焼きばんへ。定期的に飲む同じ北陸出身のSさんとSさんの同僚のMさんと飲む。もつ焼きは当然おいしいのだけど、ばんサラダもおいしい。カニカマが入ったサラダ、今度家でも作ってみようかな。
その後、いくつかお店を変えて、この日はトータルで4杯ぐらい飲んだ。そんなに酔ったつもりはなかったんだけど、相性が悪い酒があったのか翌日若干頭痛がした。