"tool"

Goのanalysisとtypesに入門する

Goで静的解析してリンターを実装したい。具体的には、あるT1インターフェース型の変数がスコープにあるときは、T1よりゆるい任意の型の使用を禁止する、みたいな制約を入れたい。その辺に転がっている記事ではASTを覗いてみたり、SSAを覗いてみたりするようだけど、ASTとその型をまともに扱っていつつ、いい感じに静的解析ツールとして仕上げる記事を見つけられなかった。

この記事ではGoプログラムの静的解析ツールを実装するために存在する標準的なツールチェーンの思想を説明する。Go Analyzerは静的解析ツールフレームワークとして用いる。具体的な静的解析には標準ライブラリを用いる。

具体的には、あるT1インターフェース型の変数がスコープにあるときは、T1よりゆるい任意の型の使用を禁止する、みたいな制約を入れたい。

これを検証するGoの静的解析ツール。例えば以下のようなrの使用を検知したい。

func parse(r io.Reader) (string, error) { ... }

func (rw io.ReadWriter) {
	var r io.Reader = getReader()
	s, err := dump(r) // 「rじゃなくてrwを使ってくれ〜!」と指摘したい。
	...
}

https://pkg.go.dev/golang.org/x/tools/go/analysis これ。準標準なパッケージ。ドキュメントの冒頭に思想がちゃんと書かれているのでそれを読むのが良さそう。

一個の解析ツールに対応する。Analyzer.Runに解析を実行する関数を定義する。この解析ツールを実行するとき(実行するのはフレームワークの仕事)に、Pass構造体が渡される。

Pass構造体は解析対象のパッケージごとに作成される。なので解析の単位はパッケージごとということになりそう。いいじゃん。

type Pass struct {
	Fset         *token.FileSet
	Files        []*ast.File
	OtherFiles   []string
	IgnoredFiles []string
	Pkg          *types.Package
	TypesInfo    *types.Info
	ResultOf     map[*Analyzer]interface{}
	Report       func(Diagnostic)
	...
}

こいつを通じて解析をする関数は処理対象のデータにアクセスしたり、処理結果を報告したりするぽい。モナドとか代数的エフェクトみたいで綺麗だ。そう思うとあれらは抽象化された一つの振る舞いの切り口を表現するための基本的な演算を定義していたのだから、まあそうだなと思える。Kokaで静的解析ツールを作るときにはpassエフェクトを定義するのだろう。

The Fset, Files, Pkg, and TypesInfo fields provide the syntax trees, type information, and source positions for a single package of Go code.

これは本質情報の予感。このあたりにうまくアクセスすることで、ぼくたちの頭の中で想像する型付き抽象構文木へのアクセスを実現できるんだろう。データ構造が思ったのと違いそうなことには気をつけよう。

これらに加えて、他のanalyzerが出力してくれる結果をこのanalyzerの入力として使える。それにアクセスするためには pass.ResultOf[a].(aResType)を参照すればよい。

診断(diagnostics)を出したければPass.Reportとか、パッケージで提供されているReportfとかを使うらしい。

ここまでで、モジュラーに静的解析ツールを実装するフレームワークの構造がわかった。それに乗っかれば静的解析をいい感じに動かすことはできそうだ。静的解析の処理を実装する方法もなんとなくわかった。Pass構造体の世界観に乗っかればokな感じがする。

次に自在にプログラムを解釈する方法を知りたい。プログラムはコンパイラに処理されていろんな形態に変換されるので、ユースケースに応じて適切な表現を選ぶ必要がある。今回は型付き抽象構文木を扱いたいので、Pass構造体のFset, Files, Pkg, TypesInfoあたりを上手に使えると良さそうだ。特にTypesInfoが気になる。これは types.Info型をとるみたいなので、typesパッケージを見に行く。

typesパッケージはこれ https://pkg.go.dev/go/types。冒頭の説明がスッキリしていてまだ何をやれば型付き抽象構文木に対してクエリっぽいことをできるか、どんなクエリっぽいことが許されるかを理解できない。なので貼ってあったチュートリアルのリンクを辿る。なお、スッキリしている説明自体は読んでよかった。このパッケージが扱うフェーズで何をやるか説明されていて、もっと詳しく読んで良さそうなことに自信を持てた。

なお、僕の目的のためには他の解析ツールの結果を使う方が良いかもしれないとも思う。暇だし気になるのでチュートリアルを読むのに時間をかけるけど。

脱線したがチュートリアルを読み進める。https://go.dev/s/types-tutorial これ。これを読む目的は、何をやれば型付き抽象構文木に対してクエリっぽいことをできるか、どんなクエリっぽいことが許されるかを理解すること。

このチュートリアルはジェネリクスには対応してないらしい。ジェネリクスのためのドキュメントは別途あるとのことだけど、今回は基礎を知りたいので気にしない。

イントロと例くらいは読んでみて、あとは斜め読みでいいかな。まずはイントロ。

Measured by lines of code and by API surface area, it is one of the most complex packages in Go’s standard library, and using it requires a firm grasp of the structure of Go programs.

とのこと。大変だ。

Starting at the bottom, the go/token package defines the lexical tokens of Go. The go/scanner package tokenizes an input stream and records file position information for use in diagnostics or for file surgery in a refactoring tool. The go/ast package defines the data types of the abstract syntax tree (AST). The go/parser package provides a robust recursive-descent parser that constructs the AST. And go/constant provides representations and arithmetic operations for the values of compile-time constant expressions, as we’ll see in Constants.

データ構造とアルゴリズムを分けるの賢そう。parserにastを定義しないとか偉い感じがする。色々あるんだろうな。どう嬉しいのかはわからないけど。定数畳み込みをastに対して実装したいが、parserに依存するわけではないよね、みたいな話かな。

名前解決、型検査、定数式の計算は一緒にやらないといけないなるほど。ここでいう名前解決とは、名前の出現に対してその宣言を対応させること。

例まで読んだがパッケージレベルの話しかわからないな。ぼくは式とかのレベルでプログラムを処理したいんだ!ということで本命のInfo構造体への言及を探すことにすると、TypeAndValueでそれらしいことを述べている。

Info.Typesは map[ast.Expr]TypeAndValue らしい。そろそろ手を動かして、プログラムのこの要素は式として扱われるか?とかをみたい。と思ったらドキュメントが例を出してくれた。こういうときが一番楽しい。式があったら型は得られるようになってるのね。ただまだよくわかってなくて、mapの定義域をast.Exprとしているが、そのExprとして本当に登録されるのはどの範囲のExprなのかがわからない。当然 ast.Expr{} なんて渡しても、その型を計算しているわけがない。どういう操作で手に入れたast.Exprに対しては、Info.Typeがその型を教えてくれるんだろうか。Infoを生成するやつが知ってるのかな。analysisパッケージはよくわからんPassがInfoを持っていたので微妙だけど、パッケージの単位で処理をするのでパッケージに存在するすべての式の型を教えてくれると思って良さそう?

確かにConfig.Checkはパッケージを型検査して、引数にInfoへのポインタをとって結果を書き込みそう。

次に、型同士の比較をしたい。具体的には、T1が必要な文脈でT2は使えるか (assignable) を判定する方法が欲しい。そのためにこれが使えるhttps://pkg.go.dev/go/types#AssignableTo。引数に渡すTypeインターフェースの値はTypeAndValueで取れるので、ほとんど勝ったようなもの。ちなみに僕は、最初ConvertibleToを使っていて全然ダメだった。ConvertibleToは数値が変換できるか判定するやつぽい。

2024-08-21

Zedエディタをずっと使っている。nvimを使う機会は無くなったと思う。ぼくにとってnvimを使うのは起動が爆速なvimモードで編集できるエディタであることだけがモチベーションだった。 Zedがそれをほぼカバーしているので、慣れとか不満をまとめることを目的としてZedを使うことにした。

