ニート日報2 2025-02-19

今日やろうと思っていたこと

  • ✅ 走る
  • ✅ 確定申告(所得税)を申告まで終わらせる
    • ✅ 消費税申告も無の申告をする
  • 掃除とアルコール消毒を進める
  • ちまちま書いてるコードを進める

今日のまとめ

  • 確定申告は所得税も消費税も完了
    • 外国税額控除完全に理解した
      • 限度額の計算に使う総所得・所得税額を分離課税分だけだと勘違いしていた(実際にはすべての所得の合計)
      • さらに定額減税と外国税額控除のコンボで複雑なことになっていた
      • システムによる計算と手計算が完全一致したときは気持ち良すぎた
    • 消費税申告は無駄にインボイス登録しちゃってたから必須になってしまい、0円で申告した
    • 還付振込はよ
  • 走るのは順調に量を増やし中
    • 以前やってたところまで戻すのが直近の目標
  • 飯は昼夜自炊
  • 確定申告が終わった開放感で満たされて他がぜんぜんできてない

明日やりたいこと

  • 走る
  • 家の設備修理
  • 送別会
  • 掃除とアルコール消毒を進める
  • ちまちま書いてるコードを進める

ニート日報2 2025-02-18

今日やろうと思っていたこと

  • ❌ 掃除とアルコール消毒を進める
  • ✅ 確定申告をほぼ終わらせる(一晩寝かせて水曜に申告まで完了させたい)
  • ❌ ちまちま書いてるコードを進める
  • ✅ 社のイベントに顔を出す

今日のまとめ

  • 確定申告は終わってないけどかなり進捗中
    • 今年は確定申告書等作成コーナーでやってる
    • 外国税額控除のシステムによる計算結果と自分の理解による手計算の値が一致しなくて、理解するために時間を要しまくってる(システム側が合ってるはず)
    • ChatGPT にソースとなる URL を提示してもらいつつ相談するのが便利
      • 正しいことを言っているのか、こっちの責任で判断することができる
  • 確定申告で時間を使って他のことができてない
  • 社のイベントには顔を出してきた
    • 退職後に初めて物理で会って挨拶をしたw
  • 昼飯に初見の二郎系ラーメン屋へ行った
    • 麺を減らして注文できることを知らず、フルサイズの二郎系を食べることに……
    • おそらく閉店時間をかなり過ぎた状態でなんとか食べきった
    • 帰り際に店員さんに聞いたら、麺の量は調整できたらしい
  • 食後に100分ちょい散歩した
    • 約束された圧倒的な血糖値スパイクへの対策
    • 前に住んでいた家の周辺を散策した

明日やりたいこと

  • 走る
  • 確定申告を申告まで終わらせる
    • 消費税申告も無の申告をする
  • 掃除とアルコール消毒を進める
  • ちまちま書いてるコードを進める

ニート日報2 2025-02-17

今日やろうと思っていたこと

  • ✅ 走る時間を少しだけでも増やす
  • ✅ 読みかけの本を読み切る
  • ❌ 掃除とアルコール消毒を進める
  • ✅ 整形外科へ行く
  • ✅ 送別会的なやつ
  • ✅ モンハン

今日のまとめ

  • 走るのは昨日よりは時間を伸ばした
    • ちょっと筋肉痛
  • Tidy First? は読み終わった
    • 今後の動き方に影響は与えられたと思う
  • 掃除は失敗
  • 整形外科は行った
    • やっぱ混みすぎて地獄
    • わずかに腰がヘルニアの気配があるけどまだ様子見で問題ないレベルだった
    • 温めろと言われた
  • 送別会というか特定チームの同窓会的なやつ
    • 懐かしみ
    • やっぱ業界狭いなーと
    • 人生
  • モンハンはちょいちょいやった
    • これまでのベータの合計より今日の方が多かった
    • 今までタイミングが合わず体感2クエくらいしかできてなかった

