oinume journal

Scratchpad of what I learned

2024年の振り返りと2025年

年末年始はハワイに行っていたので全く正月感がない感じで過ごしてしまった。1年の振り返りをしたり新年の抱負を書いたりしてもどうせ達成できないし、徒然なるままに生きたい人間なのだけれども、暇なので雑に振り返りと今年への意気込みをアウトプットしておく。

ライブ

2024年は合計9本のライブに行った。ハイライトは5年ぶりにサマソニに行ってManeskinが好きになったこと。あとはThe Bonez x Dragon AshのStraigh Upが、久しぶりにライブで酸欠になるぐらい激しくて久しぶりにライブで死を感じた。ずっとミクスチャーをやっている2つのバンドが対バンするとこんなにエネルギーが湧き出てくるのかというぐらいの熱気だった。12/30の追加公演ではPABLOも参戦してPTPの曲もやったようで本当に本当に行きたかった...!

あと12月にKORNのライブがオーストラリアであって行こうかどうかとても悩んだけど金銭的な理由で断念した。来年こそは日本に来てくれないかなと祈っている。

(以下は今年に参戦したライブとフェスの一覧)

  • 1/21: マサラーフェース2024
  • 3/17: PUNK SPRING 2024
  • 3/31: Dragon Ash x SHANK
  • 4/6: The Ravens
  • 7/18: TMC at CLUB CITTA
  • 8/7: SUMMER SONIC
  • 11/10: The BONEZ x Dragon Ash Straight Up Tour
  • 11/30: ビクターロック祭り2024
  • 12/8: REDLINE ALL THE FINAL

仕事

特筆することはないけど、生成AIのおかげでコードを書くモチベーションが激減したので、自分で手を動かすような機会が減った。つまりMTGと目の前の課題をひたすらやっつけることをしている。「BackendなんてHasura使えばいいんでないの?」と思っている人間なので、Backendの開発に楽しみが見い出せなくなっている。

事業ドメイン的には楽しい領域なので、ビジネス的に成長していればそれでよし。

2025年に向けて

今年は趣味プロダクトで作りたいアプリがあるので、なんとしても今年中に完成してリリースしたい。ライブは10回は行きたいけど行けるかなぁ。2024年は勉強会にほとんど参加せず技術的なことに興味を失いつつあるので、今年はもう少し参加したい。サマソニは観たいバンドがなくても行くべきだと昨年痛感したので、今年も行きたい。

そんな感じで今年もゆるふわに生きます。

2024年に買ってよかったもの

あまりものを買わない主義なのだけど、ささやかながら買ってよかったものを。(Amazonのリンクはアフィリエイトが入ってる)

[ニューバランス] インソール サポーティブリバウンドインソール

1年以上履いていたニューバランスのスニーカーのインソールがボロボロになったのでこれに入れ替えてみた。そしたらなんとびっくり、クッション効果が凄くて歩くのが大変快適になりQoLが爆上がりした。2000円弱の投資でここまで快適になるのならとてもコスパ良いと思う。なんだかんだでスニーカーは毎日履くものだし。とにかく快適すぎるので他のニューバランスのスニーカーも全部このインソールに替えた。デフォルトでこれを搭載してほしい

Anker 511 Charger (Nano 3, 30W) (充電器 USB-C)

常にPCを持ち歩いているため充電器も持ち運ぶ必要があり購入。元々は65Wのもの(150g)を持ち歩いていたのだけど、こっちは40gと超軽量なので買い換えた。100g減るだけでも持ち運び時の腰への負担が減るのでQoLが上がった。

タニタ 体重計 体組成計 スマホ連動 50g単位 バックライト BC-332L WH ホワイト

元々はAnkerの体重計を使っていたのだけど、たまに1kg単位でズレることがあり信憑性に疑問を持ったので安心安定のタニタのものを購入。スマホと連動する機能はAnkerの方が便利だったけどまぁよし。

[ヘリーハンセン] スカンザライトジャケット SCANDZA LIGHT JKT ユニセックス

風を通さないので、中にフリースを着れば東京の冬はこのアウターで乗り切れる。あまりにも気に入ったので同じものをもう一つ購入した。

Logicool Signature M750LGR ワイヤレスマウス

クロールがなめらかでホイール音も静か。2台のPCにBluetooth接続できるのが便利

