ジェットストリームプライムを試してみた

仕事や勉強などで物理ノートを使っているのですが、筆記具としてボールペンはジェットストリームの3色ボールペンを長らく愛用しています。ジェットストリームにはプライムというお値段高めの上位機種が存在するのですが、なんか変な宝石みたいのが付いてていまいち食指が動かなかったのですが、今年になってデザインが良い感じにリニューアルされたのでボールペンもちょっと良いものを使ってみようかと思い購入してみました。

数ヶ月使ってみての感想ですが、

  • デザインは良く、金属の重量感やマット塗装も相まって高級感はある
  • 通常の3色ジェットストリームと比べるとスリム
  • 通常のジェットストリームと違って持ち手部分がラバーではなく金属製なので長時間使っていると手が痛くなる
  • 重量はあるが重心は低いので重くて書きにくいということはない
  • 替芯が専用のもので値段が高い。芯が透明ではないのでインクの残量がわからない
  • クリップが金属製なのは耐久性という意味では良いが固すぎる気がする

などなど、確かに高級感はあるのですが、実用性という意味では結構微妙な気も…。ベージュのモデルは塗装が異なるようなのでまた少し使い勝手が違うかもしれません。

また、プライムまではいかないのですが、通常のジェットストリームと比べると若干お値段高めの中位機種もあります。

こちらも実際に購入してしばらく使ってみました。

  • 見た目の高級感やマットな手触りなどはプライムに近いものがあるが金属製ではないので軽量
  • プライムと違ってスリム筐体ではないがラックのノックがクリップに割り当てられているので通常の3色モデルと比べるとスッキリしている
  • やはりノック(特にクリップに割り当てられたブラック)が特殊で慣れないとうまく固定できないことがある
  • 持ち手部分はラバーなので長時間使っても指が痛くならない
  • 芯は普通の多色ジェットストリームと同じものが使えるのでランニングコストはいい

というわけで色々試してはみたものの、なんだかんだで今まで使っていたスタンダードな三色モデルが一番使いやすいのではという身も蓋もない結論に達してしまいました!

安いので雑に扱っても気が咎めないし、壊れたり失くしたりしても買い換えればいいかという気になりますし…。本体、替芯ともにスーパーの文房具売り場などでも比較的入手しやすいのも実用性高いです。とはいえジェットストリームは様々なバリエーションがありますし、コラボでいろんなデザインの筐体を限定で出したりしてるので、自分好みのモデルを見つけたら芯を交換して使い続けられるのはいいところですね。

今回はボールペンについてでしたが、仕事で使う文房具に関してはノートや付箋なども色々と試しているので、また機会があれば書いてみたいと思います。

(2024年2月 追記)ジェットストリームプライムをその後数年使っているのですが、以下のような点もネガティブに感じています。

  • インクの容量が少ないせいか割と頻繁に芯の交換が必要
  • 金属ボディ+塗装なので雑に扱っていると塗装が剥げてしまう
  • ブラックカラーのマット塗装は皮脂などが付くと目立つ

特に塗装剥げについては自宅のデスクでペン立てに他のペンや文房具と一緒に立てていて特に乱暴に扱っていたわけではないのですが、それでも気づいたら細かい塗装剥げがあちこちにできてしまっていました。ペンケースなどに入れて持ち運んでいたりするともっと目立つ塗装剥げができてしまうのではないかと思います。スタイリッシュで高級感もあるのですが、やはり普段使いには向かないなぁという印象です。

GitBucket 4.36.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.36.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.36.0

リポジトリビューアでのタグ選択

リポジトリビューアのブランチ選択用プルダウンでタグを選択することもできるようになりました。

f:id:takezoe:20210717231624p:plain

リポジトリのIssue/Pull Requestへのリンク

これまでもマークダウン内での#123のような記述はリポジトリ内のIssue/Pull Requestへのリンクとしてレンダリングされていましたが、これに加えてuser/repo#123のような記述で別リポジトリのIssue/Pull Requestへのリンクを生成できるようになりました。

f:id:takezoe:20210717231641p:plain

差分ビューのファイル、行へのリンク

差分ビューで各ファイル、行にリンク用の識別子が生成されるようになりました。以下のようにしてリンクすることができます。

f:id:takezoe:20210717231654p:plain

f:id:takezoe:20210717231713p:plain

XSSプロテクション無効化オプションを追加

リポジトリビューアではXSS防止のため特定の種類のファイルは描画しないようになっていますが、この挙動をリポジトリのオプションで変更できるようになりました。このオプションはGitリポジトリに格納されているこれらのファイルをHTML等に貼り付けたい場合に利用できますが、公開リポジトリでは有効にしないよう注意してください。

f:id:takezoe:20210717231733p:plain

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

trino-client-ruby 1.0.0をリリースしました

トレジャーデータが公開しているOSSの1つにpresto-client-rubyというRuby用のPrestoクライアントライブラリがあり、最近色々と弄る機会が増えてきたのでメンテナにしていただいたのですが、PrestoSQLがTrinoのリブランディングされ通信の仕様も若干変わったため、Trino対応させるとともにtrino-client-rubyに改名し、バージョンも1.0.0としてリリースし直しました。