明日やりたいこと

  • (足に筋肉痛出てきてるので走るのは休憩)
  • 掃除とアルコール消毒を進める
  • 確定申告をほぼ終わらせる(一晩寝かせて水曜に申告まで完了させたい)
  • ちまちま書いてるコードを進める
  • 社のイベントに顔を出す

ニート日報2 2025-02-16

今日やろうと思っていたこと

  • ✅ 走るのを超低負荷から再開する
  • ✅ 読みかけの本を進める
  • ✅ 昼夜自炊する
  • ✅ 家のいろんな場所をアルコール消毒する
  • ✅ 家の掃除をする
  • ✅ 洗濯機の修理をする(業者が来る)
  • ✅ モンハンのベータテストをする

今日のまとめ

  • 走るやつは、かなり低負荷で15分だけ走った
    • この休みのうちに11月末水準の時速6キロメートルで30分走って心拍数X以下を保つ水準までは体力を戻したい
  • 読みかけだった本(Tidy First?)はちょっと読み進めてあと少しで終わりそう
  • 飯は味噌キムチ鍋を作った
    • 3食分できてしまったので明日の昼飯まで戦える
  • 掃除とアルコール消毒は部分的に実施
    • せっかく休みが続くので毎日少しずつきれいにしていく(という言い訳で今日少しだけで妥協)
  • 洗濯機は公式のサポートが来て直してくれた
    • ベルトと基盤の交換で4万
    • 野良業者だと7.5万とかの見積もりだったからかなり安い
  • あとはモンハンをやって寝る

明日やりたいこと

  • 走る時間を少しだけでも増やす
  • 読みかけの本を読み切る
  • 掃除とアルコール消毒を進める
  • 整形外科へ行く
  • 送別会的なやつ
  • モンハン

転職します a.k.a. ニート日報2 2025-02-15

ニート日報とは

社会人2社目の最終出社を終えて土日を含む30日間の有給消化期間に入りました。 前回の転職の時も毎日ブログを書いていたので今回も書いていきます。 何も書くネタがない虚無な日を生み出さないための防止策でもあります。

会社の振り返り

今回の会社は8年半くらい在籍して、自分のキャリア(2社)の中では圧倒的に最長になりました。基本的にずっと同じサービスに関わっており、気づいたらなぜか巨大リポジトリのヌシ的なポジションになってしまっていました。力不足感は否めないなと思いつつ、できることをいろいろ頑張っていました。

「いろいろ」に文字通りいろいろ詰まっていていろいろな人と仕事を通じて関わりを持たせてもらいました。

寄せ書きというものに縁のない人生を送ってきましたが嬉しいことに今回はオンラインサービスを使った寄せ書きをいただきました。ありがとうございました。この寄せ書きはオンラインでは1年間しかアクセスができず、それを物理化して保存できるようにする部分が課金ポイントになっていて面白いと感じました。地味に高いですがせっかくなので物理化してみようかなと思っています。

一緒に仕事をした若者たちの「業務でのソフトウェアエンジニア観」のようなものに少しでも影響を与えていたことを寄せ書きから知り非常に感慨深くなりました。入社時点では自分が若者枠だったはずなのに世の中、巡っていくのだなとしみじみです。

仕事で関わった人に挨拶しきれなかったのは申し訳無さがあります。最後の週にゆったり挨拶回りをする予定だったのですがコロナ感染後のアレで最終日まで家に籠もることになってしまったのが悔やまれます。

実は2024年頭の時点で「住宅ローンを組んでマンションを買い、住み始めたら退職してフリーランスになる」方針で動いていたのですが、なんやかんやあってマンションを買うのは延期になり、フリーランスにはならず会社に所属する方針に変わりました。相変わらず勢いで人生を動かしている感が強いですw

次の会社