OCNモバイルONEからmineoにMNPした

最近ドコモ回線があまりにも詰まったり繋がらなかったりすることが多くてどうにも我慢できなくなったことと、たまたまmineoがキャンペーンをやっていてコストダウンできそうなので勢いでmineoに乗り換えた。後悔は全くしていない。

数ヶ月前まではドコモ回線がつながりにくいこと以外はOCNは特に不満もなく、Musicカウントフリーオプションの存在もあり3年ほど使っていた。ただ、最近は新規契約を停止していてirumoという改悪されたMVNOに軸足を移す流れがあるのと、その影響でOCNモバイルONE自体がもう改善されないリビングデッド状態になっていたので、緩く乗り換え先を探していた。

mineoにしようと思ったのは

  • 1.5Mbpsなら使い放題のオプションがある
  • ドコモ以外の回線も選べる

という点で、実際乗り換えてみてよかったと思った。それ以外にも通話系のオプションが充実してたり、ギガを永遠に貯められるオプションなどユニークなオプションがあっていいなと思う。

Audibleにハマったのでオススメする記事

AmazonでAudibleが3ヶ月無料キャンペーンをやっていたので試しに使ってみたところ、かなり自分のツボに刺さったので良いポイントをまとめてみた。

自分的にAudibleが刺さったポイント

「本を読みたいけど時間がない...」というのが、Audibleに出会う前の自分だった。いや、正確には「読書したいけどスマホのKindleで読んでいると気付いたら他のことをしている」というのが実態だった。Audibleであれば、ウォーキング中や通勤時間などのスキマ時間に「耳」から本の内容をインプットできるので、「気付いたらスマホで違うことをしていた」ということが起きにくい。そのため、Audibleで本を聴くようになってから圧倒的に読書習慣が根付いた。

豊富なコンテンツ

詳しくは Audibleのサイト を見てもらうとして、対象の書籍の幅の多さに驚く。たとえば小説であれば、「三体」「プロジェクトヘイルメアリー」などヒットしたものは大体あるイメージ。ビジネス書も「イシューからはじめよ」「コンサル一年目が学ぶこと」などそれなりのラインナップがある。

もともと自分はウォーキング中にはPodcastを聴いていたのだけど、あまり興味のあるPodcastもなく惰性で聴いていた。Audibleであれば書籍が対象なので得られる情報の質がPodcastに比べて高いし、密度が濃いと感じる。

なお、Audibleは本の内容を人間が読み上げているため、小説だと「その声じゃないんだよなぁ」と思うこともあるがこれはしょうがない。

Audibleアプリのクオリティが高い

Audibleアプリは、単純にただのAudiobookよりさらに良い体験を提供していると思っている。具体的には、再生速度が0.05刻みで細かく調節できるのと、クリップ&メモ機能が便利だ。

クリップ機能は、読まれている本の位置を保存する機能でいわゆるしおりみたいなもの。クリップしておいた場所に後からジャンプできるのと、そのクリップに対して自分用のメモを保存することができる。メモをする場合は自動で再生が止まるようになっているのも気が利いていて良い。

月1500円で聴き放題

中には別途お金を払う必要がある本もあるが、大体のものは1500円で聴けるので、聴いてみて「これはイマイチだな」と思ったらやめればいいし、逆に気に入ったら書籍を購入するのも良い。本屋での立ち読み感覚で色々聴くことができるのがグッド。

目にやさしい

Audibleを再生している間はなるべくスマホは見ないで外界を見るようにしている。本を読んでいるとどうしても目が疲れてしまう問題があるけど、Audibleではスマホさえ見なければ目は疲れない。

イマイチな点

再生速度を2倍にするなどして速度を上げることでカバーできるが、書籍を読む速読に比べると遅いという問題はある。あと上で書いたように小説はナレーターの声が自分のイメージと違うことが多いので、Audibleで聴くには向かないかもしれない。

まとめ

「Amazonから金でももらっているのか?」というような記事になってしまったけど、Audibleは自分の読書週間を大幅に改善してくれたプロダクトなのでオススメ記事を勢いで書いた。以前Audibleを試して「コンテンツが少ない」と思って使わなくなった人ももう1回見てみるといいかも。

Go言語でcodemod

大規模なコードベースでリファクタリングを省エネ化するためにcodemodを最近調べていて、軽く試行錯誤したのでそのメモ。