Zedは速いし機能もしっかりあるし、設定ファイルのデザインが意味ある単位で残すモチベーションの湧くような設計になっていることろが好き。

Winsowsで使えないとか日本語入力に不満があるとかはまあいいかと思えるくらいには良いと思っている(そのあたりはコントリビューションチャンスということで)。

今年の夏休みは充実していた。

  • 実家に帰省
  • おばあちゃんハウスに帰省 (with 家族)
  • 高校の友達と会う
  • 大学の友達と金沢・高山観光
  • オリエンテーリング参加
    • 久しぶりにやった。楽しかった
    • 大学の別の友達とかと会う
  • 新しく人と関わり始める
  • k8s入門
  • Zed入門
  • unifiedとcloudflare入門(日記用のブログサイトの作成・デプロイ)

雑にメモ化して実行速度が倍くらいになったのだけど、嬉しいような何をやってるんだか、という気持ちになる。今回のは重複するファイルアクセスの結果を変数に束縛するだけなので、メモ化というかなんというかだけど。それくらい最初から作法としてやろうという感じはする。

2024-08-15

日記をnextjsでビルドして、cloudflare pagesにデプロイするようにした。cnameの設定が効くようになれば、https://diary.nfurudono.comから見えるようになるはず。

cloudflareのアカウントを初めて作って設定したが、体験よかった。デプロイとか周りの開発のためにCLIツールやそれのgithub actionsバインディングが提供されていて、サクッとデプロイできた。記念すべき初デプロイの成功をメモしておくhttps://github.com/naoyafurudono/naoyafurudono.github.io/actions/runs/10399555684/job/28798614059

Hugoの設定をたくさん書いていても楽しくないのでNext.jsでなんでもやってみよう、というモチベーション。unifiedがいい感じで楽しいので動くところまで持って来れた。

ソースコードはhttps://github.com/naoyafurudono/naoyafurudono.github.io/tree/main/tools/ttにある。

Neovimにlazyを入れてプラグイン管理することにした

これまで特にプラグインを使っていなかった(それくらいで済む用途にしか使っていなかった)のだけど、カラースキームを指定したくなったのでプラグインマネージャを入れた。

どれども大差ないといろんな記事で言われていたので名前とかが気に入ったlazyを使うことに。

https://github.com/naoyafurudono/dotfiles/blob/add-lazy/nvim/init.lua#L17-L55 で設定している。

2024-08-12

vimの sort コマンドを知った。設定ファイル書くときとかの、気持ち並び替えておきたいところに使えて便利。

週末は帰省して、さらに親の実家に行き親戚に会ってきた。いとこの子供にジュースをたかられて甘やかす体験を初めてした。あんなに食べて大丈夫かと思うほどよく食べる。

AHK入門

Windowsマシンでキーボード操作が不便なので導入する。悪態をつきながらも使っている人を知っているので内容を理解していないが期待している。

https://www.autohotkey.com/ 公式ページからバイナリを落とせる。インストールするとwelcome画面が開いたのだが、そこに「コンパイルする」ボタンがあって、ちょっと不安になる。僕はプログラムをボタンを押してコンパイルしないといけない?

ついてきたマニュアルはいい感じのスタイリングでよみやすそう?

頭から飽きるまで読んでいく。

  • スクリプトの作成 (Create a Script)
    • Be sure to save the file as UTF-8 with BOM if it will contain non-ASCII characters. For details, see the FAQ.

    • BOMがいるらしい。そういえばBOMってなんなのだろう。結局まだちゃんと理解してない。
  • スクリプトの実行 (Run a Script)
    • なんかソースファイルをダブルクリックしたりして実行できて、実行してる間だけ効くらしい。
    • イベントハンドラみたいなやつの定義がそれぞれのスクリプトに対応するかと思っていたが、なんかメンタルモデルがあってなさそう
  • それぞれのスクリプト実行がWindowsのトレイアイコンに反映されるらしい。なるほど

飽きたのでhello worldする。

以下はCapsLockを押すとhello, worldと出力するよう設定するahkスクリプト。ちなみにこれらのhello, worldはCapsLockを打って入力している。

#Requires AutoHotkey >=v2.0.0

CapsLock::
  {
    SendInput "hello, world"
  }
  Return

CapsLockで英数変換するのは以下で実現できた。

#Requires AutoHotkey >=v2.0.0

CapsLock::
  {
    SendInput "^{Space}"
  }
  Return

紆余曲折あって、以下のようになった。Windowsでもいい感じにvim使えるようになって幸せ。

https://github.com/naoyafurudono/dotfiles/blob/main/autohotkey.ahk

#Requires AutoHotkey >=v2.0.0

IME_SET(SetSts, WinTitle:="A")    {
    hwnd := WinExist(WinTitle)
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        cbSize := 4+4+(PtrSize*6)+16
        stGTI := Buffer(cbSize,0)
        NumPut("Uint", cbSize, stGTI.Ptr,0)   ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", "Uint",0, "Uint",stGTI.Ptr)
                 ? NumGet(stGTI.Ptr,8+PtrSize,"Uint") : hwnd
    }
    return DllCall("SendMessage"
          , "UInt", DllCall("imm32\ImmGetDefaultIMEWnd", "Uint",hwnd)
          , "UInt", 0x0283  ;Message : WM_IME_CONTROL
          ,  "Int", 0x006   ;wParam  : IMC_SETOPENSTATUS
          ,  "Int", SetSts) ;lParam  : 0 or 1
}

IME_GET(WinTitle:="A")  {
    hwnd := WinExist(WinTitle)
    if  (WinActive(WinTitle))   {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        cbSize := 4+4+(PtrSize*6)+16
        stGTI := Buffer(cbSize,0)
        NumPut("DWORD", cbSize, stGTI.Ptr,0)   ;   DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", "Uint",0, "Uint", stGTI.Ptr)
                 ? NumGet(stGTI.Ptr,8+PtrSize,"Uint") : hwnd
    }
    return DllCall("SendMessage"
          , "UInt", DllCall("imm32\ImmGetDefaultIMEWnd", "Uint",hwnd)
          , "UInt", 0x0283  ;Message : WM_IME_CONTROL
          ,  "Int", 0x0005  ;wParam  : IMC_GETOPENSTATUS
          ,  "Int", 0)      ;lParam  : 0
}

IME_TOGGLE() {
  current := IME_GET()
  IME_SET(!current)
}

IME_OFF() {
  IME_SET(0)
}

CapsLock::
  {
    IME_TOGGLE()
  }

~Esc::
  {
    IME_OFF()
  }

2024-07-06

先週くらいに調査をした上で今日材料と道具を買ってきて、加工のための準備をしている。誤差は出るものとして、それを許容できる加工方法を考えるのが楽しいしめんどい。

今日で材料調達までやった。近所にコーナンがあるのでそこで木材を買って、カットサービスで板を切り出してもらいつつ工具の貸し出しとバンを借りての運搬をした。コーナンの皆さんはプロフェッショナルな感じがして最高だった。どこからどこまでが責任範囲かを明確に意識してらしているし、彼らの範囲内であれば柔軟に対応してくれる。僕の範囲の話をふるとそれはあなたの決めの問題だと言ってくれて最高。それでいてドライな感じではなくてHRTな感じがしてすごい。今まですごいスーパーと見ていたのはもったいなかったなと思っている。コーナンの彼らは専門性と職責を理解して遂行するプロフェッショナルだと感じた。サービスカウンターの方と木材カットの対応をしてくれた方とお話ししたがみなさん本当にすごかった。

一度設計をしたのだがでかい板からの切り出しの寸法を計算したタイミングで捨ててしまったので設計を書き直す羽目になってしまった。とはいえそこはサクッと復旧できて、今はちまちま補助線を木材に引いている。飽きて試しにした穴を開けたりしているのだが、意外と良い工作精度が出ているので心配しすぎだったかもしれない。