github.com

PrestoはレスポンスのJSONの形式がバージョンによって若干異なるため、presto-client-rubyではmodel_versionというオプションで使用するPrestoのモデルを指定できるようになっているのですが、このオプションで351以前のバージョンを指定するとPrestoモードで動作するようになっています。デフォルトではTrinoモードで動作します。

client = Trino::Client.new(
  server: "localhost:8880",
  ssl: {verify: false},
  catalog: "native",
  schema: "default",
  ...
  model_version: "316" # Works in Presto mode
)

ただ、model_versionオプションは必ずしも対象のPrestoのバージョンをそのまま指定すればよいというわけではなく、ちょっとわかりにくい部分もあるのでクライアントのインスタンス生成時にPresto/Trinoのバージョンを確認しに行って自動で判定するようにしてもいいかもしれないと思っています。

今後も改善できる点があれば引き続きメンテしていきたいと思います。

Programming in Scala Fifth Edition

以前アーリーアクセスで購入して手をつけていなかったScala3対応のProgramming in Scala Fifth Edition、ようやく完成したようなので最近発売されたForth Editionの日本語版と見比べながらざっと目を通してみました。

Scala言語の入門書としては以前よりもだいぶ整理されて真っ当な作りになっていると思います。すでに標準ライブラリから外れて久しいXML、パーサコンビネーター、Swingはもちろん、存在がいまいち謎だった最後のスプレッドシートの章もまるっと削除されていますし、既存の章の順番も見直されています。元々Programming in Scalaの構成はだいぶ謎な気がしていたので、今回Scala3へのアップデートにあわせて一新されたのはよかったのではないかと思います。

個人的にはJavaとの相互運用やFutureの章が削除されてしまったのは残念かなと思うのと、この書籍の出自を考えると仕方ない気もするのですが、assertはともかくテストについては要らないんじゃないかなぁとは思いました。それまで全くsbtに触れてないのに突然sbtの設定とか出てくるし…。

また、サンプルコードが全編Scala3で新たに導入されたインデント構文(quiet syntax)になっており、Scala2と一切互換性がないという点はかなり気になりました。Scala3の新機能は一応それとわかるように書かれているのですが、逆にScala3で廃止された機能については特に明記されていません。つまり、本書はScala3から新たにScalaを始める人向けの書籍であるということです。

すでにScala2をバリバリ使いこなしている人はこの本を読まなくてもScala3に追従するためのリソースはオンラインで入手できると思うのでいいとして、これからScalaを学習するという人のうち、このタイミングでScala3で学習し始めて、Scala2は一切触らないという人が一体どれだけいるのか…。数年後、Scala業界の大半がScala3に移行した後であればよいと思うのですが、今入門書として読むのは結構微妙かもという気がしました。

世の中的にScala3への移行はなかなか一筋縄ではいかなそうな気がしていますし、正直脱落する個人や企業も出てくるのではと思っているのですが、特に新規参入者の方がこの本で混乱してしまわないことを祈るばかりです。

その他のScala3対応書籍

オライリーのProgramming ScalaもScala3対応にアップデートされているようなのですが、こちらはどんな感じなのでしょうか。目次を見ると一応Scala2からScala3へのマイグレーションについての記述があるようですし、型クラスについてもScala2とScala3双方での解説があるようなので、今読むのであればこちらの方がいいかもしれません。

日本語でのScala入門書

さて、日本では先日Forth Editionの翻訳版が発売されました。何気なく書籍情報を眺めていたら監訳者に前職の同僚氏が!これはお布施せねば!ということで早速クリックしました。こちらはScala 2.13対応ですが、まだまだ現場では当面Scala2が主流で使われると思われるので、今Scalaを学習するのであればこちらもオススメです。

日本語だと技評さんの実践Scala入門も実用的でいいですね。

Trino/Prestoの互換性調査補助ツールを作った

Trino/Prestoをバージョンアップする際には事前に動作の互換性検証などを行なっているのですが、検証作業自体は以前Presto Conference Tokyo 2020でも紹介させていただいたquery-simulatorという内製のツールを使って自動化されているものの、実際に非互換の挙動を発見した後の原因調査(原因のコミットを特定してバグかどうかの判断をする)については引き続き地道な作業が必要な状態でした。

Trino/Pretsoは開発が非常にアクティブで、1回のリリースに数百のコミットが含まれます。1年程度バージョンアップを怠っているだけでも変更が巨大すぎてコードの変更履歴から原因を特定するのは非常に困難になります。そこで、まずは複数バージョンのTrino/Prestoでクエリの実行結果を比較することで変更が導入されたバージョンを特定し、その後、そのバージョンのコミットの中から原因となったコミットを調査するという作業を行なうことになるわけですが、このうちバージョンを特定する部分の作業は自動化できそうということでツールを作ってみました。

github.com

