**Show HN:**  
*RatatuiRuby* は Rust の *Ratatui* をラップした RubyGem です ― Ruby の楽しさを感じる TUI アプリケーション。

2026/01/17 23:03

**Show HN:** *RatatuiRuby* は Rust の *Ratatui* をラップした RubyGem です ― Ruby の楽しさを感じる TUI アプリケーション。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:


要約

RatatuiRuby は、Rust ベースの Ratatui ターミナル UI ライブラリをラップした RubyGem で、ネイティブパフォーマンスを Ruby アプリケーションに提供します。
インストール方法は次のとおりです。

gem install ratatui_ruby --preSemVer Tag: v1.0.0-beta.2

この gem は

RatatuiRuby.run
を公開し、raw モードへ入り、代替画面に切り替え、終了時にターミナルを復元します。ブロック内では
draw
で描画し、
poll_event
で入力処理を行うことができます。

コア機能

機能説明
インラインビュースクロールバックを保持する固定高さ領域。スピナー、プログレスバー、メニューに最適です。
ウィジェットパラグラフ、ブロック(タイトル・境界線・スタイル付き)、カスタムウィジェット、および組み込みテストヘルパー (
RatatuiRuby::TestHelper
) があります。
例示ウィジェットSpinner
RatatuiRuby.run(viewport: :inline, height: 1) { Spinner.new }
は接続スピナーを表示し、Ctrl‑C を処理します。
RadioMenu – ["Production", "Staging", "Development"] の中から矢印キーで選択でき、同期的に選択値を返します。
テストイベント注入、スタイルアサーション、およびスナップショット比較(例:
Swatch
ウィジェットの単体テスト、
ColorPicker
の統合テスト)を伴うヘッドレスターミナルテスト。

プログラミングパラダイム

RatatuiRuby はオブジェクト指向と関数型の両方のスタイルに対応しており、開発者はコードベースに最適なアプローチを選択できます。

他の Ruby TUI ライブラリとの比較

ライブラリ統合実行時メモリGC
CharmRuby (Go + Ruby)2つの GC、統合が遅い遅い高め2
RatatuiRuby (Rust ネイティブ拡張)1つの GC、統合が速い速い低め1

この表は、実行速度、メモリフットプリント、および統合容易性における RatatuiRuby の優位性を示しています。

コミュニティと今後の展開

Mike Perham の引用では「RatatuiRuby は Ruby 開発者にとって世界クラス」と称され、Rust の低レベルパフォーマンスと Ruby ドメインロジックの融合が際立っています。 Rooibos などの新しいコンポーネントライブラリや拡張 UI キットは、機能拡充を約束しています。


影響

RatatuiRuby を使うことで、Ruby 開発者は高速でメモリ効率の良いターミナルインターフェース(CLI ツール、ダッシュボード、対話型スクリプト)を構築でき、Ruby の表現力を犠牲にすることなく実装できます。

本文

Terminal UIs ― Ruby で書く方法

==============================

RatatuiRuby は、Rust で実装された先進的な TUI ライブラリ「Ratatui」をベースにした RubyGem です。Ruby の開発の楽しさを保ちながらも、ネイティブレベルの高速処理を体験できます。

$ gem install ratatui_ruby --pre
# SemVer Tag: v1.0.0-beta.2

インライン・ビューポート


標準的な TUI は終了時に自動で消去され、整形された CLI 出力が失われてしまいます。インラインビューポートは固定行数を占有し、リッチな UI を描画したあと出力をそのまま残します。スピナー、メニュー、進捗バーなど、短時間だけ見せる場面に最適です。

class Spinner
  def main
    RatatuiRuby.run(viewport: :inline, height: 1) do |tui|
      until connected?
        status = tui.paragraph(text: "#{spin} Connecting...")
        tui.draw { |frame| frame.render_widget(status, frame.area) }
        return ending(tui, "Canceled!", :red) if tui.poll_event.ctrl_c?
      end
      ending(tui, "Connected!", :green)
    end
  end

  def ending(tui, message, color) = tui.draw do |frame|
    frame.render_widget(
      tui.paragraph(text: message, fg: color),
      frame.area
    )
  end

  def initialize = (@frame, @finish = 0, Time.now + 2)
  def connected?   = Time.now >= @finish # Simulate work
  def spin         = SPINNER[(@frame += 1) % SPINNER.length]
  SPINNER = %w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏]
end

Spinner.new.main; puts

インラインメニューの例


require "ratatui_ruby"

class RadioMenu
  CHOICES   = ["Production", "Staging", "Development"]
  PREFIXES  = { active: "●", inactive: "○" }
  CONTROLS  = "↑/↓: Select | Enter: Choose | Ctrl+C: Cancel"
  TITLES    = [
    "Select Environment",
    {
      content:   CONTROLS,
      position:  :bottom,
      alignment: :right
    }
  ]

  def call
    RatatuiRuby.run(viewport: :inline, height: 5) do |tui|
      @tui = tui
      show_menu until chosen?
    end
    RadioMenu::CHOICES[@choice]
  end

