はじめに
アドベントカレンダーのネタがいよいよありません。
3週間ぐらい前に、小さなCrystalのShardを作ったことを思い出しました。これの紹介をまだQiitaに書いてなかったと思うので書きます。
easyclip
マルチプラットフォーム(Linux, Mac, Win) でクリップボードをCrystalから扱うライブラリです。といっても、難しいことは一切しておらず、極めて安直な実装になっています。
使うときは shard.yml
を書いて
dependencies:
easyclip:
github: kojix2/easyclip
shards install
を実行してください。すると、こんな感じで動きます。
require "easyclip"
# テキストをクリップボードにコピーする
EasyClip.copy("たぬき")
# クリップボードのテキストを取り出す
str = EasyClip.paste
puts str
# => たぬき
実装は…
こんな感じで、OSごとに指定のコマンドを用意して、標準入出力を使ってコピーまたはペーストしているだけです。
private def copy_command
{% if flag?(:darwin) %}
"pbcopy"
{% elsif flag?(:unix) %}
"xsel -ib"
{% elsif flag?(:win32) %}
"clip"
{% end %}
end
private def paste_command
{% if flag?(:darwin) %}
"pbpaste"
{% elsif flag?(:unix) %}
"xsel -ob"
{% elsif flag?(:win32) %}
"powershell.exe -command Get-Clipboard"
{% end %}
end
予想通りでしたか?
さらに細かいコードはこちらから見てください。
なお、Windows は clip.exe
の仕様のため、どうしてもコピーした文字列に改行コードが入ります。
安直な実装はよくないか
上記の実装をみて、「なんだよー。こんなことかよ…。」って思ったかもしれません。
しかし、自分で言うのもなんですが、こういった安直な実装は意外とバカにならないと思うんですよね。OSのAPIなどを使って、きちんとしたライブラリを作る人はすごいと思いますが、今回のような安直な実装であれば、少ない行数で実装できる上に、当分はメンテナンスフリーで動き続けるはずです。Crystal言語のようなマイナー言語を使う場合は、メンテナンスのコストは特に減らす必要があり、こういった格好悪いけど、壊れにくいタイプの実装もありではないかと思います。
Process がやや使いづらい
あと、こんな簡単な実装でもわりと罠にはまると完成には時間がかかったりします。Crystalの標準ライブラリの Process
の仕様が使いにくいところがあり、ドキュメントを見てもわからずソースコードを当たったりしました。マイナー言語のつらいところです。
Crystalのライブラリは壊れやすいか?
これは少し物議を呼ぶ発言かもしれませんが、Crystalは自作のツールに他人が作ったライブラリを導入するハードルがRubyよりも高いと感じます。その理由として、Shardは不具合を起こすことが多いように感じます。RubyのGemと比較すると、CrystalのShardは寿命が短いのではないでしょうか。
もちろんその理由として、Crystalが若い言語であり、1.0以前は仕様の変更が多かったこと、ユーザーが少ないためバグに目が届かないこと、結果的にメンテナンスが継続的ではないことが大きいと思います。
しかし、静的型付け言語の型の許容性の低さも、Shardの寿命の短さと無関係ではないでしょう。Rubyの場合は、10年前に放置されたライブラリであってもそれなりに動作することは少なくありません。しかし数年前に作成されて放置されたCrystalのライブラリが動く確率はかなり低いと思います。型がずれるとすぐ動かなくなるのはバグの発見を容易にしますが、一方で過去の放置資産を使うことを難しくしており、エコシステムの拡大を阻害している一つの要素であると僕は思っています。
こういったことがあるので、私は「Crystalは静的型なのでRubyよりも優れている」という立場を私は採用していません。Crystalの動的な性質が好きです。
この記事は以上です。