フリーランスではなく会社に所属する方針になったので転職しなくても良い雰囲気もありますが、辞める前提でいろいろ動いており、すでに気持ちが切り替わっていました。前々から密かに気になっていた会社が1社あり、まずはそこを受けてみたらありがたいことに選考を通過したためそこへ行くことにしました。

基本方針として、現在所属している会社は公開されたネット上では積極的には公開しないスタイルでやっています。今までの所属は公開されたネット上の情報から簡単にわかりますがw 次はたぶんプライベートの発表資料にも載せない程度の秘匿感でやっていきます。

今回が人生最後の転職になれば良いなーと今のところ考えています。ちなみに入社時点のお賃金は今とほぼ同じです。

世の中、流れというものが存在する?

会社とはまったく関係ないのですが、退職することを社内に公表した今年1月上旬から最終出社を迎える2月中旬までの間に驚くほどいろいろな問題が連続して発生しました。

  • 親知らず抜歯(下真横完全埋没)で大ダウンして4日寝て過ごす
  • 身内の不幸。お通夜葬式はなんとか参加(かなり高齢。年末に顔を見に行くことはできていた)
  • 抜歯の抜糸後、おそらくクラムチャウダーのアサリによって感染性胃腸炎になり4日寝て過ごす(最大39.7度を観測してハードだった)
  • 胃腸炎でダウンしている間に口内環境が終わっていて抜歯跡地がすこし腫れてきたためまた歯医者へ
  • 免許証をコンビニのコピー機に忘れる(コンビニで保管してくれていて翌朝回収できた。日本の治安最高)
  • (ここで次の会社のための健康診断を受けた。この週だけ奇跡的に無事)
  • 鼻と喉が痛くなり細菌系に若干心当たりがあり、そうだと怖かったので病院へ行ったらコロナであることが発覚(コロナは治ったけど現時点でも咳だけ残ってる)
  • 洗濯機が壊れる(1年以上怪しい兆候があったのを無視していた)

お祓いとか信じてないタイプだけどお祓い行ったほうが良いのか考えてしまいます。

今日のまとめ

  • ついったで見かけたさくらの AppRun(beta) を動かしてみた
  • プライベートのあれこれを進めるために直近の動き方を決めた
  • モンハンのベータテストをちょっとやった
  • 転職記事的な内容を書いた

明日やりたいこと

  • 走るのを超低負荷から再開する
  • 読みかけの本を進める
  • 昼夜自炊する
  • 家のいろんな場所をアルコール消毒する
  • 家の掃除をする
  • 洗濯機の修理をする(業者が来る)
  • モンハンのベータテストをする

packer.nvim から lazy.nvim に移行した後に nvim-treesitter が無限にインストールし続ける件

問題はタイトルの通りです。 ensure_installed を指定していると起動時にインストールが実行されるため、何度インストールが実行されても Neovim を再起動する度にまたインストールが実行されてしまう症状です。

原因

Neovim 内で &runtimepath を見てみると、 ~/.local/share/nvim/site が含まれています。 この中には packer とそれが管理するプラグインも格納されている ~/.local/share/nvim/site/pack/packer も含まれます。 これ以上は追っていないですが、おそらく nvim-treesitter がこのディレクトリ以下を見てインストールされているかどうかの判定を行なっているようでした。

対処方法

packer を完全に削除することで治ります。

1
rm -rf .local/share/nvim/site/pack

Neovide を WSL で使う (Neovim は mise で管理する場合)

Neovide を Windows で WSL 内の Neovim で使うときのメモです。Neovim を mise で管理している人向けです。

  • Neovide は Windows 向けをインストールする
  • Windows 側に Neovide の設定ファイルを用意する
  • WSL 内からは neovide.exe で起動する

ちょっと詳しく

Neovim を mise で管理している場合、Neovide から nvim が見えなくて起動時にエラーになってしまいます。 これを解決するために nvim のパスを設定ファイルに書いておきます。

Windows 向けの設定ファイルは %APPDATA%\neovide\config.toml に置きます。