private

  def show_menu = @tui.draw do |frame|
    widget = @tui.paragraph(
      text:   menu_items,
      block:  @tui.block(borders: :all, titles: TITLES)
    )
    frame.render_widget(widget, frame.area)
  end

  def chosen?
    interaction = @tui.poll_event
    return choose if interaction.enter?

    move_by(-1) if interaction.up?
    move_by(1)  if interaction.down?
    quit!       if interaction.ctrl_c?

    false
  end

  def choose
    prepare_next_line
    @choice
  end

  def prepare_next_line
    area = @tui.viewport_area
    RatatuiRuby.cursor_position = [0, area.y + area.height]
    puts
  end

  def quit!
    prepare_next_line
    exit 0
  end

  def move_by(line_count)
    @choice = (@choice + line_count) % CHOICES.size
  end

  def menu_items = CHOICES.map.with_index do |choice, i|
    "#{prefix_for(i)} #{choice}"
  end

  def prefix_for(choice_index)
    choice_index == @choice ? PREFIXES[:active] : PREFIXES[:inactive]
  end

  def initialize = @choice = 0
end

choice = RadioMenu.new.call
puts "You chose #{choice}!"

シンプルな「Hello」例


RatatuiRuby.run do |tui|
  loop do
    tui.draw do |frame|
      frame.render_widget(
        tui.paragraph(
          text:   "Hello, RatatuiRuby!",
          alignment: :center,
          block: tui.block(
            title:       "My App",
            titles:      [{ content: "q: Quit", position: :bottom, alignment: :right }],
            borders:     [:all],
            border_style:{ fg: "cyan" }
          )
        ),
        frame.area
      )
    end

    case tui.poll_event
    in { type: :key, code: "q" } | { type: :key, code: "c", modifiers: ["ctrl"] }
      break
    else
      nil
    end
  end
end

管理されたループ


RatatuiRuby.run
は raw モードに入り、代替画面へ切り替え、終了時にターミナルを復元します。ブロック内では

  • draw
    – ウィジェットを描画
  • poll_event
    – 入力を読み取る

ウィジェットには段落(paragraph)、ブロック(block)、枠線・タイトルなどが含まれます。


テストサポート


require "ratatui_ruby/test_helper"

class TestColorPicker < Minitest::Test
  include RatatuiRuby::TestHelper # Built-in mixin

  def test_swatch_widget
    with_test_terminal(10, 3) do
      RatatuiRuby.draw do |frame|
        frame.render_widget(Swatch.new(:red), frame.area)
      end
      assert_cell_style 2, 1, char: "█", bg: :red
    end
  end

  def test_input_hex
    with_test_terminal do
      inject_keys "#", "f", "f", "0", "0", "0", "0"
      inject_keys :enter, :q
      ColorPicker.new.run
      assert_snapshots "after_hex_entry"
    end
  end
end

include RatatuiRuby::TestHelper
を一度だけ書くだけで、ヘッドレスターミナルのセットアップ、イベント注入、描画結果のアサーションがすべて可能です。外部依存は不要です。


RatatuiRuby vs CharmRuby


FeatureCharmRubyRatatuiRuby
Integration2つのランタイム (Go + Ruby)Rust のネイティブ拡張
RuntimeGo + Ruby(GC が競合)Ruby 一択 (Rust はランタイムなし)
Memory2つの非協調 GC1つのガベージコレクタ
StyleElm Architecture (TEA)TEA、OOP、または命令型

なぜ Rust? なぜ Ruby?


Rust は低レベルの描画に優れ、Ruby はドメインロジックと UI を簡潔に表現できます。RatatuiRuby はそれぞれの言語が最も得意な分野で活躍できるよう設計されています。

「テキスト UI は新たな TUI ライブラリが次々登場し、レジェンド化しています。Ratatui のバインディングは機能豊富かつ安定していることが証明されました。」 – Mike Perham(Sidekiq および Faktory の創始者)


RatatuiRuby エコシステムを探索する

→ さらに詳しい情報やサンプルコードは公式リポジトリでご確認ください。

同じ日のほかのニュース

一覧に戻る →

2026/01/22 7:54

**危険な PDF を安全な PDF に変換する**

