For a decade (2014-2024), I was a Ruby-only developer. I worked across the Ruby ecosystem—from Rails development to Ruby’s core tooling like IRB, RDoc, and the debug gem. But while I moved around the stack, I stayed within Ruby’s boundaries. Ruby wasn’t just my primary language; it was essentially my only language. That changed in 2025. This year, I’ve contributed to Sorbet (C++), worked on RBS’s parser (C), and am now diving into ZJIT (Rust). A combination of factors enabled this shift—something I’d always dreamed of but was terrified to attempt. But AI coding tools like Cursor and Claude Code—both encouraged at Shopify—have been absolutely career-changing. The Perfect Storm of Opportunity Before diving into the AI aspect, I need to acknowledge two crucial factors that made this transition possible: First, our Ruby DX team’s roadmap shifted to require Sorbet’s support for RBS, which meant I now had to work on projects written in C++ and C—system programming languages that require understanding concepts I’d never encountered in Ruby. Second, Shopify’s Ruby and Rails Infrastructure team is packed with experts who genuinely love sharing their knowledge. Alexander Momchilov, Alexandre Terrasa, Max Bernstein, and many others have been incredibly generous with their time. Those pairing/tutoring sessions gave me the C/C++/JIT fundamentals I needed to even attempt this work. But here’s the thing: great mentors and project opportunities to learn new languages have always existed. What’s different now is how AI has fundamentally changed the learning curve. The Complexity of System Programming Projects Let me use ZJIT, a new just-in-time (JIT) Ruby compiler, as an example (to learn more about it, check out this RailsAtScale post by Max). This project perfectly illustrates the challenge: it requires both deep conceptual understanding (how JITs and GC work) AND language/tool-specific expertise (Rust idioms, C programming conventions, Ruby’s build system). Working on ZJIT means constantly juggling: Rust (what ZJIT is written in) C (what Ruby is written in) General JIT knowledge (compiler theory, optimization strategies) ZJIT-specific concepts (its particular architecture and design decisions) Ruby internals (how the VM actually works) Ruby build systems (which have their own conventions on top of tools like autoconf and Makefile that I’d rarely encountered before) A single pull request typically touches 2-4 of these areas simultaneously. Claude is remarkably helpful with the first three—language syntax, general concepts, standard patterns. It’s hit or miss for the last three—project-specific knowledge, deep internals, and build system quirks. But that’s still cutting my learning blockers in half. AI as a Complementary Pairing Partner The real breakthrough came when I stopped thinking of AI as a code generator and started treating it as a pairing partner with complementary skills. This isn’t about AI writing code for me. If I expected Claude to implement ZJIT features correctly, I’d likely be frustrated and probably waste more time than I’d save. The AI lacks the project-specific context and deep domain knowledge required. Instead, we act as a pair of engineers with different strengths. While it knows more about language-specific syntax and patterns than I do, I understand the project requirements and constraints better (and hopefully have better taste). This creates a productive learning dynamic where: I provide task requirements and project context AI identifies existing patterns and acts as the language expert I question why certain approaches would or wouldn’t work AI explores the theory, either through actually changing code or simply inferring, and gives me the result Through the conversation, I’m learning both the language AND how to apply it effectively For example, when I need to profile a Ruby bytecode instruction for ZJIT, I can ask Claude Code to examine previous PRs that did something similar and explain the parts I don’t understand line by line. I can ask “dumb” questions like “Why do JIT compilers need profiling?” without feeling like I’m wasting someone’s time. I get immediate clarification on unfamiliar Rust syntax. And throughout this process, I’m building my understanding of both the language and the system. Of course, there were also times where we were both heading in the wrong direction together, and could only be saved by my mentors and teammates’ clarification and knowledge sharing. AI accelerates learning, but human expertise remains irreplaceable for course correction. The Language Barrier Is Dissolving What excites me most is that we no longer need to spend 100+ hours learning C before making our first contribution to a C project. AI acts as a second pair of eyes, unblocking us from silly rookie mistakes—using the wrong syntax to declare variables, misunderstanding type conventions, or fighting with unfamiliar tooling. We can start contributing meaningfully from day one, learning what we need as we go. This doesn’t replace deep expertise—our team’s language experts remain invaluable. But it does mean that being productive in multiple languages is now achievable for more developers. The cognitive load of syntax, standard library functions, and common patterns can be offloaded, letting us focus on the actual problems we’re solving. For someone who spent a decade as a “Ruby developer,” becoming a multi-language developer in less than a year feels revolutionary. And I suspect I’m just early to a trend that will reshape how we think about programming language specialization entirely.