チュートリアル
このチュートリアルでは、Konpeito のインストールから実際のコードを動かすところまでを一通り体験します。
1. インストール
前提条件
| 依存 | バージョン | 用途 |
|---|---|---|
| Ruby | 4.0.1+ | 必須(コンパイラ本体の実行) |
| LLVM | 20 | CRuby ネイティブバックエンド、mruby バックエンド |
| Java | 21+ | JVM バックエンド |
| mruby | 3.x or 4.x | mruby バックエンド |
LLVM、Java、mruby は使うバックエンドに応じて必要になります。いずれか1つだけでも動きます。
Konpeito のインストール
gem install konpeito
LLVM 20 のインストール(CRuby バックエンド用)
macOS:
brew install llvm@20
ln -sf /opt/homebrew/opt/llvm@20/lib/libLLVM-20.dylib /opt/homebrew/lib/
gem install ruby-llvm
Ubuntu / Debian:
sudo apt install llvm-20 clang-20
gem install ruby-llvm
Fedora:
sudo dnf install llvm20 clang20
gem install ruby-llvm
Java 21 のインストール(JVM バックエンド用)
macOS:
brew install openjdk@21
Ubuntu / Debian:
sudo apt install openjdk-21-jdk
Fedora:
sudo dnf install java-21-openjdk-devel
環境チェック
konpeito doctor # CRuby バックエンドを確認
konpeito doctor --target jvm # JVM バックエンドを確認
必要なツールがすべてインストールされていれば、緑のチェックマークが表示されます。以下の2つの WARNING は正常なので無視して構いません:
- ASM tool: WARNING — JVM バックエンド用のバイトコードアセンブラです。初回の JVM ビルド時に自動でビルドされるため、事前の対応は不要です。
- Config: WARNING — カレントディレクトリに
konpeito.tomlが見つからないという意味です。プロジェクトをまだ作成していない場合は正常です。konpeito initで作成するか、ソースファイルを直接konpeito buildに渡せば問題ありません。
2. Hello World
CRuby バックエンド(ネイティブ拡張)
# hello.rb
module Hello
def self.greet(name)
"Hello, #{name}!"
end
end
konpeito build hello.rb # → hello.bundle (macOS) / hello.so (Linux)
Ruby から使う:
require_relative "hello"
puts Hello.greet("World") # => "Hello, World!"
コンパイルされた拡張は標準の CRuby C 拡張です。C で書かれた gem と同じように、どの Ruby プロセスからでもロードできます。モジュールで囲むことでトップレベルの名前空間を汚さないようにします — 拡張ライブラリではこのパターンが推奨です。
JVM バックエンド(スタンドアロン JAR)
# hello_jvm.rb
puts "Hello from Konpeito!"
konpeito build --target jvm --run hello_jvm.rb
初回ビルド時は “Building ASM tool” というメッセージが出ます。これは一度きりのセットアップです。
出力例:
Compiling hello_jvm.rb (jvm)
Building ASM tool (first-time setup)...
ASM tool ready.
Running: java -jar hello_jvm.jar
Hello from Konpeito!
Finished in 0.9s -> hello_jvm.jar (36 KB)
生成された JAR はスタンドアロン — 実行マシンに Ruby は不要です。
3. Konpeito の仕組み
Konpeito がコードをコンパイルするとき、各操作は2つのカテゴリに分類されます:
- ネイティブ — コンパイラが型を解決し、ネイティブ CPU 命令(例: LLVM:
add i64,fadd double,getelementptr)または型付き JVM バイトコード(例:iadd,dadd)を出力。Ruby のメソッド探索オーバーヘッドなし。 - 動的フォールバック — 型が特定できない場合、
rb_funcallv(LLVM)またはinvokedynamic(JVM)にフォールバック。通常の Ruby と同じ速度で動作。コンパイラが警告を出すので、どこが境界かわかります。
RBS 型注釈を追加すると、動的フォールバックをネイティブディスパッチに昇格できます。速度が不要な箇所はそのままにしても問題ありません。
Gem とランタイム依存
require "some_gem" を書いた場合:
- ロードパス上にある場合(
-Iで指定) — gem のソースも一緒にコンパイルされ、直接ディスパッチ・単相化・インライン化が適用されます。 - ロードパス上にない場合 —
rb_require("some_gem")が発行され、CRuby が実行時にロード。動的ディスパッチ経由ですが正しく動作します。
4. CRuby バックエンド: 実用例
パターン1: 拡張ライブラリ
計算集約的な関数だけコンパイルし、通常の Ruby アプリから require して使うパターンです。
ステップ1: コードを書く
# physics.rb
module Physics
def self.distance(x1, y1, x2, y2)
dx = x2 - x1
dy = y2 - y1
dx * dx + dy * dy
end
def self.sum_distances(xs, ys, n)
total = 0.0
i = 0
while i < n - 1
total = total + distance(xs[i], ys[i], xs[i + 1], ys[i + 1])
i = i + 1
end
total
end
end
ステップ2: RBS で型を明示する(任意)
RBS がなくても HM 推論で型は解決されますが、明示すればより強い最適化が効きます。
方法A: インライン RBS(手軽でおすすめ)
rbs-inline コメントで、Ruby ソース内に直接型注釈を書けます:
# physics.rb
# rbs_inline: enabled
module Physics
#: (Float x1, Float y1, Float x2, Float y2) -> Float
def self.distance(x1, y1, x2, y2)
dx = x2 - x1
dy = y2 - y1
dx * dx + dy * dy
end
#: (Array[Float] xs, Array[Float] ys, Integer n) -> Float
def self.sum_distances(xs, ys, n)
total = 0.0
i = 0
while i < n - 1
total = total + distance(xs[i], ys[i], xs[i + 1], ys[i + 1])
i = i + 1
end
total
end
end
方法B: 別ファイルの RBS
# physics.rbs
module Physics
def self.distance: (Float x1, Float y1, Float x2, Float y2) -> Float
def self.sum_distances: (Array[Float] xs, Array[Float] ys, Integer n) -> Float
end
ステップ3: コンパイル
# インライン RBS の場合(方法A)
konpeito build --inline physics.rb
# 別ファイル RBS の場合(方法B)
konpeito build physics.rb
-v をつけると、推論された型と動的フォールバック箇所が表示されます:
konpeito build -v physics.rb
ステップ4: Ruby から使う
# app.rb — 通常の Ruby(Konpeito ではコンパイルしない)
require_relative "physics"
xs = Array.new(10000) { rand }
ys = Array.new(10000) { rand }
puts Physics.sum_distances(xs, ys, 10000)
ruby app.rb
ネイティブになる部分: distance は完全にネイティブ — dx * dx + dy * dy は fmul double + fadd double 命令に変換。sum_distances の while ループもネイティブカウンターループです。
動的フォールバックになる部分: xs[i] は Ruby Array への rb_funcallv 呼び出し(Array は CRuby オブジェクト)。ここもネイティブにしたい場合は NativeArray[Float] を使います:
NativeArray で完全ネイティブ化
NativeArray[Float] は unboxed の double 値を連続メモリに格納します。配列要素アクセスは getelementptr + load に直接変換され、メソッドディスパッチは一切発生しません。
ローカル NativeArray(関数スコープ)
NativeArray は Konpeito 固有の型なので、生成・使用するコードも Konpeito でコンパイルする必要があります。NativeArray の作成・アクセスは同じ関数スコープ内にまとめます:
# physics_native.rb
# rbs_inline: enabled
module Physics
#: (Float, Float, Float, Float) -> Float
def self.distance(x1, y1, x2, y2)
dx = x2 - x1
dy = y2 - y1
dx * dx + dy * dy
end
def self.run
n = 10000
xs = NativeArray.new(n)
ys = NativeArray.new(n)
i = 0
while i < n
xs[i] = i * 0.0001
ys[i] = i * 0.0002
i = i + 1
end
total = 0.0
i = 0
while i < n - 1
total = total + distance(xs[i], ys[i], xs[i + 1], ys[i + 1])
i = i + 1
end
puts total
end
end
Physics.run
konpeito run physics_native.rb
ヒント:
konpeito runはコンパイル済みアーティファクトを.konpeito_cache/run/にキャッシュします。ソースファイルやRBSファイルが変更されていなければ、再コンパイルはスキップされます。--no-cacheで強制再コンパイル、--clean-run-cacheでキャッシュクリアが可能です。
注意: 同じディレクトリに
physics_native.rbとphysics_native.bundleの両方が存在する場合、require "./physics_native"は.rbソースファイルを先にロードします。konpeito runはロードパスを自動的に処理するため、この問題を回避できます。ビルドと実行を分けたい場合は、出力先を別ディレクトリにしてください:konpeito build -o build/physics_native.bundle physics_native.rb ruby -r ./build/physics_native -e ""
重要: ローカル NativeArray はスタック上に確保されるポインタであり、CRuby のメソッドディスパッチ経由で他の関数に引数として渡すことはできません。ローカル NativeArray は必ず同じ関数スコープ内で作成・使用してください。関数をまたいで共有したい場合は、モジュール NativeArray を使ってください。
これで xs[i] と ys[i] もネイティブになり、ループ全体が Ruby のメソッドディスパッチを経由せずに実行されます。
モジュール NativeArray(グローバル、関数間共有)
ゲームの状態やシミュレーションデータなど、複数の関数からアクセスする配列は、RBS でモジュールのインスタンス変数として固定サイズの NativeArray を宣言できます。コンパイラが LLVM グローバル配列を直接生成するため、C ラッパーファイルは不要です。
インライン RBS(rbs_inline: enabled)を使えば、モジュール宣言と配列型を同じファイルに書けます:
# physics.rb
# rbs_inline: enabled
# @rbs module PhysicsData
# @rbs @xs: NativeArray[Float, 10000]
# @rbs @ys: NativeArray[Float, 10000]
# @rbs end
#: (Float, Float, Float, Float) -> Float
def distance(x1, y1, x2, y2)
dx = x2 - x1
dy = y2 - y1
dx * dx + dy * dy
end
def init_data
i = 0
while i < 10000
PhysicsData.xs[i] = i * 0.0001
PhysicsData.ys[i] = i * 0.0002
i = i + 1
end
end
#: () -> Float
def compute_total
total = 0.0
i = 0
while i < 9999
total = total + distance(PhysicsData.xs[i], PhysicsData.ys[i],
PhysicsData.xs[i + 1], PhysicsData.ys[i + 1])
i = i + 1
end
total
end
def run_physics
init_data
compute_total
end
konpeito run --inline physics.rb
または別ファイルの RBS で宣言:
# physics.rbs
module PhysicsData
@xs: NativeArray[Float, 10000]
@ys: NativeArray[Float, 10000]
end
構文は NativeArray[T, N] で、T は要素型(Integer または Float)、N は固定サイズです。アクセスは ModuleName.field_name[index]、代入は ModuleName.field_name[index] = value です。
注意: モジュール NativeArray は LLVM(CRuby)と mruby バックエンドで使用できます。JVM バックエンドは未対応です。実際のゲームでの使用例は
examples/mruby_space_invaders/を参照してください。
パターン2: アプリケーション全体のコンパイル
require チェーンを辿り、ロードパス上のすべてのファイルを単一の拡張に一括コンパイルします。
例: kumiki GUI アプリ
kumiki はクロスプラットフォームのデスクトップ UI フレームワークです。
gem install kumiki
# counter.rb
require "kumiki"
include Kumiki
class CounterComponent < Component
def initialize
super
@count = state(0)
end
def view
column(padding: 16.0, spacing: 8.0) {
text "Count: #{@count}", font_size: 32.0, color: 0xFFC0CAF5, align: :center
row(spacing: 8.0) {
button(" - ") { @count -= 1 }
button(" + ") { @count += 1 }
}
}
end
end
frame = RanmaFrame.new("Kumiki Counter", 400, 300)
app = App.new(frame, CounterComponent.new)
app.run
Option A: 全体コンパイル(kumiki のソースも含む)
konpeito build -I /path/to/kumiki/lib counter.rb
-I で kumiki の lib/ を指定すると、require "kumiki" の先にあるすべてのファイル(59ファイル)が一括コンパイルされます。直接ディスパッチ・単相化・インライン化がコード全体に適用されます。
Option B: 自分のコードだけコンパイル
konpeito build counter.rb
-I なしでは counter.rb だけがコンパイルされ(約50 KB)、kumiki は実行時に CRuby がロードします。
実行:
konpeito run counter.rb
または、.rb / .bundle の名前衝突を避けるために別ディレクトリにビルドします:
konpeito build -o build/counter.bundle counter.rb
ruby -r ./build/counter -e ""
-r ./build/counterで拡張をロード。Init関数がトップレベルコードを実行し、アプリが起動します。-e ""で空スクリプトを渡します(Ruby が stdin を待たないように)。counter.rbと同じディレクトリでruby -r ./counter -e ""を使わないでください — Ruby は.bundleより.rbを先にロードするため、コンパイルされていないソースが実行されます。
5. JVM バックエンド: 実用例
スタンドアロンプログラム
# physics_jvm.rb
def distance(x1, y1, x2, y2)
dx = x2 - x1
dy = y2 - y1
dx * dx + dy * dy
end
def sum_distances(n)
total = 0.0
i = 0
while i < n
total = total + distance(i * 1.0, 0.0, 0.0, i * 2.0)
i = i + 1
end
total
end
puts sum_distances(1000)
konpeito build --target jvm --run physics_jvm.rb
JAR を生成して別途実行:
konpeito build --target jvm -o physics.jar physics_jvm.rb
java -jar physics.jar
GUI アプリ(Castella UI)
JVM バックエンドでは Castella UI(Skia ベースのリアクティブ GUI フレームワーク)が使えます。
git clone https://github.com/i2y/konpeito.git
cd konpeito/examples/castella_ui
bash setup.sh # JWM + Skija JAR をダウンロード(約30 MB、初回のみ)
bash run.sh framework_counter.rb
# framework_counter.rb
class CounterApp < Component
def initialize
super
@count = state(0)
end
def view
label = "Count: " + @count.value.to_s
Column(
Text(label).font_size(32.0),
Row(
Button(" - ").on_click { @count -= 1 },
Button(" + ").on_click { @count += 1 }
).spacing(8.0)
)
end
end
$theme = theme_tokyo_night
frame = JWMFrame.new("Counter", 400, 300)
app = App.new(frame, CounterApp.new)
app.run
Castella UI の詳細は Getting Started のウィジェットカタログとテーマ一覧を参照してください。
5.5. mruby バックエンド: スタンドアロン実行ファイル
mruby バックエンドはスタンドアロン実行ファイルを生成します — 実行マシンに Ruby や Java は不要です。アプリケーション配布、ゲーム開発、Ruby がインストールされていない環境へのデプロイに最適です。
スタンドアロン Hello World
# hello.rb
def main
puts "Hello from Konpeito!"
end
main
konpeito build --target mruby -o hello hello.rb
./hello # => Hello from Konpeito!
ビルドと実行を一度に:
konpeito run --target mruby hello.rb
raylib stdlib でゲーム開発
Konpeito は mruby バックエンド向けに raylib stdlib を内蔵しています。コード内で module Raylib を参照すると、コンパイラが RBS/C ラッパーを自動検出します — 手動セットアップは不要です。
# catch_game.rb
module Raylib
end
def main
screen_w = 600
screen_h = 400
Raylib.init_window(screen_w, screen_h, "Catch Game")
Raylib.set_target_fps(60)
paddle_x = screen_w / 2 - 40
paddle_y = screen_h - 40
paddle_speed = 400
obj_x = Raylib.get_random_value(30, screen_w - 30)
obj_y = 0
obj_speed = 150.0
score = 0
while Raylib.window_should_close == 0
dt = Raylib.get_frame_time
if Raylib.key_down?(Raylib.key_left) != 0
paddle_x = paddle_x - (paddle_speed * dt).to_i
end
if Raylib.key_down?(Raylib.key_right) != 0
paddle_x = paddle_x + (paddle_speed * dt).to_i
end
obj_y = obj_y + (obj_speed * dt).to_i
if obj_y > screen_h
obj_x = Raylib.get_random_value(30, screen_w - 30)
obj_y = 0
end
Raylib.begin_drawing
Raylib.clear_background(Raylib.color_black)
Raylib.draw_rectangle(paddle_x, paddle_y, 80, 14, Raylib.color_skyblue)
Raylib.draw_rectangle(obj_x, obj_y, 16, 16, Raylib.color_gold)
Raylib.draw_text("Score: #{score}", 10, 10, 20, Raylib.color_white)
Raylib.end_drawing
end
Raylib.close_window
end
main
konpeito run --target mruby catch_game.rb
Clay stdlib で UI レイアウト
Konpeito は mruby バックエンド向けに Clay UI stdlib を内蔵しています。Clay は Flexbox スタイルのレイアウトエンジンで、コンテナのツリーからレイアウトを計算し、raylib 経由で描画コマンドをレンダリングします。コード内で module Clay を参照すると自動検出されます。
# Clay レイアウト: open/close でコンテナを定義、layout/bg で設定、text でテキスト追加
Clay.begin_layout
Clay.open("root")
Clay.layout(1, 16, 16, 16, 16, 8, 1, 0.0, 1, 0.0, 2, 0) # 縦方向、GROW、中央揃え
Clay.bg(40.0, 40.0, 60.0, 255.0, 0.0)
Clay.open("card")
Clay.layout(1, 12, 12, 12, 12, 4, 1, 0.0, 0, 0.0, 0, 0) # 縦方向、幅GROW、高さFIT
Clay.bg(255.0, 255.0, 255.0, 255.0, 8.0) # 白、角丸
Clay.border(200.0, 200.0, 200.0, 255.0, 1, 1, 1, 1, 8.0) # グレーのボーダー
Clay.text("Hello!", font, 24, 40.0, 40.0, 40.0, 255.0, 0)
Clay.close
Clay.close
Clay.end_layout
Clay.render_raylib # raylib で全コマンドをレンダリング
主要概念:
Clay.open(id)/Clay.close— ネストされたコンテナの定義Clay.layout(dir, pl, pr, pt, pb, gap, sw_type, sw_val, sh_type, sh_val, ax, ay)— Flexbox レイアウトClay.bg(r, g, b, a, corner_radius)— 背景色と角丸Clay.border(r, g, b, a, top, right, bottom, left, corner_radius)— ボーダーClay.text(str, font_id, size, r, g, b, a, wrap)— テキスト要素Clay.pointer_over(id)/Clay.pointer_over_i(id, index)— ヒットテスト
examples/mruby_clay_ui/ にサイドバーレイアウトのデモと Memory Match カードゲームがあります。
ゲームフレームワーク
Konpeito には 2D ゲーム構築用のフレームワーク(game_framework.rb)が含まれています:
- タイルマップ描画、スプライトアニメーション、シーン管理、NPC システム、テキストボックス
- Tween/イージング(linear, quad, cubic, bounce, elastic)、画面シェイク、シーン遷移
- 簡易物理演算(AABB、重力、摩擦)、パーティクルシステム、オブジェクトプール
- FSM(有限状態マシン)、タイマーシステム、パララックススクロール
- グリッド/タイルユーティリティ、デバッグオーバーレイ(FPS、衝突矩形)、ゲームパッド抽象化、セーブ/ロード
- Clay UI ヘルパー:
fw_clay_rpg_window,fw_clay_bar,fw_clay_num,fw_clay_menu_item module G+NativeArrayグローバルによるゼロアロケーションのゲーム状態管理
examples/mruby_dq_rpg/ に JRPG デモ、examples/game_showcase/ に物理・パーティクル・Tween・FSM・パララックスを活用したプラットフォーマーデモがあります。
KUI — 宣言的 UI フレームワーク
KUI(Konpeito UI)は、Clay + Raylib(GUI)または ClayTUI + termbox2(TUI)を統一的な宣言 API でラップする Pure Ruby DSL です。同じコードで GUI/TUI 両方のビルドが可能です。
カウンターアプリ(GUI)
# counter_gui.rb
# rbs_inline: enabled
require "kui_gui"
# @rbs module AppState
# @rbs @s: NativeArray[Integer, 4]
# @rbs end
#: () -> Integer
def draw
vpanel pad: 24, gap: 16 do
header pad: 12 do
label "Counter App", size: 28, r: 255, g: 255, b: 255
end
spacer
cpanel gap: 8 do
label "Current Count:", size: 20
hpanel gap: 4 do
spacer
label_num AppState.s[0], size: 36, r: 100, g: 200, b: 255
spacer
end
end
spacer
hpanel gap: 12 do
spacer
button " - ", size: 20 do
AppState.s[0] = AppState.s[0] - 1
end
button " Reset ", size: 20 do
AppState.s[0] = 0
end
button " + ", size: 20 do
AppState.s[0] = AppState.s[0] + 1
end
spacer
end
spacer
divider
footer do
label "KUI Framework Demo", size: 14, r: 120, g: 120, b: 140
end
end
return 0
end
#: () -> Integer
def main
kui_init("KUI Counter", 450, 350)
kui_theme_dark
AppState.s[0] = 0
while kui_running == 1
kui_begin_frame
draw
kui_end_frame
end
kui_destroy
return 0
end
main
konpeito build --target mruby -o counter_gui counter_gui.rb
./counter_gui
TUI 版への切り替え
require 行を変えるだけで同じアプリをターミナル向けにビルドできます:
# counter_tui.rb
require "kui_tui"
# ... draw/main は同じコード ...
# フレーム末尾に _kui_update_focus を追加してキーボードナビゲーションを有効化
konpeito build --target mruby -o counter_tui counter_tui.rb
./counter_tui
KUI ウィジェット一覧
| ウィジェット | 説明 |
|---|---|
vpanel(pad:, gap:) { } | 縦方向コンテナ(幅/高さ GROW) |
hpanel(pad:, gap:) { } | 横方向コンテナ(幅 GROW、高さ FIT) |
cpanel(pad:, gap:) { } | 中央寄せコンテナ |
fixed_panel(w, h, pad:) { } | 固定サイズコンテナ |
scroll_panel(pad:, gap:) { } | スクロール対応の縦方向コンテナ |
card(pad:, gap:) { } | ボーダー付きサーフェスパネル |
header(pad:) { } | プライマリカラーのトップバー |
footer(pad:) { } | 控えめなボトムバー |
sidebar(w, pad:, gap:) { } | 固定幅の縦方向サイドバー |
label(text, size:, r:, g:, b:) | テキストラベル |
label_num(value, size:, r:, g:, b:) | 整数表示(文字列割り当てなし) |
button(text, size:) { } | クリック可能なボタン(ブロックがクリック時に実行) |
menu_item(text, index, cursor, size:) | 選択可能なメニュー項目 |
spacer | 余白を埋める |
divider(r:, g:, b:) | 水平区切り線 |
progress_bar(value, max, w, h, r:, g:, b:) | プログレスバー |
ライフサイクルとテーマ
kui_init("タイトル", width, height) # ウィンドウ/ターミナルを初期化
kui_theme_dark # ダークテーマ(インディゴ背景、明るいテキスト)
kui_theme_light # ライトテーマ(白背景、暗いテキスト)
while kui_running == 1
kui_begin_frame
# ... UI を描画 ...
kui_end_frame
end
kui_destroy # 後片付け
入力
key = kui_key_pressed
# 戻り値: KUI_KEY_UP, KUI_KEY_DOWN, KUI_KEY_LEFT, KUI_KEY_RIGHT,
# KUI_KEY_ENTER, KUI_KEY_ESC, KUI_KEY_SPACE, KUI_KEY_TAB,
# KUI_KEY_BACKSPACE, または KUI_KEY_NONE
状態管理
KUI アプリはモジュール NativeArray で GC フリーな状態管理を行います:
# @rbs module AppState
# @rbs @s: NativeArray[Integer, 4]
# @rbs end
AppState.s[0] = 42 # 書き込み
x = AppState.s[0] # 読み出し
examples/kui_counter/ にカウンターデモ、examples/kui_dashboard/ にサイドバーナビゲーション付きマルチページダッシュボードがあります。
シェル実行 & ファイル I/O — KonpeitoShell
シェルコマンドの実行やファイルの読み書き:
# KonpeitoShell を参照すると自動検出されます
output = KonpeitoShell.exec("ls -la")
status = KonpeitoShell.exec_status # 0 = 成功
home = KonpeitoShell.getenv("HOME")
KonpeitoShell.setenv("MY_VAR", "value")
content = KonpeitoShell.read_file("data.txt")
KonpeitoShell.write_file("out.txt", "hello")
KonpeitoShell.append_file("log.txt", "new line\n")
if KonpeitoShell.file_exists("config.json") == 1
# ...
end
JSON — KonpeitoJSON
yyjson を使った JSON パース・生成:
obj = KonpeitoJSON.parse('{"name": "Alice", "age": 30}')
json = KonpeitoJSON.generate(obj)
HTTP — KonpeitoHTTP
libcurl を使った HTTP クライアント:
body = KonpeitoHTTP.get("https://example.com")
暗号 — KonpeitoCrypto
OpenSSL を使ったハッシュ・暗号化:
hash = KonpeitoCrypto.sha256("hello")
圧縮 — KonpeitoCompression
zlib を使ったデータ圧縮:
compressed = KonpeitoCompression.gzip("Hello, World!")
decompressed = KonpeitoCompression.gunzip(compressed)
上記の stdlib モジュールはすべて自動検出されます。ソースコードでモジュール名を参照するだけで、コンパイラが適切な RBS と C ラッパーを自動注入します。
クロスコンパイル
zig cc を使って他のプラットフォーム向けにクロスコンパイルできます:
konpeito build --target mruby \
--cross aarch64-linux-musl \
--cross-mruby ~/mruby-aarch64 \
-o game game.rb
| オプション | 説明 |
|---|---|
--cross TARGET | ターゲットトリプル(例: x86_64-linux-gnu) |
--cross-mruby DIR | クロスコンパイル済み mruby のインストールパス |
--cross-libs DIR | 追加ライブラリ検索パス |
mruby vs CRuby バックエンド比較
| 観点 | CRuby バックエンド | mruby バックエンド |
|---|---|---|
| 出力 | .so/.bundle(拡張ライブラリ) | スタンドアロン実行ファイル |
| 実行時依存 | CRuby 4.0+ | なし |
| 用途 | ライブラリ/アプリの高速化 | 配布、ゲーム |
| raylib stdlib | 非対応 | 自動検出 |
| Clay UI stdlib | 非対応 | 自動検出 |
| KUI(宣言的 UI) | 非対応 | 自動検出(GUI/TUI) |
| Thread/Mutex | 対応 | 非対応 |
| キーワード引数 | 対応 | 対応 |
| コンパイルキャッシュ | .konpeito_cache/run/ | .konpeito_cache/run/ |
6. 型システム
HM 型推論(注釈不要)
Konpeito は Hindley-Milner 型推論でほとんどの型を自動解決します:
def double(x)
x * 2 # 2 が Integer → x は Integer → 戻り値も Integer
end
def greet(name)
"Hello, " + name # String + String → String
end
推論された型はそのまま unboxed 最適化に使われます。RBS は不要です。
RBS でより正確に
RBS を追加すると、コンパイラにより正確な情報を伝えられます:
別ファイル方式:
# sig/math.rbs
module TopLevel
def add: (Integer a, Integer b) -> Integer
end
konpeito build --rbs sig/math.rbs math.rb
インライン方式(rbs-inline):
# rbs_inline: enabled
#: (Integer, Integer) -> Integer
def add(a, b)
a + b
end
konpeito build --inline math.rb
ネイティブデータ構造
型付き高速データ構造が使えます(CRuby・mruby バックエンド):
| 型 | 用途 | 特徴 |
|---|---|---|
NativeArray[T] | 数値配列 | unboxed、連続メモリ、5-15x 高速 |
NativeClass | 構造体 | unboxed フィールド、10-20x 高速 |
StaticArray[T, N] | 固定長配列 | スタック割り当て、GC なし |
NativeHash[K, V] | ハッシュマップ | 線形探査、4x 高速 |
Slice[T] | メモリビュー | ゼロコピー、バウンドチェック付き |
# NativeArray の例
def sum_array(n)
arr = NativeArray.new(n)
i = 0
while i < n
arr[i] = i * 1.5 # unboxed store
i = i + 1
end
total = 0.0
i = 0
while i < n
total = total + arr[i] # unboxed load
i = i + 1
end
total
end
これらの型を使うには RBS 定義が必要です。詳細は API Reference を参照してください。
7. プロジェクト構成
konpeito init でプロジェクトを初期化できます:
konpeito init --target jvm my_app
cd my_app
my_app/
konpeito.toml # ビルド設定
src/
main.rb # エントリポイント
test/
main_test.rb # テストスタブ
lib/ # JVM 依存(JAR)
.gitignore
konpeito run src/main.rb # コンパイル & 実行
konpeito test # テスト実行
8. 便利なコマンド
konpeito build -v source.rb # 推論結果と動的フォールバック箇所を表示
konpeito build -g source.rb # DWARF デバッグ情報付きでビルド(lldb/gdb 対応)
konpeito check source.rb # 型チェックのみ(コード生成なし)
konpeito build --profile source.rb # プロファイリング情報付きでビルド
konpeito run --no-cache source.rb # キャッシュを無視して強制再コンパイル
konpeito run --clean-run-cache source.rb # runキャッシュクリア後にビルド&実行
konpeito fmt # コードフォーマット(RuboCop)
konpeito deps source.rb # 依存関係の解析・表示
# mruby バックエンド
konpeito build --target mruby -o app app.rb # スタンドアロン実行ファイル
konpeito run --target mruby app.rb # ビルド&実行(キャッシュあり)
konpeito doctor --target mruby # mruby 環境チェック
次のステップ
- CLI Reference — 全コマンドとオプション
- API Reference — ネイティブデータ構造、標準ライブラリ、Castella UI ウィジェット
- Language Specification — 対応構文と型システムの詳細