ツイッタを徘徊していると一緒に仕事している強い人の悩みをうかがい知れて楽しい(ぼくが楽しむことを分かった上で知らせてくれているのだろう)。分かっていることではあるが、向こうも不安を抱えながら決断して僕たちに指針を示して進んでいるのだよなと確認をした。どこかで飲みに行きたい気持ちになった。大体納得の上で一緒に動いているが数くないぼくがいだているちょっとした不満(納得はしている)を共有したりしたいなと思っている。

2024-06-25

本棚を自作する。清く正しい本棚の作り方が参考になりそうなので通読する。

通読した。以下の手順かな。今度ホームセンター行こう。

  • 材料の検討をつける
    • 21mm以上の厚さでカット可能でそれなりのサイズの板が必要
    • パイン集製剤はよさそう
  • 設計する
    • 自分の本のサイズとその量を見積もるかな
    • 僕の場合は専門書が3サイズ(A5?,A4?,教科書?)あるのと小説と漫画がある。それぞれのサイズを計り量を見積もる
    • その上で高さ180cmくらいかなのものを一旦設計して、入手できる材料のサイズを鑑みて調整する
  • 材料を調達する
    • 購入・裁断・運び入れが課題
  • 組み立て
    • 補助線の書き込みと穴あけ、ねじ止めとボンドでの固定がやること
  • 研磨
    • エッジの処理とかはこのタイミングで一度やる
  • 塗装
    • 材料によるがニスとかでいいかな
    • 蜜蝋とか油は本への影響がありそうでちょっと怖い
  • 乾かす
    • 塗料が乾くまで外で乾かす。天気が大切
  • 研磨
    • 最後にシュッとやれるとよさそう

RubyKaigi2024参加メモ

RubyKaigi2024に参加したので、思ったことをメモしておきます。

参加したセッションはこちら: https://rubykaigi.smarthr.co.jp/2024/plans/d2350276-c631-4bdc-ad75-49e446e798a3

今回のセッションをいくつか聞いてShopifyのやり方に憧れるようになった。エンジニアリングをしていく上での姿勢として、課題に対して上流から対処しよう、みたいな箴言があってそれが心に残っている。 ShopifyのRuby周りのチームはまさにそれを地で行っていると今回のセッションを聞いて感じたそういうチームに所属して(作って?)良いエンジニアリングをしていきたいと思っていたのだが、これまでは具体的なイメージいを持っていなかった。

ShopifyのRubyチームによる貢献にはすでに自分が直接的に恩恵を受けているし、彼らがどういう思想で取り組んで具体的に何をしてきたか、これからどういう思想でやっていくかを生で聞くことができた。遠いけれども具体的に目標とする存在に出会えたことが今回の一番の収穫だったと思う。

バージョンとかライブラリのインストールとか大変だしよく分からないのでスッキリする方向に進んでいきそうで楽しみ。セッションも普通に勉強になった。

一方的に知っていた人もお互い初めましてな人もお話しできてよかった。今回存在を新たに認知した人ももちろんいて、いろんな人が色々やっていることとか、意外とコミッタ少ないこととか認知できて良い。 Rubyって人間が作ってるんだなと感じる。

現実味を感じる一週間でした。

hugoで多言語対応始めた

https://github.com/naoyafurudono/naoyafurudono.github.io/commit/b4966a3e96c2a8131da6d623cef85df5c97439ba このコミットみたいな感じで設定したりファイル名を変えたりすると、いい感じにパスを掘ってくれる。

パスを掘ってくれる以外のメリットは知らない。

Nextjsのプロジェクトにstorybookを導入してみた

https://github.com/naoyafurudono/timer/pull/1

このプルリクエストで頑張った。コミットメッセージにやったことは書いてある。

公式ドキュメントがしっかりしてそう。storybookが内部で使っているwebpackが@ インポートを読めないみたいで、プラグインを入れる必要があった。

2024-03-02

op inject が欲しいやつだった。テンプレートに1passのURLぽいやつを書いてコマンドに渡すと、そこを埋めたファイルを出力してくれる。埋め込むときに環境変数を読んで、URL内での参照を置換した上で1passのレコードを参照することもできる。

https://developer.1password.com/docs/cli/secrets-config-files/

2024-02-17

glangにgeneraterを入れようというプロポーザルがあって、試験的に実装されているみたい。いくつかのパターンがあるけど、だいたいこんな感じで使える (The Go Playground)

ジェネレータとして使われる関数は定義の段階では普通の関数と区別がつかないような構文定義をされている。コンパイラやランタイムの実装が気になるし、静的解析ツールが大変なことにならないかが心配。

気が向いたらプロポーザルを読もう。ジェネレータが引数にとる関数がブールを返すけど、どちらを返すかを誰が決めているかも気になる。

第一印象ではgolangには入らないで欲しいなと感じた。

読書メモ - eBPF入門

  • eBPF面白そうだったので。その目的とかユースケースを知りたかったり、周辺ツールがどういう具合に整備されて使われているかも知りたかった。

  • コンテナ横断で情報を取れるのはなるほどなって感じ
  • hello worldいつやろうか迷う
    • limaでやるのはつらいのかなと想像しつつ手を動かしていない
    • 帰省していてlinuxマシンが手元にない
    • 本で紹介されている方法は本番ではお勧めできないとか今の所書いてあるし

  • コンテナ環境をホストするなら監視で使えるかも。いかがわかっていない
    • 何を監視したいのか
    • 何を監視できるのか

  • プログラムのサイズを制限しているのは何が目的なんだろう

2023-11-14

このブログのデプロイに使っているgithub action workflowを読んでいたら、外部リポジトリにデプロイするのも簡単なことに気がついた。https://github.com/peaceiris/actions-gh-pages/tree/v3/#%EF%B8%8F-deploy-to-external-repository-external_repository

たとえばプライベートリポジトリでマークダウンを管理して、公開したいアセットだけを今のリポジトリに置く運用を実現できる。公開したくない文言はどこにも書かない運用にしているのだけど、限界はたまに感じるので移行しても良いかも。とはいえ情報はできるだけオープンにしたい信仰があるのも確かなので悩ましい。

2023-10-24

hugoでCJKの文章で改行を無視できるようになった。 platexとかでは当たり前のように単独の改行は日本語文中で無視されていたが、巷のmarkdownエンジンはそうとは限らない。 hugoがデフォルトで使うgoldmarkではオプションで指定できていたようだが、 hugoではそのオプションを活用しないでいたみたい。

v0.118.0に更新される際に、hugoの設定でサポートされるようになった(リリースノート)。とてもめでたい。

昔は改行しない人間だったのだけど、論文を書くときに教えてくれていた先生が綺麗に改行しているのを見てそれに倣うようになった。テキスト処理は人間の仕事ではなくて、ソースコードは読み書きしやすい形であることだけを気にするべきだと信じているので改行は自由に行いたい気持ちがある。

先月PRを書いたやつがシュッとマージされていた。本当にそれでいいんか?という感じがするが、何はともあれコントリビュータになれたのは嬉しい。好きなツールに貢献できる喜び。

世の中にはいろんなソフトウェアやシステムがあって日常的にそれらを使っているわけだが、いざ何かを作りたいとなったときに何をするのが楽しそうかは悩んでしまう。何が面白そうかわからないのだ。普段使っているあれこれが100倍早くなったらどうなるかを想像して幸せになれそうならそれを実現するために頑張るのは便利な考え方かもしれないと思った。

2023-10-09

テキストを扱うツールをたくさん知れたことが情報系に進んで一番お得なことだったなと感じている。エディタ、git、その他CLIツールを日常的に使う環境に身をおけたことは幸運だったと思う。というか、これが幸運ではなく当たり前な世の中になって然るべきな気がしてきた。