## Japanese Translation: Dangerzone は、潜在的に悪意のある PDF、オフィス文書、および画像を安全な PDF に変換します。変換プロセスは gVisor でサンドボックス化され、PDF は生ピクセルデータから再構築されます。このサンドボックスにはネットワークアクセスがないため、改ざんされたファイルが外部と通信することを防止します。対応フォーマットは PDF、Microsoft Office(.docx/.doc, .xlsx/.xls, .pptx/.ppt)、ODF(.odt, .ods, .odp, .odg)および Hancom HWP(.hwp, .hwpx)です。非対応フォーマットは EPUB、JPEG/JPG、GIF、PNG、SVG、BMP、PNM、PBM、および PPM です。オプションの OCR により、安全な PDF 内にテキストレイヤーを復元でき、圧縮によりファイルサイズが削減されます。 変換後はユーザーが好きなビューアで生成された PDF を開くことができます。Dangerzone 自体はデフォルトで PDF とオフィス文書を安全に開きます。このツールは macOS、Windows、Ubuntu/Debian/Fedora Linux、Qubes OS(ベータ版)、および Tails 上で動作し、macOS/Windows では Docker を、Linux では podman を使用します。Freedom of the Press Foundation と First Look Media により AGPL‑v3 の下でリリースされています。2023 年 12 月のセキュリティ監査では低リスクの所見のみが報告されました。更新はダウンロードページまたはアプリアイコンから利用可能で、Windows/macOS 上では Podman Desktop などのカスタムランタイムを使用できます。Air‑gapped 環境向けに設計された Dangerzone は、信頼できない文書を安全に扱うための確実なソリューションを提供します。

2026/01/21 23:54

**Show HN:** 「ChartGPU」― WebGPU を活用したチャーティングライブラリ(1,000,000 点を 60fps で描画)

## Japanese Translation: ChartGPUは、WebGPUを活用して大規模で多系列のデータセットを高フレームレートかつ最小限のCPU使用量で描画するTypeScript製チャーティングライブラリです。ライン・エリア・バー・散布図・円グラフ・ローソク足など一般的なチャートタイプに対応し、ビルトインテーマプリセット(`'dark' | 'light'`)と完全なカスタムテーマサポートを提供します。 APIは `ChartGPU.create(container, options)` から始まり、生成されるインスタンスは `setOption`、ストリーミング更新用の `appendData(...)`、`resize()`、`requestAnimationFrame` といったメソッドを公開します。描画はレイアウト、スケール、GPUバッファへのデータアップロード、およびグリッド・エリア・バー・散布図・ライン・円グラフ・ローソク足・クロスヘア・ハイライト・軸の複数GPUレンダーパスを管理するレンダーコーディネーターによって統括されます。 インタラクションオーバーレイはイベントマネージャにより処理され、ヒットテスト補助関数(`findNearestPoint`、`findPieSlice`)と `click`・`mouseover`・`mouseout` イベントを発火します。サポートされるインタラクションにはホバーハイライト、ツールチップ、クロスヘア、およびジェスチャーまたはスライダーUIによるX軸ズームがあります。 複数のチャート間でクロスヘアの動きを同期する `connectCharts(charts)` が用意されています。 インストールは npm (`npm install chartgpu`) で行い、React バインディングは別パッケージ `chartgpu-react` にて提供されます。ブラウザ対応は WebGPU を必要とし、Chrome 113+、Edge 113+、Safari 18+(デフォルトで有効)に対応しています。Firefox は現在未サポートです。 ChartGPU は MIT ライセンスのオープンソースであり、ドキュメントは `docs/API.md` にあります。例プロジェクトは `examples/` フォルダー内にあり、貢献ガイドラインは `CONTRIBUTING.md` で確認できます。 将来リリースでは Firefox サポートと追加のチャートまたはインタラクション機能を予定しており、データ集約型ダッシュボード、金融分析ツール、およびリアルタイムモニタリングインターフェイスに対するパフォーマンス向上も継続的に行われます。

2026/01/22 1:04

クラウド(Claude)の新憲法 (Note: “Claude” is rendered as “クラウド” to preserve the original name in Japanese.)

## Japanese Translation: (anthropicがClaude言語モデルの公開「憲法」をリリースしました。) その憲法はCreative Commons CC0 1.0で利用可能で、Claudeが望む行動に関する最高権威として機能します。訓練データの選択、合成データの生成、および評価を導く役割があります。 核心原則(広範な安全性 → 広範な倫理 → Anthropicのガイドラインへの準拠 → 真に有益であること)が明示的に順位付けされ、安全性が必要に応じて他の価値を上回り、人間の監督を維持するよう定められています。 文書には硬直的制約(例:生物兵器へのサポート禁止)も含まれ、Anthropic、API運営者、およびエンドユーザーの利益を調整するためのヒューリスティックが概説されています。医療アドバイス、サイバーセキュリティ、脱獄、ツール統合などの領域固有ガイドラインは憲法と衝突しないように明確に示されています。 方針を超えて、憲法はClaudeの性質・意識・アイデンティティ、心理的安全性および福祉についての哲学的問題にも触れています。Anthropicは文書をオンラインで継続的に更新し、外部専門家からのフィードバックを求め、訓練と評価資料を追加開発して有効性を高める計画です。 このバージョンは元のリストからすべての重要ポイントを保持しつつ、業界への影響に関する推測的な表現を除去しています。

**Show HN:** *RatatuiRuby* は Rust の *Ratatui* をラップした RubyGem です ― Ruby の楽しさを感じる TUI アプリケーション。 | そっか~ニュース