1
2
neovim-bin = "$HOME/.local/share/mise/shims/nvim"
wsl = true

これで Neovide から nvim が見えるようになります。

自分の場合は WSL でしか使わないので wsl オプションもついでに有効化しておきます。 これによって neovide.exe --wsl ではなく neovide.exe だけで起動できるようになります。

Rust の shaku と mockall を組み合わせて使う例

shaku は DI ライブラリです。 日本語での情報が少なかったの詳細めに書いていきます。

mockall はモックライブラリです。 こちらは日本語での情報もすぐに見つかったので詳細は触れていないです。

まず shaku を使う

以降のコードスニペットにおいて use は省略しています。末尾にあるおまけの全体コードでは省略していないので気になる方はそちらを参照してください。 shaku の使い方については公式のガイドを見た方が当然詳しいですが、ここでも一通り使い方を書きます。

shaku を使うの最小の例

ここでは Hoge という trait で例示します。 trait を shaku で扱えるようにするには Interface の subtrait にします。

1
2
3
pub trait Hoge: Interface {
fn hoge(&self) -> String;
}

trait 側の準備はこれで完了です。

次に Hoge を実装した struct HogeImpl を用意します。 中身はてきとーです。 この HogeImpl の attribute に shaku(interface = Hoge) を指定することで、HogeImplHoge の解決に利用されることを示します。 そして derive(Component) することでボイラープレートを自動生成します。 Component の代わりに Provider を使うこともできますがそれは後述します。

1
2
3
4
5
6
7
8
9
#[derive(Component)]
#[shaku(interface = Hoge)]
pub struct HogeImpl;

impl Hoge for HogeImpl {
fn hoge(&self) -> String {
"hoge".to_string()
}
}

次に macro module! を使って依存解決に使う struct を作ります。

MyModule は自由に名前をつける部分です。 componentsproviders に、依存解決にどの struct を使うのかを指定します。Component である HogeImplcomponents に指定することで Hoge が解決できるようになります。

1
2
3
4
5
6
module! {
MyModule {
components = [HogeImpl],
providers = [],
}
}

これで使う準備は完了です。 テスト内で使ってみると以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[cfg(test)]
mod tests {
use shaku::HasComponent;

use super::*;

#[test]
fn test_hoge() {
let module = MyModule::builder().build();
let hoge: &dyn Hoge = module.resolve_ref();

let result = hoge.hoge();
assert_eq!(result, "hoge");
}
}

Component Hoge を依存に持つ例

上の例だと Hoge として HogeImpl を作っているだけなので何も嬉しくないです。 次に Hoge に依存する別のものを作ってみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pub trait Fuga: Interface {
fn fuga(&self) -> String;
}

#[derive(Provider)]
#[shaku(interface = Fuga)]
pub struct FugaImpl {
#[shaku(inject)]
hoge: Arc<dyn Hoge>,
}

impl Fuga for FugaImpl {
fn fuga(&self) -> String {
format!("fuga: {}", self.hoge.hoge())
}
}

今回は FugaImplComponent ではなく Provider としてみました。 2つの違いはざっくり以下です。

  • Component は MyModule のインスタンス内において1つのインスタンスを共有する
  • Provider は module.provide() の呼び出しの度に(内部での依存解決の度にも)新しくインスタンスが作られる

Component に依存する場合は Arc<dyn Trait> なフィールドを用意したうえで、その attribute に shaku(inject) を指定します。

module! 部分は以下のようになります。Provider の場合は providers に指定します。

1
2
3
4
5
6
module! {
MyModule {
components = [HogeImpl],
providers = [FugaImpl],
}
}

テスト内で使ってみると以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[cfg(test)]
mod tests {
use shaku::{HasProvider};

use super::*;

#[test]
fn test_fuga() {
let module = MyModule::builder().build();
let fuga: Box<dyn Fuga> = module.provide().unwrap();

let result = fuga.fuga();
assert_eq!(result, "fuga: hoge");
}
}