GASでスライド生成

Google Slidesで作成したテンプレートファイルに文字列を置換する形でスライドを生成するスクリプトをChat GPTに書いてもらったのでメモ。

+--------------------------------+
|                                |
|  {{氏名}}                      |
|                                |
|                                |
|     {{住所}}                   |
+--------------------------------+

みたいなスライドを作って、

氏名,住所
佐藤太郎,日本のどこか
田中一郎,東京のどこか

みたいなスプレッドシートでスクリプトを実行すると以下のようなスライドをテンプレのあるスライドに追記する。

+--------------------------------+
|                                |
|  佐藤太郎                      |
|                                |
|                                |
|     日本のどこか               |
+--------------------------------+

+--------------------------------+
|                                |
|  田中一郎                      |
|                                |
|                                |
|     東京のどこか               |
+--------------------------------+

スクリプトは以下。

function createSlidesFromSheet() {
  var slideId = 'ここにスライドのIDを入れる'
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();
  
  var slide = SlidesApp.openById(slideId);
  var templateSlide = slide.getSlides()[0]; // テンプレートとして使う最初のスライドを取得
  
  var headers = data[0]; // ヘッダー行を取得

  // データ行をループ
  for (var i = 1; i < data.length; i++) {
    var row = data[i];
    var newSlide = slide.appendSlide(templateSlide); // テンプレートスライドをコピー
    
    var shapes = newSlide.getShapes();
    for (var j = 0; j < shapes.length; j++) {
      var shape = shapes[j];
      var text = shape.getText().asString();
      
      // スプレッドシートのヘッダーを参照して、対応するデータでプレースホルダーを置き換える
      for (var k = 0; k < headers.length; k++) {
        var placeholder = '{{' + headers[k] + '}}';
        text = text.replace(placeholder, row[k]);
      }
      
      shape.getText().setText(text);
    }
  }
}

2023-09-21

gh コマンドを使うとPRの番号とタイトルを取得できる。

