先日、SubscribeしているRuby Weeklyからメールが届きました。
何やらRubyでGUIが触れる「glimmer-dsl-libui」たる、とても面白そうなgemが紹介されていました。
このgemは福岡Ruby2022でスペシャルアワードを受賞しており、とても注目されているgemのようです。
GUIを触ろうと思うと、低レイヤーが扱える言語が対象に上がるイメージがありますが、何とRubyでGUIが作れてしまう...というのが驚きです。 どんなgemなのか気になったので少し触ってみました。
gemのインストールのみでGUIが作れる
何よりも驚いたのがglimmer-dsl-libui
のみをインストールすればRubyでGUIを触ることが可能という点です。
だいたい何かしらの低レイヤー言語で実装された依存ライブラリを事前にインストール・アップデートをしないと、こういったライブラリは使えない認識ですが、事前準備は特に不要とのこと...。
githubのREADME.mdを参考に簡単なサンプルを動かしてみます。
Gemfileを更新してbundle install
を行っただけの状態ですが、果たして問題なく動くのでしょうか...。
# frozen_string_literal: true source "https://rubygems.org" gem 'glimmer-dsl-libui', '~> 0.10.2'
require 'glimmer-dsl-libui' include Glimmer window('hello world', 300, 200) { button('Button') { on_clicked do puts 'Button Clicked' end } }.show
おぉ、何か出ましたよ。ウィンドウ(300x200)にButtonと表示されたボタンが描画されています。
先のサンプルコードの通り、GUIが構成されています。
コードを見る感じ、ボタンのクリック時にハンドラーが仕込まれているようなので、ボタンをクリックしてみます。
おそらく、コンソール上に「Button Clicked」と表示されるはずです。
$ bundle exec ruby main.rb # ボタンを押下後... Button Clicked
思った通りです。各要素にハンドラーを仕込んでRubyの処理を実行させることも可能でした。
もう少し複雑なサンプルも記載されていたので、そちらも動作させてみます。個人情報を登録・検索可能な簡易なアプリケーションのようです。
コード量が多いため、コード転載は割愛します。
おぉ、先ほどのサンプルと比べるとかなりリッチなGUIが描画されました。
軽く触ってみたところ、データの追加・検索も問題なく動いていました。これは凄いですね。他にもテトリスやスネークゲームといったサンプルまで紹介されており、このgemの可能性を感じます。
どうやって作っているのか
RubyでどのようにGUIが触れるように実現しているのでしょうか。
ピュアなRubyだけでは実装が難しいように思えます。gemの依存関係を調べていくと「libui」というC言語で実装されたGUIライブラリに辿り着きました。
このライブラリ自体がさまざまな言語で使用可能なように、各言語用のライブラリを提供していました。
Ruby用のライブラリも存在しておりglimmer-dsl-libui
は、Ruby用のライブラリをgemとしてインストールして内部で使用しているようです。
となると、どこかでC言語で実装されているlibui
をRuby側で読み込んでいる箇所があるはずです。
先ほどのライブラリのソースコードを追ってみると、該当のコードを発見することができました。
lib/libui/ffi.rb
begin dlload LibUI.ffi_lib rescue LoadError raise LoadError, 'Could not find libui shared library' end
LibUI/lib/libui/ffi.rb at main · kojix2/LibUI · GitHub
あまり、見慣れない構文ですがdlload
というメソッドを使うことで、C言語のライブラリをインポートすることができるんですね。今まで全く使う機会がなかったです...。
require 'fiddle/import' module Sample extend Fiddle::Importer dlload "/usr/lib/libc.dylib" extern "int printf(char*, ...)", :printf, :varargs end Sample.printf("Hello world! from Ruby!\n") # Hello world! from Ruby!
Fiddle::Importer#dlload (Ruby 3.2 リファレンスマニュアル)
最後に
Ruby Weeklyにて紹介されていたglimmer-dsl-libui
を試してみました。
まずRubyでGUIが触れるというのに驚かされました。デスクトップアプリを作るならElectron一択かな...と思っていたのですが、Rubyでも作れる可能性があると考えるだけでワクワクします。
文法もSwiftUIのようで、非常に可読性が良いと感じました。
実装の中身についても非常に面白かったです。
C言語でGUIの基本的な処理をライブラリ化して、それらをRubyから使用すれば、確かにOSのグラフィックAPIを使用することが可能です。
ただ直接、Rubyから呼び出すのは難しいという壁を感じつつ、Ruby向けにライブラリ化してくれている方には頭が上がりません...。
少しでも「ええな〜」と思ったらはてなスター・はてなブックマーク・シェアを頂けると励みになります。