Provider の場合は module.provide() でインスタンスを作って Box<dyn Trait> で受け取ります。

ここでは unwrap していますが derive(Provider) で生成した分についてはエラーにはなり得ないです。
Provider を手動で実装して provide 内でエラーになり得るコードを書いた場合はエラーの可能性があります。

Provider Fuga を依存に持つ例

Component だけでなく Provider への依存も持つことができます。 上で作った Fuga を依存に持つものを作ってみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pub trait Piyo: Interface {
fn piyo(&self) -> String;
}

#[derive(Provider)]
#[shaku(interface = Piyo)]
pub struct PiyoImpl {
#[shaku(provide)]
fuga: Box<dyn Fuga>,
}

impl Piyo for PiyoImpl {
fn piyo(&self) -> String {
format!("piyo: {}", self.fuga.fuga())
}
}

Provider に依存する場合は Arc ではなく Box<dyn Trait> をフィールドに持たせて attribute shaku(provide) を付与します。 ちなみにProvider から Component に依存はできますが、逆の Component から Provider への依存はできません。

module! の定義にも追加したら利用できるようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module! {
MyModule {
components = [HogeImpl],
providers = [FugaImpl, PiyoImpl],
}
}

#[cfg(test)]
mod tests {
use shaku::HasProvider;

use super::*;

#[test]
fn test_piyo() {
let module = MyModule::builder().build();
let piyo: Box<dyn Piyo> = module.provide().unwrap();

let result = piyo.piyo();
assert_eq!(result, "piyo: fuga: hoge");
}
}

特定の実装を置き換える

上で作ったうち、他から依存されている HogeFuga の実装をテストにおいて置き換えてみます。 今回は mockall を使うので trait の attribute に cfg_attr(test, automock) を指定しておきます。 これによって MockHogeMockFuga が自動で作られます。

1
2
3
4
5
#[cfg_attr(test, automock)]
pub trait Hoge: Interface { ... }

#[cfg_attr(test, automock)]
pub trait Fuga: Interface { ... }

Component の実装を置き換える

テスト内で MockHoge を作って hoge が呼び出されたときに本来の実装とは別の値を返すようにしてみます。

1
2
3
4
let mut mock_hoge = MockHoge::new();
mock_hoge
.expect_hoge()
.returning(|| "mocked_hoge".to_string());

module builder において with_component_override を使って Hoge の上書きをする設定を行ないます。

1
2
3
let module = MyModule::builder()
.with_component_override::<dyn Hoge>(Box::new(mock_hoge))
.build();

この module を使って依存解決を行なうとHoge として mock_hoge が使われるようになります。 実行結果を見ると mock_hoge が使われていることがわかります。

1
2
3
let fuga: Box<dyn Fuga> = module.provide().unwrap();
let result = fuga.fuga();
assert_eq!(result, "fuga: mocked_hoge");

Provider の実装を置き換える

Provider を置き換えるには module builder の with_provider_override を使います。 これの引数は Fn になっているので、クロージャ外で mock_fuga を作って move で渡しても所有権の問題(Fn は複数回呼ばれうるので返り値にするものが Clone できないと外から渡せない)でコンパイルが通りません。 なのでクロージャ内で作っています。

1
2
3
4
5
6
7
8
9
let module = MyModule::builder()
.with_provider_override::<dyn Fuga>(Box::new(|_| {
let mut mock_fuga = MockFuga::new();
mock_fuga
.expect_fuga()
.returning(|| "mocked_fuga".to_string());
Ok(Box::new(mock_fuga))
}))
.build();

こちらのパターンでも別の実装に置き換えることができました。

1
2
3
let piyo: Box<dyn Piyo> = module.provide().unwrap();
let result = piyo.piyo();
assert_eq!(result, "piyo: mocked_fuga");