gh pr list --search "<SHA>" --state merged`

https://cli.github.com/manual/gh_pr_list

"<SHA>" の部分は一般にクエリを指定できるそう。多分 pr:open みたいなやつ。逆にコミットハッシュを指定できることが驚き。

ベストバイ

酔っていて興が乗ったので「しばらくの間で買って良かったもの」N選をやります!!

本棚を買いました!横に長いタイプの本棚で、高さは太ももくらいです。二段だけで、本棚の上にも物を置けるような感じ。幅は120cmくらい(ところでセンチって微妙ですよね)で、横に長めの本棚です。 2cmくらいの厚さのベニヤ?でできていて、それなりに丈夫そうな雰囲気があります。 minneで買いました。一階にプログラミング言語のほんを置いて、2階にそのほかの本を置いています。本棚にある本の中でのおすすめは、『数学の基礎 集合・数・位相』です。これを読むと実数の作り方がわかって感動できます。また、眠れない夜にぴったりで、楽しめるときには存分に興奮できるし、そうでもないときには眠くなります。ホテルに聖書の代わりにこれを置いたらいいのにと思ってます。

M2 macbook airを買いました!これはいい物です。ノートパソコンのいいところは椅子に座らないでも使えるところです。仕事で疲れた体でも、ノートパソコンならさわれます。退勤後もキーボードを触る幸せを感じられるのはノートパソコンのおかげです。ところで酔った状態でキーボードを叩いていると、タイプミスが頻発します。タイピングに頭のリソースを使っているようです。 m2 macbook airはキーボードがいい感じだし、性能もいいのがいいところです。メモリは16GBにしています。細かいことはよくわからないので、考えないことにします。

キリがない気がするので個数制限を設けましょう。 N=5にします。あと3個。

ルンバを買いました。ルンバのいいところは、掃除でstuckしている光景がちょっとかわいそうなところです。彼は頑張って掃除してくれるのですが、たまに段差に座礁して身動きが取れなくなります。その姿は少し傷ましくて、それを避けるための掃除をしないとなという気持ちにさせてくれます。一人暮らしの家に優しさを発揮する機会を与えてくれるのがルンバのいいところなんじゃないかと思います。こういうふうに書くと彼はポンコツみたいな表現になってしまいますが、彼は僕より掃除が上手いです。頼りにしてるよ。

会社に入るよりかは前に、echo dotを買いました。 echo dot自体がもたらす利益よりも、そのインターフェイスがあることを前提とした環境構築への影響がノミネートの理由です。 echo dotのおかげでルンバやswitch botを導入できました。音楽も流せるしアラームも設定できる。

5月の頭にリュックサックを買いました。新宿の駅の近くの百貨店で見つけて、ゴールデンウィークいっぱい悩んでから購入に至りました。出勤も旅行もオリエンテーリングの遠征も全てこのリュックと一緒です。ちょっと小さいけど必要十分な機能提供してくれている感じが好き。

いかがだったでしょうか? この記事ではベスタバイ5選を紹介しました! この記事が皆さんの参考になれば幸いです。よかったらチャンネル登録と高評価、よろしくお願いします。

<!-- エンディングテーマが流れる -->

2023-09-09

tomlもyamlも難しいので、みんなjsonを書けばいいのにと思う。 Goとか静的型付け言語とかが流行って、読みやすさの意義が重要視されている時代なはずなのに、設定ファイルは書きやすさとか、見栄えの良さが重視されていそうなフォーマットが人気なのが解せない。 jsonがナウいんじゃないかと思うし、好みとしてもjsonがいいなと思う。

jsonは誤解することが一番少なそうだし、みんな何が嫌なんだろう。編集がちょっとたいへんとか? そんなに設定ファイルを編集している時点で大変なことになっているのだから、それは妥当な大変さ何じゃないかと思うのだけど。

ブログを分割したい

このブログは日記も開発っぽいことも両方書いてある。これらを別のサイトに分けようと考えている。

  • 開発の記事が日記に埋もれるのが嫌だから
  • 今の環境だと開発の記事を書きにくい・表現しにくいから
    • コードや数式を書きにくい・表示が微妙など
    • madoko使いたい

そのための準備としてnetlifyを試しに使ってみた。このブログのリポジトリを登録したら、特に細かい設定をしないでもシュッとデプロイできてしまった。すごい。DNSとかSSLとかの設定を試していく。

ところでデプロイの設定は何もわからないのでチュートリアルが必要。madoko使うなら設定ちゃんとしないとだろうし。

2023-08-30

dotfileを整備して、シェルの設定を複数のマシンで共有していると、あるコマンドがインストールされている場合にのみ、有効にしたい設定が出てくる。僕が今回遭遇したのは、k8sのcontextをプロンプトに表示する設定をなんとかしたいという欲求。いい感じに表示するコマンドが入っていれば、プロンプトに反映したいけど、入っていなければ別に表示しないのもありで、無理して全てのマシンにコマンドをインストールしたくはない。

コマンドの存在をチェックして、設定を条件分岐するのがナイーブな解決方法で僕もそうした。そこで気になるのが、コマンドの存在チェックのベストプラクティス。

command -v が良さそうだった。https://qiita.com/kawaz/items/1b61ee2dd4d1acc7cc94 fishでもbashでも使える。

コーヒーとハンバーガーを食べたらいつもより夜に動けている。不健康は一時的な動作を促進するのかもしれない(本当か?)。

昼健康な食事を摂ったのでバランス。

dotfilesのセットアップスクリプトを書いた

dotfilesをGitHubで管理しているのだが、今までは設定ファイルの管理だけで、インストールは手動で行なっていた。設定ファイルを使いまわせるだけでだいぶ便利なんだけど、コンテナ環境の中で作業したくなると、手動インストールに耐えられなくなる。そこで重い腰を上げてセットアップを自動化した。

git のインストールと以下の実行でok。 nvimとかfishとかcargoとかが入る。

git clone https://github.com/naoyafurudono/dotfiles.git
bash dotfiles/setup.sh

test

arm環境かつubuntuだけでしか動かしていないが、dockerコンテナでセットアップスクリプトを動かして、正常に終了するかを確認するテストを書いた。

この手のセットアップスクリプトのテストって、世の中ではどのようにテストしているんだろう。以下の難しさがテストを大変にしている気がする。

  • 環境依存な部分をうまく吸収する必要があること
  • インストール失敗の判定が難しいこと

2023-07-01

envsubstを使うと標準入力の環境変数の参照っぽいところに環境変数の値を埋め込んだテキストを吐ける。 readmeにコマンドのヘルプメッセージを載せたいときに便利。例: https://github.com/naoyafurudono/tools/tree/main/cl

gitで管理しているファイルのパスが得られる。 git grepみたいに管理対象だけに興味があるときに便利そう。 fzfとの相性が良さげ。

2023-06-30

すでにgit管理されているファイルをgitignoreでマッチするようにしても、管理から外れない。外すためには以下のようにすると良い。

git rm -r --cached .
git add .
git commit -m 'update with .gitignore'

2023-06-29

crate.ioに初めてコードを登録した。cargo install で入るから便利。ちょっとしたCLIツール書く体験がなかなか良い。 copilotが面倒なことやってくれる。

crates.io

Railsとか書いてると深いところに元からあるファイルをコピーしたいことがちょいちょいある。そのときに長いパスを2回打ちたくないので作った。

2023-06-24

macのタイムゾーンの設定が狂っていて、今日の投稿がこれと前回の二つに分かれてしまった。

今日はmacの設定と、以降に伴って壊れたちょっとしたCLIツールの修正した。昔Rustで雑に書いたもので、エラー処理が辛そうだったので少し勉強して改善した。 anyhowを使ってみたい気持ちが湧いたけど、まずは基本的なところからということでトレイトオブジェクトを使うことにした。type Result<T> = std::Result<T, dyn Error>みたいな感じにすることで、いろんなエラーを孕んだresultに?を使うことができて幸せ。

一箇所ムムッとなったのが、クロージャの中で?を使う箇所。dyn Errorの気持ちで書いていたら、推論器はもっと具体的な型を推論していたみたいで、二つ目のエラー型の式に対して?したら型エラーになってしまった。こういうときはアノテーションをつければ良い。 Rustの型推論の割り切り方に慣れていない。

2023-06-23

macを買って環境構築をしているのでメモしていく。

  • capslock -> eisu toggle
    • システム環境設定 > キーボード > テキスト入力 > 入力ソース > Caps LockキーでABC入力モードに切り替える
    • 最近のmacは組み込みの設定で変更できるようになった
  • 1Password
  • CLIツール: 以下の順で入れると良い。気が向いたらインストールスクリプトを書こう
    • brew
    • fish
    • nvim
    • .config
    • その他
  • gitでsshを使うための設定: この投稿のおまけを参考に
    • 鍵を生成
    • githubに公開鍵を登録
    • .ssh/configを書く

個人メモ:dotiflilesに書いてあるのでコピペは不要。

# for fish
function _ssh-keygen
  set name $argv[1]
  mkdir -p "$HOME/.ssh/$name"
  ssh-keygen -t ed25519 -f "$HOME/.ssh/$name/id_ed25519"
  chmod 600 "$HOME/.ssh/$name/id_ed25519"
end
#!/bin/bash

name=$1
mkdir -p "$HOME/.ssh/$name"
ssh-keygen -t ed25519 -f "$HOME/.ssh/$name/id_ed25519"
chmod 600 "$HOME/.ssh/$name/id_ed25519"

Host github.com
  User git
  IdentityFile /Users/naoyafurudono/.ssh/github/id_ed25519

Terraformでローカル環境の管理とかできないだろうか?

2023-06-17

ルンバをレンタルして今日から使い始めた。結構細かく動いてくれて僕より掃除がうまい気がする。 7時/19時で掃除するようにしたので、目覚まし代わりになるはずだし、寝る前と出勤前に床を片付ける習慣がつきそうで期待してる。

日中に運動するとその日の体力とやる気を使い果たして何もできなくなる。やはり夜に運動するのが性に合っていそうだ。

2023-05-19

明日は秋吉台に行く。楽しみ。新幹線を初めてスマホで買った。どうやらモバイルパスモで乗れるみたいなのでワクワクしてる。更に今日、仕事が終わってからJINS MEMEを買ったのでそのあたりでも楽しみが止まらない。

明日は早いのでさっさと準備して寝ないといけない。

2023-05-13

もともとbashで書いていたスクリプトを拡張したくなって、普段ならPythonで書くところを今日は新しいことをしてみようということでRustをつかってみることにした。

Rustはまったく初めてと言うわけではなくて、ちらちらドキュメントを読んだり、ノリで学校の課題をRustで書いてみたり(痛い目にあった)したことがある。所有権のあたりで苦労はあまりしなかった(というかPythonっぽくヒープを贅沢に使うコードを書いた)のだが、Result / Optionの変換で発狂しかけた(メソッドが定義されていることに思いをはせられずに自作してしまった)。

あまり苦労しなかったと言いつつ、所有権のあたりで困りはしている。参照を受け取るコンストラクタに、その場で作ったオブジェクトを渡したいときに、一旦変数に束縛しないと、渡すオブジェクトが即死してしまっていけない問題が面倒。名前をつけるまでもない、式が体をを表しているような値にまで名前をつかないといけないのはしんどい。コンストラクタが所有権を奪うようにすればよいのだろうか。いらないから参照にしたのだよな…。

今ではそこそこなれてきて、代数的データ型とまともな型検査器がついたPythonくらいの書き方はできるようになった。 Rustのライブラリがイケイケに作られていて(エラー処理周りは辛いと感じるけど)、プログラムを書いていて楽しい。すごく汚く書いてしまった。当面の目標はまともにかけるようになることかな?ちょっとしたCLIでは大差ないのかもしれないけど。

ブログのGitHubのプログラミング言語構成比がカオスなことになってきた。

ここ何日か胃腸炎でつらい。今日はだいぶ回復して、Rustを勉強できるくらいになったけど、まだつらみを感じる。とはいえ三食たべても大丈夫な体に戻りはしたので問題なし。何日か会社に行けなかったのがなかなか悲しい。

今日は以前もらい忘れた診断書を書いていただいた。前回の診療に対して診断書を出してもらうことはなんだか難しそうで、もう一度診察していただくことになってしまった。自分の中では治ったと思っていたけど、見ていただいたらまだ治っていないとのことだったし、今はそう感じる(流されやすい性格なのか?)ので、忠告していただけてよかったと思うことにしている。

病院の帰り道で食器のフリマ的なことを日本料理屋さんがやっていた。普段使っている食器を入れ替えるのかなにかで、安く売り出してくださっていたようだ。胃腸炎になるまえに、会社のランチで「おいしそうな自炊の写真はくろっぽい器が大切」とのアドバイスを頂いていたことを覚えていたので、これは運命だと思い食器を購入した。黒っぽい器はどんぶりしか出会えなかったけど、それがなかなかいい感じだし、白っぽい器もいい感じのにいくつか巡り会えたのでほくほくしている。

あとはおいしそうなご飯をつくればよい。

夕飯につかってみた。いい感じ。味噌汁のお椀(蓋付き)が小さいやつで、フリーズドライの味噌汁一杯分しか入らないやつ(褒めてる)。感動している。

(アマプラ)。グレンラガンの監督?が制作しているらしい。ノリが楽しい。

2023-04-16

午前中はChatGPTとかであそんでいた。ブログを書いていたおかげで、AIに食わせる自分の書いた文書に困らないのが嬉しい。

文書から自分の人柄を表現してもらって、それをもとにSNSで使えるアイコンを生成しようとしたのだけどうまくいかない。人柄の表現はそれっぽいのができるのだけど、表現が抽象的になってしまうので、そのままアイコン画像を生成につかうと小学生のときによんだ漫画にでてきそうな怪しくて怖い宗教っぽい画像がでてきてしまう。

インターネット上でのキャラクタに合わせたアイコンを提案してもらえたら楽しくないだろうか?

ちなみに生成できた画像はこんな感じ。改善のしようはいくらでもありそう。

DALL-Eで生成したもので、権利の問題はなさそう (2023年4月16日閲覧):

Starting today, users get full usage rights to commercialize the images they create with DALL·E, including the right to reprint, sell, and merchandise. This includes images they generated during the research preview.

本腰を入れて文書を読むときは印刷して読みたい。なので長いWebドキュメントを読むときは少し辛いし、論文を読むときは(本腰を入れて読むなら)印刷する。本はたいてい物理の書籍を買っていた。印刷するのが面倒だし、書き込みを残しやすいので。

ただ就職して出社するようになって、移動中に文書を読みたい機会が増えた。そんななかで本を持ち運ぶのは大変で、その日に読みうる範囲だけを持ち運びたくなった。そういう経緯でPDFみたいな印刷しやすい形式で購入できる場合は積極的に電子書籍を買うようになってきた。本のサイズが小さければこれまでと変わらず物理で買ってしまうのだが、面積が大きかったり鈍器の形をしているものは電子書籍を買う。

書き込みが残らなくなる問題は解決できていないが、書き込みたくなるほどまじめの読むことは少ないし、そこまで腰を吸えられるのは結局家の中のはずだ。今の生活ではそんなに困らないだろう。余談だが、EoPLを物理でもっていないのは数少ない書き込みが大切な機会を逸しているように思える。

SNSで情報発信するのがあまり得意ではない。もともと会話があまり得意ではなくて、インスタントに情報を発するのが苦手なのだと思う。なにか考えてから言葉にするのにある程度時間がかかるし、言葉にしてから吟味したくなってしまいもする。

お酒が入ると吟味したい気持ちがどこかにいってしまうからしゃべる量が増えるのだろう。

話を戻そう。SNSは思ったことをパッと書いてそのまま発信することを重視したようなUIをしているように思う。たぶんそういうところで苦手意識を持っている。とはいえ情報発信の場としてSNSがメジャーなのは間違いないだろうし、ここみたいなブログはほとんどの人にみられないだろう。ブログを更新したときにSNSにリンクを投稿すると良い気もするが、それはそれでSNSの苦手な部分がブログ投稿に侵食してきそうで嫌な感じもする。悩ましい。

2023-03-31

東大の田浦先生が公開されている大規模ソフトウェアを探るがとてもよかった。 GDBを使って大きなソフトウェアの振る舞いを理解する方法を学べる。 2年ほど前に、こういう資料が喉から手が出るほどほしいと感じていた記憶がある。

今日はこのあと研究のことを少し考え、後輩とお酒を飲む。どちらも楽しみだ。

午前中には入社や書類を仕事をした。 Macのターミナルが重い。今まで使っていた研究室のでも重かったし、新しく使い始めたものでも重い。原因を調査中。アプリを起動するのも重いし、コマンド実行が終了してプロンプトが返るまでのレイテンシもある。

GitHub Actionsの実行結果をDiscordに通知

このブログはGitHub Actionsでデプロイしているのだが、ここしばらくデプロイに失敗したことに気が付かずに放置してしまっていた。

Actions Status Discordというアクションをデプロイの最後に叩くことで、いい感じの通知をDiscordにWebhook経由で送れる。

こんな感じに実行条件を指定しないと、デプロイが失敗したときに通知が実行されないことに注意。デフォルトでは if ${{ success() }} が指定されたものとみなされるとのこと。

Hugoのマークダウン処理をカスタム

HTML文書のheading要素の周りにはidがついていてほしいし、それへのリンクは手軽にコピーできて欲しい。その点Googleのドキュメントはとても好き。人に文書コンテンツを渡すときにこちらの意図がURLで表現できるし、そのリンクを踏んだ側も見るべき箇所にスムーズにたどり着ける。このブログを書くのに使っているHugoでも同じことをした。

このコミットのように、headingのHTMLへの変換を定義する

示したコミットではaタグで囲むだけでなく、heading levelを増やしている。 Hugoではタイトルをh1にするにもかかわらず、マークダウンの#h1にする。そのせいで、本文を書くときは##から始める必要があって気持ち悪い。この気持ち悪さを解消するために、マークダウンのheading level+1をhtmlのheading levelとしている。

使い勝手の良いデスクトップ向けウィンドウマネージャが欲しい

使い勝手のよいウィンドウマネージャがWindowsとかMacに搭載されることはないだろう。使うアプリケーションやブラウザ、入力デバイスやその使い方によって使い勝手が大きく変わるだろうから。 OSが決め打ちで提供できるものでは無いんじゃないかと思う。なので自分でまじめに使い勝手の良いものを考える必要がある。

先日オリエンテーリングのインカレの配信のお手伝いをしたのだが、そこで使っていたスイッチャがなかなかデスクトップでのウィンドウマネージャの機能として魅力的に感じた。

スイッチャにはいろんなウィンドウ(カメラからの入力や、図、合成用のテロップなど)が接続されていて、すべてが画面の下部に控えめに表示される。それらを見ながらスイッチャのオペレータが放送するためのウィンドウを選択、合成する。放送されるウィンドウは画面上部に大きく表示される。放送されるウィンドウの右に同じサイズでプレビューウィンドウも表示される。これらの違いは放送されるか否かだけで、合成のテストとかに使える。

これを実現するためには操作用のデバイス(このデバイスをスイッチャというようだ)と、大きなモニタが必要だ。

デスクトップのウィンドウマネージャでもスイッチャのように

  • すべてのウィンドウを表示しておいて
  • 本番+alphaくらいのウィンドウをメインエリアに表示する

と便利な気がする。単純にはいかないだろうけど、いい線行きそうだ。

懸念事項は以下の通り:

  • ウィンドウの個数が多くなりそう
  • ウィンドウサイズが固定ではない(アスペクト比)
  • ウィンドウの動的な生成とその配置方法が非自明

エフェクトハンドラの良さと実用性について

エフェクトハンドラで継続や代数的エフェクトを扱う必要性は一ミリもなくて、実用的にそれらが欲しくなることはないか、あるいは限られていてそこまで一般的な機能を提供する必要はないんじゃないかと感じている。

このあたりを議論するために

  1. エフェクトハンドラの嬉しさ
  2. 意味論の歴史的経緯
  3. 改善ポイント

を考える。

なお、この記事はとくに裏付けもなく書いている。気が向いたら裏付けをしようと思っているが、この記事の目的は僕の考えの整理であって、世に主張をしたいわけではない。

記事の内容は不正確なことを留意されたい。

エフェクトハンドラが実際的 (practical) なプログラミング言語でエンドユーザに使わせたくなるのは

  • エフェクトシステムと相性のよい意味論
  • 動的束縛

を提供したいからではないだろうか。エフェクトハンドラを言語に入れれば、それで表現できる操作は自動的にエフェクトシステムで追跡できるし、ハンドラを用いることでエフェクトをローカルに使えるのは特筆するべきだろう。汎用性とlocal reasoningのしやすさはエフェクトハンドラのもつ良い性質だと思う。

エフェクトハンドラで実現できる動的束縛はとても使い勝手が良い上に、エフェクトシステムで追跡することで使い勝手が上がりそうだ。動的束縛のためだけのエフェクトシステムではなく、もう少し凝ったことができるエフェクトシステムがつくとなお幸せだろうから、エフェクトハンドラみたいな抽象度の比較的高いフレームワークで実現するのは幸せなんじゃないかと感じる。

エフェクトハンドラと呼ばずに “algebraic effects” とか “algebraic effects and handlers” とか呼ぶ流派、時代がある。歴史的には

  • algebraic effects
  • algebraic effects and handlers
  • effect handlers

みたいな流れで登場したはずだ。最初はハンドラはなくて、モナドとかの話をするような人たちが副作用にモナドではない別の表現を与えようとしたんだったか。ここでいうモナドはモナド則とかを真面目に考えるような数学のモナド。代数的エフェクトもその流れの中に(このころは)あったはず。そもそも代数的エフェクトの代数とは、操作が(0だか1こ以上)あって、それらに等式制約を課す。それを満たすようなモデルを持つのが代数 (algebra) である、みたいな世界だっと思う。群とか環は代数だけど、体は代数じゃないみたいな話を聞いたことがある。そういうのりの代数として、エフェクトを表現したらモナドの合成みたいなことを考えるときに幸せだ、という主張がことの発端だった気がする。

ここまでは数学とかモデル理論?とかの話によっていて、あまりプログラミング言語っぽい雰囲気がしない。ハンドラとか継続が入ってきた経緯はしらないが、多分、プログラミング言語に代数的エフェクトを入れるにあたって、モナドのbindやreturnみたいなものを定義するように、エフェクトに意味を与える仕組みとしてハンドラが考えられたんじゃないかと思う。このあたりは論文をまじめに読めば分かるはず。これが確か2014年くらいのこと。

2000年くらいだったかから考えられていたエフェクトシステムとの相性に目をつけたからか知らないが、「代数的エフェクトとハンドラ」を取り入れた言語が2014年ころに登場し始める。2017年くらいにでてくる印象がある。 EffやKokaはこのへんな気がする。このあたりで、エフェクトが代数的であることはとくに気にされなくなっていき、エフェクトシステムと例外ハンドラがうまいこと組み合わさる限定継続演算子くらいの気持ちで代数的エフェクトとそのハンドラが捉えられて、やがて代数的ではないことが気になる人々がエフェクトハンドラと呼ぶようになったのではないかと思っている。

限定継続は本当に必要だろうか。もっとやさしい概念を提供するのにとどめるのはいかがだろうか。ワンショット継続とかに限定する言語もあるが、それは正しい方向性だろうか。

僕たちがほしかったものは、local reasoningしやすいエフェクトシステムとそれで健全に管理できる意味論なんじゃないかと思う。エフェクトハンドラはその条件を満たすけど、もっと使い心地のよい意味論があるはずだと思う。

最後の文をメモしたくてこの記事を書いた。それ以外は文脈である。

Google Cloudの認証を必要とするアプリケーション開発について

Google Cloudの認証・認可はきめ細かくちゃんとしている感じがして、扱うのが難しいと感じていた。少し調べたらApplication Default Credentials with client librariesの説明を見つけて腹に落ちた。これを抑えた上で、それぞれの実行環境でどのようにcredentialをセットアップするかを見ると、プロセスの権限が半分くらいわかる。ここまでで、サービスアカウントがどのようにプロセスに付与されるかを理解できるはずだ。

次に、それぞれのサービスアカウントがどのようなリソースへのアクセスをもつか、それをどうやって設定するかを確認すれば認証・認可を自由に管理できるんじゃないかと思う。How Application Default Credentials worksが良い水先案内に見える。

このあたりは知識がないと本当に挙動がわけわからないので分かりやすいところにドキュメントを置いといたり、積極的にエラーメッセージで教えてほしい。 Google Cloudを使う上での義務教育だと感じた。

Linux (gnome) でよくやる設定

GNOMEというかLinuxというかでよくやる設定を列挙する。キーボード系が多いと思う。

以下を実行

gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ next-tab '<Primary>Tab'
gsettings set org.gnome.Terminal.Legacy.Keybindings:/org/gnome/terminal/legacy/keybindings/ prev-tab '<Primary><Shift>Tab'

参考: https://askubuntu.com/questions/133384/keyboard-shortcut-gnome-terminal-ctrl-tab-and-ctrl-shift-tab-in-12-04

xremapxkeysnailを使うどちらもそんなに使い心地は変わらないと思う。今はxkeysnailを使っている。

課題が2つある:

  • xkeysnailuinputを必要とすること
    • sudoが必要とreadmeに書かれているのはこれが理由
  • xkeysnailをsystemdに登録すること
    • sudoつけられない/等価なことはできない?

以下のように解決する

  1. 必要な権限を自分に与える
    1. sudoなしでxkesynailを実行できるようになる
  2. systemdに登録して、ログインくらいのタイミングで有効にする

これの通りにやればよい: https://github.com/mooz/xkeysnail/issues/64#issuecomment-600380800

  1. 設定ファイルを書く https://github.com/naoyafurudono/configs/blob/main/systemd/user/xkeysnail.service
  2. ~/.config/systemd/user/におく
    1. バイナリをおく: 上の例では~/.local/binにおいてあることを想定している
  3. systemdに登録する: systemctl --user enable --now xkeynail
    1. enableで登録、--nowで今実行

もしうごかなかったらjounalctl -rでsystemdのログをみる。

https://github.com/naoyafurudono/configs/blob/main/mozc/ibus_config.textproto~/.config/mozc/におく。

参考: https://blog.nfurudono.com/posts/mozc-default-engine/

2023-02-27

Gentooが入った。基本的に待っているだけではあるのだけど、それがなかなか大変。パッケージを一瞬でインストールできる幸せに気がついた。割とすぐにUbuntuに戻るかもしれない。今はnodejsとtexliveをコンパイルしている。未だかつてなくCPUが仕事をしている。かわいそうに。とはいえportageに触れるのはなかなか楽しい。

mozcの設定はこのブログのメモに助けられた。過去の自分に感謝。

(追伸) Gentooを入れるためにssdを付け替えたのだけど、そのときにじゃまで外したCPUクーラーがうまくはまっていなかった。このPCはまともな冷却なしでもろもろをビルドしていたのだ。本当にかわいそうなことをしてしまった。ずっとうるさかったのでさっさと気がつくべきだった。今はこれまでがうそのように静か。

軽いドキュメントを印刷するためのツールが欲しい

さくっと書いた文書を印刷したいことがある。ビジネスライクな手紙とか、その日のTODOリストなんかがそうだ。 LaTeXやMadokoを使うのは大げさな感じがして、諦めて手書きするか、Google Docsで済ませることが多い。とはいえ手紙の書き方を毎回調べたり、フォーマットを調整したり、PCで打ち込んだデータを手書きするのはつらい。

テンプレートと変数の宣言、UIの調整と文書のまともな処理をして印刷(A4)できるものが欲しい。A4のPDFに変換できればよい。それぞれの文書のソースはマークダウンのちょっとした拡張くらいの文法で書きたい。エディタで編集したいのでGoogle Docsとかはなしで。テンプレートの作成方法はテキストにこだわらない。いじりやすいと嬉しい。

問題が以下のように分割できるはず。

  • テンプレート作成
  • ソースの文法
    • Markdown拡張
  • テンプレートへのソースの埋め込み
  • PDFへの変換

HTML/CSSやlatexを勉強してMadokoでくっつければなんとかできる気はするが、大変そうだしあまり楽しくない。文書作成ツールを自作するか?とりあえず、HTML/CSSで手紙を表現できるようになるところから始めるのが良さそうか。自作マークダウン拡張(というより処理系)はまれに欲しくなるのでやっても良いだろう。Hugoもそんなに快適じゃないし、Madokoはいじりにくいので。

  • 自分でコードをいじりやすいこと
  • メタな文書処理がしやすいこと
    • 識別子や文書の変数への束縛、正規表現やCFGベースのテキスト置換など
    • この辺はMadokoが強い
  • そういえばMadokoはPDFの生成でHTMLを使わずにlatexを使っていたな…

ここまで来て、Paper CSSという良さげなリポジトリを見つけた。 Qitaでこのライブラリを使って帳票を作る例が解説されている

まだそれぞれをあまり読んでいないのであとで確認する。このあたりの技術に合うように出力することにして、それを生成するマークダウンエンジンを用意すればok?

やはりしんどい気がする。GUIでなんとかする方法を探すのが楽だろうか。あらためて考えよう。

Google Docs APIを利用するのはどうだろうか。 APIはあまりリッチではなくて、create, update, pullができるのみ。文書構造の編集はJSONをごりごりいじることで実現する。JSONスキーマが定義されているので、これを見ながら必要な変換を定義すればよい。

テンプレートをGoogle DocsのGUIで作成して、それをAPIでpullした上で、コンテンツを注入したドキュメントをcreateすれば、やりたかったことを実現できそうだ。テンプレートの置き換え箇所の指定方法はどうするのが良いだろうか。

(開始記号)名前(引数リスト)(終了記号)を文書に埋め込む。これがひとかたまりの文書オブジェクトとして認識されることが必要。また、これにスタイリングを適用した場合、埋め込み後もそのスタイリングが保たれるようにする。引数に他の名前が出現しうることに注意する

テンプレに埋め込むテキストを定義する側では、埋め込み内容の定義リストを作成する:

def name(args: list[str]) -> str:
  return f"""\
ここに置換後の文字列を書く。
ここにも埋め込みの出現を許す。
"""

埋め込み処理では、JSON形式のテンプレのすべてのテキストについてマクロ展開をすればよい。

リブロワークスからCSSで組版するノウハウをまとめた本が5/12に出るらしい。途中までをオフィシャルが公開している。 Vivliostyleというソフトを使って、MarkdownとCSSで書籍を作るらしい。その手のソフトは他にもあるようで、比較サイトを先の書籍で紹介されていた。

こう思うとmadokoはだいぶ良いものだなと感じる。適用範囲を限定した置換とlatexはなかなか強い。 latexとcssを完全に理解すればmadokoが最高かもしれない。

PCの構成メモ

PCを自作して使っているのだけど、どんなパーツを使ったか忘れて後でなにか買い足すときに互換性があるかわからなくてこまる。今回調査してメモしておく。

Ubuntuを入れて使っているけど特に不満はない。不満はないのだが、この間Gentooのことを教えてもらって面白そうなので使ってみようと思っている。

余談だが、このPCは親に就活で必要だろうからといって渡してもらったお金で組んだのだった。自由に使えと言ってもらったが、きっとスーツとかを想定していたのだろう。幸いなことにスーツは買わずに済んでいるので(兄のお下がりがまだ着れる)、ずっと気になっていた自作PCに手を出すのに使ったのだった。少し後ろめたい気持ちがないでもなかったが、Linuxとか触るの楽しいことが分かって仕事でもこの手のものを触りたいと思えたし、面接の話のネタにもなったので結果オーライだろう。学校とか本で学ぶOS周りの技術をそのまま試せるのが僕には嬉しかったのだろう。Windowsでは厳しいし、Macもどこか違っているので。

HugoでタグをつけるためのTips

車輪の再発明ではあるだろうけどメモしておく。archetypes/hugo newで生成する.mdファイルのテンプレを置くことができる。そこにありうるすべてのタグを書いておけば、記事を書くときに関係ないタグを消すことで、関連するタグを忘れずにつけることができる。

僕は以下のようにフロントマターを設定している。

---
title: "TODO"
date: {{ .Date }}
author: "Naoya Furudono"
draft: true
tags: [
    "daily"
    ,"PL"
    ,"tech"
    ,"ubuntu"
    ,"alexa"
    ,"book"
    ,"idea"
    ,"python"
    ,"tool"
]
---

2022-12-30

昔聴いていた音楽を久しぶりに聞きたくなったのだがSpotifyで配信されていなかった。ローカルにデータがあったのでそこからSpotifyかVLCとかで使えるようにしようと思ったのだが、ローカルデータのファイルフォーマットが変だったりディレクトリ構成がイマイチで体験が良くない。

そこでメタデータをもとにフォルダに振り分けたりフォーマットをmp3に変換するスクリプトを書いた。量があったので並列化したところ割といい感じになった。

せっかくなのであとで使いやすいようにCLIを調整した。コードをGitHubにアップロードしてある。 できることや使い方はreadmeを参照すること。

ffmpegはすごいし、Pythonもすごい。

型ヒントに関する記事で欲しい要点がまとまった記事 と出会ったので共有。 Enumはしらなかった。これまではLiteralとUnionでしのいでいたのでありがたい。

最近Pythonを好きになりつつある。4月からキャディで使っていた下地と、最近学んだ人権のための機能のおかげ。

別に職を探しているわけではなく、気になった人のプロフィールを見たかったので。スキルをテストして、パスするとバッジとして自慢できる機能がある。 OOPで試したらパスした。やったね! クラスベースのOOPLに関する知識を見ている感じだった。

世の中にはいろんな機能があるのだなあという感想。自己申告でスキルを履歴書とかに書くよりも客観的な感じがして良いかもしれない。

公開したいと思ってきたのだけど、スパムが嫌でずっと避けてきた。 Base64でエンコードして公開するアイデアを思いついたので試しにやってみる。このブログの自己紹介ページに載せてみた。この方法の問題点は面倒なことと、なれてない人には難しい点だろう。

それなりに頑張らないと収集できないだろうからスパムが来てもどんなところがそんなに頑張ったかを知れて楽しいだろう。

風の噂でこの方法は対策してあるソフトが存在すると聞いた。それではつまらないのでもう少し凝ったことをしてみた (該当コミット)。

Base64でhtmlにアドレスを書いておいて、JSで一定時間後にhtmlに書き込むアイデア。伝えたい人にとって楽になるのが何より良いし、クローラのタイムアウトにある程度期待できるのも良い。無限に対策と不安点は出てきそうなのでこのくらいにしておこう。

実現のためにHugoのショートコード機能を使った。もっと楽しい使いみちがあるようなので気が向いたら導入する。

2022-11-28

AmazonでEchoが安かったので買ってしまった。特に使いみちは考えていなかったのだけど、プログラミングの新しいエントリポイントとして楽しい。

とりあえずハローワールドはできた。設定したフレーズでechoに話しかけると、設定したとおりに会話できる。プログラムが会話を通じて対話的に進行するのが新鮮だ。なかなか便利そう。定型的な記録をとるのには使えるだろう。

プログラムを書くときには発話自体を処理せずに、それをライブラリが処理した結果得られるインテントで実行を分岐させる。ビルトインのものもあるし、開発者が文字列でしていすることもできる。文字列で指定した場合、その聞き取り方?を学習してくれるみたいだ。

ついでにLambdaにも入門してしまった。Functionsの方が使い勝手が良い? pythonの依存ライブラリをrequirements.txtで指定できないのが悲しい。

2022-11-27

タイトルを見たときには、アーキテクチャ的な話が中心なのかと思っていたけど、蓋を開けると、それを構成するための技術を基礎から説明してくれた。たとえばデータベースの種類(関係、ドキュメント、グラフ)とその実例や特性、インデックスのデータ構造の説明、比較など。データベースだけの本でもないけど、そのへんはまだ読んでいないので触れない。

そういう話が終わると、分散システムを考えだす。こういう話の持っていきかたは読者として嬉しいし、文書を書くときに見習いたい。

D2はテキストから図を生成するツールで、マーメイドとかが競合になるようなイメージだろう。企業がオープンソースで開発している。設計思想が良さげ。まだやりたいことをあまりやりきれていないようなので、開発を追いかけたいし、実際に使ってみたい。修論で使えるかな。