まだ、きちんとしたインターフェースを作っていないのでScalaコードを書いて実行する必要があるのですが、以下のようなコードで指定した範囲のバージョンのTrino/Prestoをdockerで起動し、クエリの実行結果を比較しつつ二分探索で変更が導入されたバージョンを自動的に検出してくれます。

import io.github.takezoe.trino.checker._

val checker = new BinaryVersionChecker(new DockerQueryRunner())
val results = checker.check(Range.inclusive(317, 350), "SELECT null GROUP BY 1, 1")
printResults(results)

実行結果はこんな感じになります。このケースでは339が変更が導入されたバージョンということになります。

✅ 317: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 350: Left(java.sql.SQLException: Query failed (#20210526_154140_00004_yzz4q): Multiple entries with same key: @38f546e: null=expr and @38f546e: null=expr)
✅ 334: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 342: Left(java.sql.SQLException: Query failed (#20210526_154251_00003_2km75): Multiple entries with same key: @63f11e0f: null=expr and @63f11e0f: null=expr)
✅ 338: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 340: Left(java.sql.SQLException: Query failed (#20210526_154338_00002_2xtvz): Multiple entries with same key: @76615946: null=expr and @76615946: null=expr)
❌ 339: Left(java.sql.SQLException: Query failed (#20210526_154358_00002_jdnni): Multiple entries with same key: @4aca599d: null=expr and @4aca599d: null=expr)

本当はコミットを特定するところまで自動化できると楽なのですが、バージョンを絞り込めばコミット履歴からあたりがつくこともありますし、実際に動かして動作確認するにしてもTrino/Prestoをソースからビルドする必要があるのでIDE上で実行したほうが早いかなという感じです。ニッチなツールなのでさほど頻繁に利用する機会はないかもしれませんが、こういった簡単なツールでも作業の効率化に役立つので、もっと早く作っておけばよかったなぁと思っています。

ユニコーン企業のひみつ ―Spotifyで学んだソフトウェアづくりと働き方

話題のユニコーン企業本を早速読んでみました。分量もそれほどでもありませんし、日本語なので1日で読み切ることができました(翻訳ありがたい)。

内容については散々色んなところで書かれていますので今更ここで書くこともないかと思いますが、この本に書かれている内容はあくまで成功したテック企業のひとつの事例として捉える必要があるかと思います。

ソフトウェア開発プロジェクトの方法論であるアジャイルと比べ、エンジニア組織論はスコープが広く影響を及ぼす要素が多い割にサンプル数が少なく、本来はなかなか一般化して語ることの難しい領域だと思います。その割にこの書籍では(話をわかりやすくするために敢えてやっているのだと思いますが)大企業×スタートアップという二元論的な書き方や、「エンタープライズ」「ユニコーン」「テック企業」など言葉のチョイスからして煽り気味なところもあり、読者層によっては誤った受け止められ方をされ兼ねないと感じました。

エンジニア組織の話については思うところが多々あるのですが、ありすぎてこれ以上の感想をここで書くことはできそうにありません。また、こういった話題からは当面距離を置いてソフトウェアエンジニアリングに集中したいという個人的なモチベーションもあり、今のタイミングでこの本を読んだのは失敗だったかもしれないという気持ちもあります。良い本だとは思うのですが、残念ながら自分はピュアな気持ちで読むことができなかったです。

仕事ではじめる機械学習 第2版

トレジャーデータでの同僚である@chezouさんが著者に名を連ね、名著と名高い「仕事ではじめる機械学習」。恥ずかしながら第1版は読んでいなかったのですが改訂版が出たとのことでGW休暇中に読んでみました。

仕事ではじめる機械学習 第2版

仕事ではじめる機械学習 第2版

噂通りの名著というか怪著ですw タイトルの通り、機械学習アルゴリズムだけでなく、学習結果の評価方法やデータの集め方、システム構成やモニタリングなど運用にあたって留意すべきことなど「業務として」機械学習に取り組みにあたって留意すべき事項が書かれています。果ては機械学習の導入にあたっての立ち回り方など割と身も蓋もない(けれども実際のところ重要な)ことまで堂々と書かれていて、日本ならではの面もあるかもしれませんが、オライリーからこんな本が出せるのかと感動すら覚えてしまいました。

第1版は読んでいないので正確な差分はわからないのですが、この第2版ではML Ops機械学習モデルの検証、バンディットアルゴリズム、オンライン広告での機械学習といった章が新規に書き起こされているようです。ML Opsの章に関してはこの書籍でも書かれている通り、なかなかこれを使っておけばOKというものがなく(クラウドサービスが提供するサービスはガバナンス上の問題で使いにくかったり、OSSのものは既存インフラとの連携面で問題があったり等々…)内製してしまうパターンも多いのではないかと思いますが、今後この分野がどのように発展・定着していくかは興味深いところです。

全編通して著者の方々の知見に満ち溢れており、現場でのご苦労が偲ばれると共に読み物としても面白いので、業務で機械学習に関わりのないソフトウェアエンジニアの方が読んでも面白いのではないかと思います。今のところ日本語でしか読めない書籍ですので、日本人であることに感謝しつつ読ませていただきました。