やりたいこと

例えば以下のようなTable Driven TestなコードをBEFOREからAFTERに書き換えたい。コード量が多いため人間がやるのは現実的ではなく、codemodで機械的に書き換えたい。

BEFORE

package main

import (
    "slices"
    "testing"
)

func TestContains(t *testing.T) {
    type args struct {
        ss []string
        s  string
    }
    tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "empty: false",
            args: args{[]string{}, ""},
            want: false,
        },
        {
            name: "found: true",
            args: args{[]string{"a", "b", "c"}, "b"},
            want: true,
        },
        {
            name: "not found: false",
            args: args{[]string{"a", "b"}, "c"},
            want: false,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := contains(tt.args.ss, tt.args.s); got != tt.want {
                t.Errorf("contains(): want=%v, got=%v", got, tt.want)
            }
        })
    }
}

func contains(ss []string, s string) bool {
    return slices.Contains(ss, s)
}

AFTER

func TestContains(t *testing.T) {
    type args struct {
        ss []string
        s  string
    }
    tests := map[string]struct {
        args args
        want bool
    }{
        "empty: false": {
            args: args{[]string{}, ""},
            want: false,
        },
    }
    ...
}

DIFF

--- a/tools_eg/table_driven_test.go
+++ b/tools_eg/table_driven_test.go
@@ -10,29 +10,25 @@ func TestContains(t *testing.T) {
        ss []string
        s  string
    }
-  tests := []struct {
-      name string
+   tests := map[string]struct {
        args args
        want bool
    }{
-      {
-          name: "empty: false",
+       "empty: false": {
            args: args{[]string{}, ""},
            want: false,
        },
-      {
-          name: "found: true",
+       "found: true": {
            args: args{[]string{"a", "b", "c"}, "b"},
            want: true,
        },
-      {
-          name: "not found: false",
+       "not found: false": {
            args: args{[]string{"a", "b"}, "c"},
            want: false,
        },
    }
-  for _, tt := range tests {
-      t.Run(tt.name, func(t *testing.T) {
+   for name, tt := range tests {
+       t.Run(name, func(t *testing.T) {
            if got := contains(tt.args.ss, tt.args.s); got != tt.want {
                t.Errorf("contains(): want=%v, got=%v", got, tt.want)
            }

試したこと

eg

egというのは golang.org/x/tools 配下で提供されているコード書き換えのコマンドのこと(link)。例えば以下のようにdeprecatedな ioutil.ReadAll を呼び出している箇所をtemplateのGoコードを用いて io.ReadAll に書き換えることができる。

http_get.go

package main

import (
    "fmt"
    "io/ioutil" //nolint:staticcheck
    "net/http"
)

func main() {
    resp, err := http.DefaultClient.Get("https://github.com/golang/go")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(body))
}

http_get.template

package main

import (
    "io"
    "io/ioutil"
)

func before(r io.Reader) ([]byte, error) {
    return ioutil.ReadAll(r)
}

func after(r io.Reader) ([]byte, error) {
    return io.ReadAll(r)
}

egを使って書き換える

$ eg -t http_get.template -w http_get.go

ただ、egでは先ほどのようなTable Driven Testの struct -> map[string]struct にするのは eg: map[string]struct{} is not a safe replacement for struct{name string} のエラーでできなかった(ref)。

なので、次に紹介するast-grepを試してみた。

ast-grep

ast-grepは様々な言語に対応した、ASTベースでコードの検索、Linterの作成、コード書き換えを行えるコマンドラインツールである。YAMLファイルによる独自のルールを定義することによって、かなり複雑なパターンマッチングを行うことができる。

ASTツリーを表示しながらパターンにマッチした部分をハイライトするPlaygroundも用意されているので、AST初心者でも試行錯誤すればルールが定義できそうな雰囲気を感じる。自分はまだ使いこなせてないので、とりあえず紹介だけ。

これを使えばおそらく先ほどのTable Driven Testのコードは書き換えられそうな気がする。

その他のツール

  • TypeScriptだとts-morphというものがあり、これのGo版が欲しい...!!!
  • Codemodというコード書き換えのためのSaaSがある。内部的にはast-grepなどを呼び出すっぽい

最後に

とりあえずast-grepで試行錯誤して上手くいったらまた記事を書きます。