まとめというか感想

  • shaku を使って DI まわりのボイラープレートを最小限にできた
  • shaku 自体は非常に小さいライブラリなのでもしも問題があっても自分で対処できそう
  • shaku と mockall の組み合わせで特に問題になることもなく普通に使えた

おまけ

最終形のコードの全体は以下です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use std::sync::Arc;

use shaku::{module, Component, Interface, Provider};

#[cfg(test)]
use mockall::{automock, predicate::*};

#[cfg_attr(test, automock)]
pub trait Hoge: Interface {
fn hoge(&self) -> String;
}

#[derive(Component)]
#[shaku(interface = Hoge)]
pub struct HogeImpl;

impl Hoge for HogeImpl {
fn hoge(&self) -> String {
"hoge".to_string()
}
}

#[cfg_attr(test, automock)]
pub trait Fuga: Interface {
fn fuga(&self) -> String;
}

#[derive(Provider)]
#[shaku(interface = Fuga)]
pub struct FugaImpl {
#[shaku(inject)]
hoge: Arc<dyn Hoge>,
}

impl Fuga for FugaImpl {
fn fuga(&self) -> String {
format!("fuga: {}", self.hoge.hoge())
}
}

#[cfg_attr(test, automock)]
pub trait Piyo: Interface {
fn piyo(&self) -> String;
}

#[derive(Provider)]
#[shaku(interface = Piyo)]
pub struct PiyoImpl {
#[shaku(provide)]
fuga: Box<dyn Fuga>,
}

impl Piyo for PiyoImpl {
fn piyo(&self) -> String {
format!("piyo: {}", self.fuga.fuga())
}
}

module! {
MyModule {
components = [HogeImpl],
providers = [FugaImpl, PiyoImpl],
}
}

#[cfg(test)]
mod tests {
use shaku::{HasComponent, HasProvider};

use super::*;

#[test]
fn test_hoge() {
let module = MyModule::builder().build();
let hoge: &dyn Hoge = module.resolve_ref();

let result = hoge.hoge();
assert_eq!(result, "hoge");
}

#[test]
fn test_fuga() {
let module = MyModule::builder().build();
let fuga: Box<dyn Fuga> = module.provide().unwrap();

let result = fuga.fuga();
assert_eq!(result, "fuga: hoge");
}

#[test]
fn test_fuga_mock() {
let mut mock_hoge = MockHoge::new();
mock_hoge
.expect_hoge()
.returning(|| "mocked_hoge".to_string());

let module = MyModule::builder()
.with_component_override::<dyn Hoge>(Box::new(mock_hoge))
.build();
let fuga: Box<dyn Fuga> = module.provide().unwrap();

let result = fuga.fuga();
assert_eq!(result, "fuga: mocked_hoge");
}

#[test]
fn test_piyo() {
let module = MyModule::builder().build();
let piyo: Box<dyn Piyo> = module.provide().unwrap();

let result = piyo.piyo();
assert_eq!(result, "piyo: fuga: hoge");
}

#[test]
fn test_piyo_mock() {
let module = MyModule::builder()
.with_provider_override::<dyn Fuga>(Box::new(|_| {
let mut mock_fuga = MockFuga::new();
mock_fuga
.expect_fuga()
.returning(|| "mocked_fuga".to_string());
Ok(Box::new(mock_fuga))
}))
.build();
let piyo: Box<dyn Piyo> = module.provide().unwrap();

let result = piyo.piyo();
assert_eq!(result, "piyo: mocked_fuga");
}
}

YAPC::Hiroshima 2024 に参加してきました

久し振りに YAPC へ行ってきました。 広島へは行ったことがなかったので旅行も兼ねていました。 ここ数ヶ月、半休職的な感じで勤務数を減らして体調を整え中だったため体力具合の確認も兼ねたりしていました。

広島でコロナを貰ってしまい大ダウンしていたので軽くの感想です。

YAPC 編

