goでpkgパッケージを作りたくなる派の意見
個人的にはpkgパッケージを作ることにわりと肯定的な立場なので思ったことをメモしておくよ。
pkgパッケージが作られる理由
pkgパッケージを作りたいと思う理由は以下だよ。
- pkgパッケージはmonorepoの小さい版と解釈すると納得できる
- 公開されたパッケージのAPIは変更しづらいがメンテし続けなくてはいけない(破壊的な変更を好まない人々の目に触れることになる)
- internalでは全然ダメ。公開を意図してパッケージを作りたい
OSSプロジェクトで見つかるpkgパッケージの理由は真ん中の理由が主かもしれない。有名な組織の下のコードだとこなれてない段階でも依存したがる人が一定数存在していそうだし。
典型的な作成例
一方OSS関係なく自分たちのコードでpkgパッケージを作りたいと思うこともあるよ。そのようなときの典型的なpkgパッケージの内訳は以下だよ(もちろんこれらはサブパッケージだよ)。
- 状態を持った生成系(e.g. 乱数, 現在時刻)
- ロガー
- 文字列 -> オブジェクト (e.g. time.Time)
application code? library (pkg)? application library (apppkg)?
場合によってはsessionIDなどを良い感じにロガーに渡すなど、アプリと自分たちの組織の慣習やインフラとが密に結びついたパッケージをapppkg的な感じで切ることもあるよ(pkg,apppkgが存在する)。
ただしこのapppkgが最終的な良い位置だとは思わないよ。すわりの悪い位置だなーということはメンバー内で納得している必要があるよ。
どうしてアプリのコードではないの?というと、アプリが複数あることもあるからだよ。
そもそもなんでpkgパッケージの要・不要が分かれるの?
作成するものがツール派とアプリ派に分かれるからだよ
ツールとは
アプリとは
- いろんなことが何でもできる
- ユーザーは非開発者
- 仕様を内部で良い感じにハンドリングする必要がある
- UIや分岐はユーザーのinputに依存する
基本的にはgoはツールの方が得意だよ。でも現在頑張ってアプリに手をかけようとしている最中という認識だよ(これはアプリ開発者の疲弊とgo2.0の新機能がどこに向いているかに対する自分の認識だよ)。
まとめ
pkgパッケージはmonorepoでgoはelmだよ。
python3.8 meets jqfpy
最近手元の環境のpythonのバージョンが3.8になった(雑に yay -Syu
をやっていた結果1)。
そう言えば、python3.8ではセイウチ演算子で知られるassignment expressionsが入ったので、jqに疲れたpythonistaのためという触れ込みで昔作っていたパッケージがもう少し便利になるかもしれない。
これ。
jqfpy?
このブログでも幾つか紹介していたっけ?
..していた模様。
ユースケースを網羅しているわけではないけれど。おそらく最初の記事を読めば雰囲気は分かるはず。
使いかた
get()
で取り出したあとは内包表記のワンライナーというのが基本的な使いかた。--slurp
や--compact
や--squash
などで少しだけ入出力を整形できる。あとしれっとyamlにも対応しているのでyqなどの代わりにもなるかもしれない。
$ seq 1 10 | jqfpy --slurp -c [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] $ seq 1 10 | jqfpy --slurp -c '[int(n) * int(n) for n in get()]' [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
python3.8 meets jqfpy
jqfpy上での操作は基本ワンライナーなので、ワンライナーの表現力をあげるセイウチ演算子と相性が良い。
$ seq 1 10 | jqfpy --slurp -c '[(n := int(x)) * n for x in get()]'
ちょっとこの例はあんまり良くないかもしれない。一番わかり易い例は正規表現などを使った簡易grepのようなもの。なのだけれど。。
正規表現でマッチした結果を使って変換
これからあげる例はかなりトリビアルなのでごめんなさい。。
テキトウに文字列が欲しい。import this
でzen of python辺りを入力にするか。
そのうちのIf
で始まるものだけを取り出す。
$ python -m this | grep -i -P "^if" If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea.
このうちifにマッチしたもののうち,
部分より手前の文字列を強調表示してみたいということにする。ちょっと無茶な例だけれど。してみたいとする。
強調後の表現は ** <matched text> **
みたいな形で表示されて入れば良いことにしよう。今までこのようなマッチ結果を利用した変換が混ざったコードはjqfpy上で書くのは辛かった。
python -m this | jqfpy --slurp 'import re; rx = re.compile(r"^if.*,", re.IGNORECASE); [line.replace(m.group(0), f"** {m.group(0)} **") for line in get() if (m := rx.search(line)) is not None]' -i raw --squash -r ** If the implementation is hard to explain, ** it's a bad idea. ** If the implementation is easy to explain, ** it may be a good idea.
:tada: できるようになりました。おしまい。というのが今回の記事。おしまい。
さいごに
jqfpyの中では、元々 ";" が改行として扱われるので、python上の便利モジュールをimportして丸投げくらいはできたのだけれど、さすがに内包表記中での評価結果を利用して変換みたいな事は今までやりづらかった。
python3.8が普段遣いになったので、もう少しjqfpyの表現の幅も広がったかもしれない。
-
Arch Linuxというやつです https://www.archlinux.org/↩