Upgrade to Pro — share decks privately, control downloads, hide ads and more …

My daily life on Ruby

My daily life onย Ruby

Slides for my RubyCon 2026 talk "My daily life on Ruby" https://rubycon.it/schedule/

Akira Matsuda

May 11, 2026

Transcript

213 slides
  1. self ๐Ÿ• Ruby committer ๐Ÿ• Rails committer ๐Ÿ• Gem author

    ๐Ÿ• Kaminari, active_decorator, action_args, jb, stateful_enum, database_rewinder, gem_src, traceroute, routes_lazy_routes, lightweight_attributes, everywhere, hocus_pocus, erd, i18n_generators, html5_validators, motorhead, heavens_door, still_life, roundabout... ๐Ÿ• Gem maintainer ๐Ÿ• Haml, SimpleCov, test-unit-rails, md2key, cfp-app... 3 / 213
  2. self ๐Ÿ• Chief Organizer of RubyKaigi (since 2015) ๐Ÿ• Founder

    of Asakusa.rb (since 2008) ๐Ÿ• Ruby Hero (2016) ๐Ÿ• Rails Luminary (2024) ๐Ÿ• Loves ๐Ÿ‡ฎ๐Ÿ‡น Rock in '70s ๐Ÿ• Premiata Forneria Marconi, New Trolls, Area, Banco del Mutuo Soccorso, Arti e Mestieri, Semiramis, Biglietto per l'Inferno, Il Balletto di Bronzo, Museo Rosenbach, Formula 3, Jacula... 4 / 213
  3. Layered into each software stack ๐Ÿ• We can choose one

    from each layer and combine them 13 / 213
  4. The kitty text sizing protocol ๐Ÿ• https://github.com/kovidgoyal/kitty/issues/8226 ๐Ÿ• Proposed and

    implemented last year ๐Ÿ• We can enlarge text size via OSC Escape Code (OSC 66) 21 / 213
  5. mkd ๐Ÿ• github.com/amatsuda/mkd ๐Ÿ• A Markdown viewer written in pure

    Ruby ๐Ÿ• By me ๐Ÿ• Renders Markdown nicely on terminals that support OSC 66 28 / 213
  6. So we have to use kitty ๐Ÿ• If we want

    to try this feature 30 / 213
  7. Structure ๐Ÿ• parser.rb: Parses Markdown and builds the deck ๐Ÿ•

    controller.rb: Accepts key inputs and executes the commands ๐Ÿ• terminal.rb: Renders on the terminal using io-console 39 / 213
  8. io-console ๐Ÿ• A Ruby stdlib ๐Ÿ• Maybe not that popular?

    ๐Ÿ• A very few usages found on the web ๐Ÿ• A very handy tool to draw characters on console ๐Ÿ• Made by nobu, the patch monster 41 / 213
  9. @nobu (Nobuyoshi Nakada) ๐Ÿ• No.1 Ruby committer (in terms of

    numbers of commits) ๐Ÿ• aka "Patch Monster" (or "Pachimon") ๐Ÿ• Maintains everything in Ruby 42 / 213
  10. io-console ๐Ÿ• A Ruby stdlib ๐Ÿ• Maybe not that popular?

    ๐Ÿ• A very few usages found on the web ๐Ÿ• A very handy tool to draw characters on console ๐Ÿ• Made by nobu, the patch monster 43 / 213
  11. What does GNU Readline do? ๐Ÿ• It bridges between users'

    key inputs and the terminal/shell 49 / 213
  12. Readline ๐Ÿ• Super legacy ๐Ÿ• Often fails to install for

    some reasons ๐Ÿ• Lacks some features that Ruby needs for irb 50 / 213
  13. @keiju (Keiju Ishitsuka) ๐Ÿ• The godfather of Ruby ๐Ÿ• It

    was keiju who gave the name "Ruby" to Matz's language (1993) ๐Ÿ• Was Matz's colleague at that time ๐Ÿ• The author of irb ๐Ÿ• The author or Reish 53 / 213
  14. Reish ๐Ÿ• And so he started from reinventing Readline in

    pure Ruby ๐Ÿ• Which was named Reidline 56 / 213
  15. Reline ๐Ÿ• Pure Ruby Readline implementation ๐Ÿ• Created by itoyanagi

    ๐Ÿ• Inspired by keiju's unfinished work "Reidine" 59 / 213
  16. Reline ๐Ÿ• Totally replaced Readline (2019) ๐Ÿ• irb's backend today

    ๐Ÿ• Maintained by the irb team today ๐Ÿ• tompng, ima1zumi, st0012, and hasumikin 60 / 213
  17. @itoyanagi (Itoyanagi) ๐Ÿ• An adventurer ๐Ÿ• A legacy killer in

    Ruby ๐Ÿ• Killed RDoc's own parser in favor of Ripper ๐Ÿ• Created Reline ๐Ÿ• Achieved a big refactoring on irb on top of Reline 62 / 213
  18. Pure Ruby Readline equivalent has done ๐Ÿ• So it's time

    to create a pure Ruby shell on top of it? ๐Ÿ• As keiju planned? 64 / 213
  19. zsh ๐Ÿ• The ultimate modern shell ๐Ÿ• bash compatible ๐Ÿ•

    Highly customizable ๐Ÿ• Advanced completion system ๐Ÿ• Brought the "plugin system" to the shell world 70 / 213
  20. Limitations ๐Ÿ• Because it's pipeline-based ๐Ÿ• All inputs and outputs

    are strings ๐Ÿ• test commands does all the hard works under the hood 73 / 213
  21. test command basics % test 1 = 1 % echo

    $? 0 % test 1 = 2 % echo $? 1 74 / 213
  22. A tricky alias for test, [ % if [ "$FOO"

    = "hello" ]; then > echo true > fi 75 / 213
  23. Trickiest part in sh languages ๐Ÿ• Does all the heavy

    liftings when comparing things ๐Ÿ• I won't go into details, but it has too many features and too many options ๐Ÿ• This makes even a simple if or loop statements hard to write 76 / 213
  24. Too many options ๐Ÿ• -b, -c, -d, -e, -f, -g,

    -h, -k, -n, -p, -r, -s, -t, ๐Ÿ• -u, -w, -x, -z, -L, -O, -G, -S, ๐Ÿ• file1 -nt file2, file1 -ot file2, file1 -ef file2, ๐Ÿ• string, s1 = s2, s1 != s2, s1 < s2, s1 > s2, ๐Ÿ• n1 -eq n2, n1 -ne n2, n1 -gt n2, n1 -ge n2, n1 -lt n2, n1 -le n2 77 / 213
  25. ๏ฌsh ๐Ÿ• More modernized shell than zsh ๐Ÿ• Very much

    opinionated ๐Ÿ• Strong functions ๐Ÿ• Aggressive completion ๐Ÿ• Just works without lots of configurations ๐Ÿ• Unlike zsh 79 / 213
  26. The ๏ฌsh language ๐Ÿ• Trying to improve bash usability ๐Ÿ•

    I can understand the motivation ๐Ÿ• But the language design is... still not intuitive ๐Ÿ• I mean it doesn't feel like "my language" 82 / 213
  27. ๏ฌsh ๐Ÿ• So it failed to dominate the market ๐Ÿ•

    Many people are still living with zsh 83 / 213
  28. The feature that we need for our endgame shell ๐Ÿ•

    Ruby as the scripting language! 86 / 213
  29. Reish again ๐Ÿ• Even the creator of irb couldn't finish

    it ๐Ÿ• Why did I thought that I can do it? 88 / 213
  30. History ๐Ÿ• I started working on it from 1st, January

    this year ๐Ÿ• Roughly done in about two weeks ๐Ÿ• It's been my main login shell since then 90 / 213
  31. Features ๐Ÿ• Written in pure Ruby ๐Ÿ• bash compatible ๐Ÿ•

    All existing bash scripts should just work ๐Ÿ• Ruby-flavored extended syntax ๐Ÿ• Covers most of zsh features ๐Ÿ• Just works without lots of configurations 91 / 213
  32. Demo (completion) % cd % cd ~ % git %

    gem % bundle % rbenv 92 / 213
  33. Ruby ๏ฌ‚avored language ๐Ÿ• if, elif, fi => if, elsif,

    end ๐Ÿ• Blocks ๐Ÿ• Method chaining ๐Ÿ• lambda literal ๐Ÿ• p command for inspecting in Ruby level ๐Ÿ• Ruby constant reference ๐Ÿ• Use of Ruby Threads for background processing ๐Ÿ• And many more experimental features 93 / 213
  34. Blocks ๐Ÿ• if/loop commands take { } block that is

    evaled in Ruby ๐Ÿ• We can forget the test command ๐Ÿ• Enumerator ๐Ÿ• each, select, map ๐Ÿ• it is available 94 / 213
  35. Demo if { 1 + 1 == 2 } echo

    "1 + 1 is 2" end 95 / 213
  36. Method chaining ๐Ÿ• Commands take () like methods ๐Ÿ• So

    pipelines can be written as method chaining 97 / 213
  37. Ruby constant reference ๐Ÿ• There's no command or feature that

    starts with a Capital letter in UNIX ๐Ÿ• So, we can assume that if it starts with A-Z, it must be a Ruby constant 101 / 213
  38. Implementation ๐Ÿ• Reline based, like irb, as I told you

    ๐Ÿ• And heavily relies on the Ruby stdlibs 109 / 213
  39. Standing on the shoulders of giant Ruby ecosystem ๐Ÿ• Reline

    ๐Ÿ• FileUtils ๐Ÿ• Open3 ๐Ÿ• Thread ๐Ÿ• did_you_mean etc. 110 / 213
  40. Naming software is hard... ๐Ÿ• The gem name "rubish" was

    already taken... ๐Ÿ• Installable via homebrew for now... 113 / 213
  41. The "system ruby" problem ๐Ÿ• A shell has to be

    loaded before loading rbenv or such ๐Ÿ• So the shell runs on "system Ruby" ๐Ÿ• Which is still 2.6 on Mac ๐Ÿ• Which is very old 114 / 213
  42. The "system ruby" problem => Resolved! ๐Ÿ• Fixed by changing

    the executable to a bash script that detects other rubies ๐Ÿ• (This slide was added after the talk) 115 / 213
  43. Textbringer ๐Ÿ• shugo's editor in pure Ruby ๐Ÿ• Built on

    top of Curses ๐Ÿ• Emacs clone 122 / 213
  44. @shugo (Shugo Maeda) ๐Ÿ• Creator of lots of weird (and

    lots of useful) features of Ruby ๐Ÿ• Creator of protected scope ๐Ÿ• Creator of callcc ๐Ÿ• Creator of Refinements ๐Ÿ• Creator of eruby (ERB specification) ๐Ÿ• Creator of mod_ruby (Apache module) ๐Ÿ• Creator of net-ftp/net-imap ๐Ÿ• Maintainer of Curses ๐Ÿ• Matz's boss at his company, NaCl 123 / 213
  45. Curses ๐Ÿ• Ruby binding for curses, Ncurses, and PDCurses ๐Ÿ•

    For building richer TUI tools ๐Ÿ• Like tetris ๐Ÿ• Or text editor ๐Ÿ• shugo maintains this so his text editor keeps working 124 / 213
  46. rfd ๐Ÿ• https://github.com/amatsuda/rfd ๐Ÿ• "FD" (a legendary Japanes filer for

    MS-DOS) clone ๐Ÿ• Vim-ish UI ๐Ÿ• Pure Ruby ๐Ÿ• On top of Curses 126 / 213
  47. Features ๐Ÿ• Covers most of basic features of NeoVim ๐Ÿ•

    Some critical features like async, LSP, and tree sitter are not supported yet ๐Ÿ• Covers most of settings (:set) ๐Ÿ• Kind of emulates VimScript ๐Ÿ• Executes Lua scripts! 133 / 213
  48. Running Lua scripts from Ruby ๐Ÿ• I'm just using rufus-lua

    gem ๐Ÿ• And it magically works! 134 / 213
  49. rufus-lua ๐Ÿ• A Ruby binding that calls Lua engine via

    FFI ๐Ÿ• Created by jmettraux 135 / 213
  50. @jmettraux (John Mettraux) ๐Ÿ• A gentleman from Switzerland ๐Ÿ• Lives

    in Hiroshima, Japan ๐Ÿ• Author of rufus-scheduler and the family 136 / 213
  51. That's everything that I wrote in my proposal ๐Ÿ• A

    pure Ruby UNIX shell ๐Ÿ• A pure Ruby text editor 138 / 213
  52. Missing features ๐Ÿ• Terminal integration ๐Ÿ• Like moving cursor and

    copy & paste with keyboard shortcuts ๐Ÿ• Like GNU Screen 145 / 213
  53. That's something beyond shell's domain ๐Ÿ• That's terminal emulators' territory

    ๐Ÿ• For instance, kitty implements them on its own 146 / 213
  54. Python? ๐Ÿ• If there's a Python based terminal emulator ๐Ÿ•

    There should be no reason we cannot do it in Ruby!๐Ÿ’ก 150 / 213
  55. And so I made it (and so this talk seems

    to continue a little bit more) 151 / 213
  56. Echoes ๐Ÿ• https://github.com/amatsuda/echoes ๐Ÿ• Pure Ruby terminal emulator ๐Ÿ• Native

    UI components ๐Ÿ• Not based on Reline here ๐Ÿ• Supports only macOS so far ๐Ÿ• So the UI is COCOA based 152 / 213
  57. Features ๐Ÿ• Any shell should work on it ๐Ÿ• Supports

    kitty text sizing protocol ๐Ÿ• So the presentation tool works on it ๐Ÿ• Supports image rendering ๐Ÿ• Even tetris works on it ๐Ÿ• Native UI based features ๐Ÿ• Native dialog! ๐Ÿ• Multiple fonts! ๐Ÿ• Multiple bg colors! ๐Ÿ• With gradations! 153 / 213
  58. A pure Ruby terminal emulator ๐Ÿ• TBH, it'd be hard

    to beat alacritty, Ghostty and such in rendering speed 155 / 213
  59. The CLI dev stack on which everyone lives today ๐Ÿ•

    Terminal Emulator ๐Ÿ• Shell ๐Ÿ• Text Editor 158 / 213
  60. Connected with super legacy APIs ๐Ÿ• When the consoles displayed

    only 8 colors ๐Ÿ• When UNICODE was not a thing ๐Ÿ• When Ruby was not there yet 159 / 213
  61. NORMAL TERMINAL โถ SHELL pty (one byte stream, bidirectional) โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

    โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Terminal โ”‚ โ”‚ Shell โ”‚ โ”‚ โ”‚ keystroke bytes โ”€โ”€โ–บโ”‚ โ”‚ โ”‚ - ANSI โ”‚ โ—„โ”€ echoed keystroke โ”‚- Reline โ”‚ โ”‚ parser โ”‚ + cursor ANSI โ”‚ parses โ”‚ โ”‚ - cell โ”‚ (round-trips) โ”‚ keys โ”‚ โ”‚ grid โ”‚ โ—„โ”€ prompt as โ”‚- prompt is โ”‚ โ”‚ โ”‚ ANSI bytes: โ”‚ formatted โ”‚ โ”‚ โ”‚ "\e[1;32m$\e[0m " โ”‚ as ANSI โ”‚ โ”‚ โ”‚ โ—„โ”€ completion list as โ”‚- completionโ”‚ โ”‚ โ”‚ text + ANSI โ”‚ pre-baked โ”‚ โ”‚ โ”‚ โ—„โ”€ command stdout โ”‚ to bytes โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ (also bytes) โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ 160 / 213
  62. NORMAL TERMINAL โถ SHELL Two parsers (one in each side).

    Every keystroke makes a round trip. Prompt / completion / cursor moves are all flattened to escape codes โ€” the terminal can't distinguish "this byte is part of the prompt" from "this byte is part of command output". Just one big stream. 161 / 213
  63. So we have to perform a lot of String conversion

    dances ๐Ÿ• Here and there between the layers ๐Ÿ• Causes performance overhead ๐Ÿ• Causes mojibake ๐Ÿ• Causes exceptions, e.g. "invalid byte sequence in UTF-8" 163 / 213
  64. Integration ๐Ÿ• What if we run everything in one Ruby

    process? ๐Ÿ• We could skip all the abstractions and legacy APIs in favor of simple Ruby method calls! 164 / 213
  65. You know, that's called "full stack" ๐Ÿ• "full stack" is

    stronger than micro components ๐Ÿ• Ruby is good for building full stack software ๐Ÿ• The web framework proved it already 165 / 213
  66. Echoes integration ๐Ÿ• Echoes directly renders shell outputs via native

    API ๐Ÿ• Skipping legacy UNIX API ๐Ÿ• Skipping Reline as well! 167 / 213
  67. The text editor can be run there ๐Ÿ• Directly from

    with in the terminal emulator via one method call ๐Ÿ• Skipping the whole shell process 169 / 213
  68. So am I reinventing an IDE? ๐Ÿ• Like Rubymine or

    VSCode ๐Ÿ• Well, maybe... 173 / 213
  69. To build everything myself with my favorite language ๐Ÿ• Instead

    of just downloading and using an IDE that is built for general purpose 175 / 213
  70. I made pure Ruby dev tools for you! ๐Ÿ• Please

    try them, and give me feedbacks! 179 / 213
  71. I made pure Ruby dev tools for you! ๐Ÿ• Please

    try them, and give me feedbacks! 180 / 213
  72. I'm not a terminal pro ๐Ÿ• But AI made me

    possible to do this 184 / 213
  73. And so can you, of course ๐Ÿ• We live in

    such an exciting world as a programmer! 185 / 213
  74. Ruby can do anything ๐Ÿ• Ruby is not just a

    language that runs Rails on the servers ๐Ÿ• Ruby has a very rich ecosystem ๐Ÿ• And Ruby is your best friend! 189 / 213
  75. The land where every software that we use is written

    in Ruby ๐Ÿ• So that it's readable ๐Ÿ• So that it's maintainable ๐Ÿ• So that it's extendable 193 / 213
  76. Let's try using Ruby ๐Ÿ• For something that you've never

    tried ๐Ÿ• For tools that you actually use ๐Ÿ• For something that makes your life better ๐Ÿ• Or just for something fun 203 / 213
  77. Q: Why not Rust? Everyone creates such CLI tools with

    Rust (or zig or whatever) these days. Why don't you do so? 209 / 213
  78. A: Why not Ruby? Who decided that Ruby is not

    the language for that? 210 / 213

More Decks by Akira Matsuda

Other Decks in Programming