前夜祭、本編、YAYAPC と一通り参加してきました。 以下、いくつか感想をつらつら書いていきます。

songmu さんのやつ

個人的にインパクトが強かったのは songmu さんが YAYAPC で話していたやつです。こういう話は大人数がいるところではなかなかしないから貴重でした。内容は非公開なのでぼやかしつつ、自分の感想としては↓でした。 あまり効果がない的な流れでしたがあるところではあることを表明しておきます。もっと夢もあります。

関数型プログラミングと型システムのメンタルモデル

naoya さんの関数型の話が良いなーと思っていたら、ちょうど似たようなタイミングで Elixir の記事がすこし注目されていたり、Elixir 実践入門の発売が迫っていたりで Elixir をやってみることにしました。発表では Elixir だったわけではないですが Elixir は前から気になっていた言語だったので良いきっかけになりました。

Elixir 実践入門が発売される直前に先にすごいE本で Erlang もやり始めてみました。コロナでダウンしている間に横になって読んでいた程度なのでまだがっつりはできていないです。 新しい言語をやるのは久し振りでした。以前は頻繁にいろいろ本を写経してたのが最近はあまりできていませんでした。そういう意欲が回復したのは大きな収穫だったかもしれません。

My Favorite Protocol: Idempotency-Key Header

以前「こういうのが必要だよなー」と自分でも考えていたものが、やはり多くの人が必要としていたことが知れて安心?しました。規格化を目指して話が進んでいるとのことなので必要な場面に遭遇したら使っていきます。

キーノート

生のとほほさんを見られてとにかく感動でした!!

アウトプットは自然とやっているというのがやっぱ強いなと。伝説的な人は大抵「好きこそ物の上手なれ」勢だなーと思いました。

トーク後にその辺で質問にあっているのを聞いていたら Vimmer であることがわかって嬉しかったです。当日は使用エディタの質問が出たときは Emacs ばかりという流れがありました。

旅行編

前夜祭の日中は尾道へ行ってきました。

↓は新幹線からの乗り換えですこしだけ乗った特殊な電車です。 エトセトラという観光列車で、広島駅と尾道駅の間を走っています。 今回はほんのすこしだけ乗った形でしたが、いつかまた広島へ行ったらフルで乗ってみたいなと思っています。

↓は尾道で食べた尾道ラーメンです。ゴロゴロした背脂が特徴らしいです。

↓は尾道の千光寺の一部の眺めです。 山に沿って作られていて全体的にすごい構造をしていました。

↓は千光寺周辺を下っているときの通路です。 めちゃくちゃ入り組んだ構造になっているのがめちゃ好みでした。

前夜祭前には原爆ドームへ行きつつ↓の動画の場所も見てきました。

↓は YAYAPC の翌日、東京へ帰る前に宮島(厳島)へ行ってきたやつです。厳島神社の鳥居です。だいぶ潮が引いていたのですぐ近くまで行けました。

コロナ編

帰りの新幹線に乗っている途中から喉が怪しく痛みだし、翌日の夕方から強烈に発熱してコロナで確定しました。

1月の頭に XBB.1.5 のワクチンを接種したばかりでもダメでした。今流行しているのは JN.1 という株のようです。

抗ウイルス薬はせっかくなので処方してもらいました(劇的な効果があるわけではなく治るのがすこし早くなる程度という説明はされつつ)。去年までは無料だったけど今は有料で3割負担の人は9000円くらいでした。 カプセルが大きく1回4個(1日2回)飲むのが辛かったです。結局長引いてしまったし処方してもらわなくて良かったな……という感想です。

この記事を書いている3月2日現在ではコロナの症状は回復しています。 ただし空咳がけっこう残っています。これは普通の風邪をひいたときも咳だけ長びくので同様なのかなと思っています。気管支弱め人材です。 発熱前症状の喉の痛みとは別な感じで喉の違和感が残ってもいます。たまに急に喉がイガイガするようにもなっています。

自分が罹患した感想としては「ただの風邪では断じてない」というものでした。

その他

新幹線や長時間の電車での移動中、ホテルで横になって休んでいるときには、買ってから積んでいたシレン6をやっていました。 広島から帰ってくる前になんとかストーリークリアまで漕ぎ着けました。 最近はちまちまクリア後ダンジョンをクリアしていき神髄に向けて心の準備を進めています。

Ubuntu 22.04 で Sorbet をビルドする

Ubuntu 22.04 の環境で Sorbet のビルドをしたらエラーが発生しました。 単純な問題ですが一応書き残しておきます。

README にあるように ./bazel build //main:sorbet --config=dbg を実行したら以下のエラーが発生しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ./bazel build //main:sorbet --config=dbg
WARNING: Download from https://mirror.bazel.build/www.colm.net/files/ragel/ragel-6.10.tar.gz failed: class java.io.FileNotFoundException GET returned 404 Not Found
WARNING: Download from https://mirror.bazel.build/ftp.gnu.org/gnu/m4/m4-1.4.18.tar.xz failed: class java.io.FileNotFoundException GET returned 404 Not Found
WARNING: Download from https://mirror.bazel.build/github.com/jmillikin/rules_m4/releases/download/v0.1/m4-gnulib-788db09a9f88abbef73c97e8d7291c40455336d8.tar.xz failed: class java.io.FileNotFoundException GET returned 404 Not Found
WARNING: Download from https://mirror.bazel.build/ftp.gnu.org/gnu/bison/bison-3.3.2.tar.xz failed: class java.io.FileNotFoundException GET returned 404 Not Found
WARNING: Download from https://mirror.bazel.build/github.com/jmillikin/rules_bison/releases/download/v0.1/bison-gnulib-788db09a9f88abbef73c97e8d7291c40455336d8.tar.xz failed: class java.io.FileNotFoundException GET returned 404 Not Found
INFO: Analyzed target //main:sorbet (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /home/mihyaeru/.cache/bazel/_bazel_mihyaeru/a74a2d0f7000d949282952fb8eb1689b/external/com_google_absl/absl/strings/BUILD.bazel:500:11: Compiling absl/strings/internal/cordz_functions.cc [for host] failed: (Exit 127): clang failed: error executing command /home/mihyaeru/.cache/bazel/_bazel_mihyaeru/a74a2d0f7000d949282952fb8eb1689b/external/llvm_toolchain_12_0_0/bin/clang -U_FORTIFY_SOURCE -fstack-protector -fno-omit-frame-pointer -fcolor-diagnostics ... (remaining 71 arguments skipped)
/home/mihyaeru/.cache/bazel/_bazel_mihyaeru/a74a2d0f7000d949282952fb8eb1689b/external/llvm_toolchain_12_0_0/bin/clang: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
ERROR: /home/mihyaeru/ghq/github.com/mihyaeru21/sorbet/common/concurrency/BUILD:1:11: Compiling common/concurrency/WorkerPoolImpl.cc [for host] failed: (Exit 127): clang failed: error executing command /home/mihyaeru/.cache/bazel/_bazel_mihyaeru/a74a2d0f7000d949282952fb8eb1689b/external/llvm_toolchain_12_0_0/bin/clang -U_FORTIFY_SOURCE -fstack-protector -fno-omit-frame-pointer -fcolor-diagnostics ... (remaining 54 arguments skipped)
/home/mihyaeru/.cache/bazel/_bazel_mihyaeru/a74a2d0f7000d949282952fb8eb1689b/external/llvm_toolchain_12_0_0/bin/clang: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
Target //main:sorbet failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.243s, Critical Path: 0.03s
INFO: 24 processes: 24 internal.
FAILED: Build did NOT complete successfully

libtinfo.so.5 が入っていないようです。 以下で入れてあげたら通るようになりました。

1
sudo apt install libtinfo5