Summarized using AI

Yes, You Can Work on Rails & any other Gem

Kasper Timm Hansen • July 08, 2025 • Philadelphia, PA • Talk

Introduction

This talk, delivered by Kasper Timm Hansen at RailsConf 2025 and titled "Yes, You Can Work on Rails & any other Gem", is aimed at demystifying the process of engaging with the Rails source code and contributing to open source gems. The session focuses on developing skills and confidence to read, navigate, and understand complex codebases, not just in Rails but across Ruby gems more generally. Hansen shares practical strategies and tools designed for long-term development and compounding learning effects, illustrated with live demos and practical anecdotes.

Key Points

  • Reframing Code Navigation as Language Learning:

    • Programming is compared to learning a language, emphasizing the importance of understanding both grammar (syntax, structure) and vocabulary (methods, classes).
    • Growth comes from improving technical literacy incrementally, much like developing fluency.
  • Integrated Approach to Upskilling:

    • Four components are outlined for ongoing skill development:
    • Knowing Your Tools: Utilize tools like the console, Ruby and Rails documentation, and commands such as bundle open, method, and debugger to explore code interactively.
    • Parsing Code Faster: Practice being exposed to new source files, focusing on recall over retention, and build familiarity through active engagement rather than passive reading.
    • Leveraging Network Effects: Learn new concepts by comparing and contrasting with known concepts, using interactive exploration and experiment-driven learning (e.g., investigating methods like itself and their behavior).
    • Compound Exercises: Engage in exploration of open source codebases, using the process of following rabbit holes through unfamiliar code to train discernment and develop context. Emphasis is on progressive understanding rather than exhaustive study.
  • Practical Demonstrations:

    • Hansen conducts live walkthroughs of Rails internals (such as initializers, Rails engines, and the module ancestry chain), showing how to trace method implementations and module inclusions using built-in tools and GitHub's interface.
    • Strategies for navigating uncertainties or hitting dead ends are shown, modeling a resilient and inquisitive mindset.
  • Anecdotes and Illustrations:

    • Several anecdotes about helping developers understand Ruby idioms (like itself, dup, object_id) are used to reinforce experimental and comparative learning.
    • The concept of "hitting bedrock" is introduced to describe the satisfying moment when exploration reaches an irreducible implementation detail.
  • Importance of Iterative and Context-Building Learning:

    • Encourages small, manageable learning steps that build upon one another over time.
    • Emphasizes that expertise is more about the accumulation of context than innate intelligence.

Conclusion/Takeaways

  • Contribution to Rails and other gems is accessible with the right learning strategies.
  • Progress is achieved through deliberate exposure, experimentation, and the development of intuition.
  • Building familiarity and context in a codebase takes time, but incremental and compound learning accelerates this growth.
  • Tools, documentation, and live exploration are key, but the most crucial asset is the learner's own curiosity and resilience.

Yes, You Can Work on Rails & any other Gem
Kasper Timm Hansen • Philadelphia, PA • Talk

Date: July 08, 2025
Published: July 23, 2025
Announced: unknown

Have you ever wanted to dig into the Rails source, but it just seems too daunting?

Good news! In this session, we'll look at practical tools to level you up, so you can make it happen. Even better, these navigation tools work for any gem & your day-to-day codebase too.

We'll use live demos to engage with real code from gems & Rails. We'll improve our ability to sight-read code & identify patterns within swiftly. You'll see how to refine your learning process so it yields compounding results to make you a better developer & teammate.

RailsConf 2025

00:00:16.880 Hello. The mic is working. Okay, cool.
00:00:19.600 Welcome to the session. Yes, you can
00:00:20.800 work on Rails any uh let's make this
00:00:23.279 Rails Cup last. Um hi, I'm Casper. You
00:00:27.199 can find everything about me on this web
00:00:29.840 address. I specialize in domain modeling
00:00:31.519 and sort of training beyond the usual
00:00:32.960 which is where some of this comes from.
00:00:34.320 We'll talk about today. In this talk,
00:00:36.320 we'll cover how I build skills and you
00:00:38.320 can too. We'll be focusing on the long
00:00:40.800 term. So, we won't cover mechanics of
00:00:42.800 contributing. Yasu who's sitting here,
00:00:44.640 you have a talk on first that's covering
00:00:46.160 it, right? Perfect. Uh thought so. Um
00:00:49.760 and after this talk I hope you'll have
00:00:51.120 more confidence to explore um you know
00:00:54.160 working on figuring things out and we'll
00:00:56.079 hopefully give you some tips to sort of
00:00:57.280 bump your information throughput by 20%.
00:01:00.000 Uh but let's do some uh table setting
00:01:02.160 first of all the way I like to think of
00:01:04.080 it to me code assistant code
00:01:05.920 communication is the communication you
00:01:07.360 have yourself your past experience where
00:01:09.439 you like to go when you're incorporating
00:01:11.040 things like this like a talk or a blog
00:01:13.119 post talk with customers and so forth.
00:01:15.520 Um, but what I've also experienced is
00:01:17.200 that really good stuff happens in
00:01:18.320 communication. And to be able to do have
00:01:21.119 that good stuff happen, we need more
00:01:22.479 overhead and capacity to see tradeoffs
00:01:24.560 and be able to weigh them and talk about
00:01:26.400 them and figure things out. But if we're
00:01:28.640 too fixed on code, we'll never get
00:01:30.720 there. In other words, we're if we're
00:01:32.560 stuck on mechanics, we'll miss out. So,
00:01:34.880 I like to compare this to speaking a
00:01:36.560 language where there's this difference
00:01:38.880 between knowing words and being a
00:01:40.720 speaker or reader. But I also think
00:01:43.200 there's another part we miss here which
00:01:44.880 is that programmer languages are also
00:01:46.560 just languages. I think we keep
00:01:48.479 overindexing on the programming part and
00:01:50.720 getting things correct which you
00:01:51.920 definitely need but in turn we neglect
00:01:54.079 this language focus where programming
00:01:56.640 languages also have grammar and
00:01:58.079 vocabulary and Ruby keeps seeing
00:01:59.680 upgrades to grammar like pattern
00:02:01.680 matching or additions to the vocabulary
00:02:03.680 with new methods or classes like data.
00:02:06.320 So in my opinion, in order to grow, your
00:02:08.000 process must focus on incorporating this
00:02:10.239 grammar and vocabulary. So you can build
00:02:12.160 that bridge between what you know now
00:02:14.400 and what you're working on knowing next
00:02:16.239 essentially. Uh in other words, you want
00:02:18.160 to improve your technical literacy to
00:02:19.760 then improve to increase your own
00:02:21.280 impact. And then you're looking to do
00:02:24.560 enough of this that you sort of achieve
00:02:26.080 escape velocity where you then more
00:02:28.319 become a speaker if you're born into
00:02:30.160 language analogy. So here's how I can
00:02:32.080 help you. Uh I've done a lot of
00:02:33.280 experience with this. I've been in and
00:02:34.480 around and ahead of Rails in ways. These
00:02:36.560 days I'm 140 to Rails. It's been a
00:02:38.800 while. I was on a core team for minus
00:02:40.720 six years. You can do the math. It
00:02:41.840 checks out. U got this commits yada
00:02:44.319 yada. Uh lots of poor Chris reviews and
00:02:47.280 I've also screwed a ton up doing this
00:02:49.360 too. I've written code that could have
00:02:51.120 been clearer and I've sent messages
00:02:52.480 could have been kinder to contributors
00:02:54.000 even under the pressure to try to move
00:02:55.519 things forward and a pretty big issue
00:02:58.000 backlog around Rails. I've done a bunch
00:03:00.080 of work uh on assorted number of gems.
00:03:02.640 Um I'm still a number contributor to a
00:03:05.120 bunch of these even though I haven't
00:03:06.000 touched them in years which I think is
00:03:07.280 kind of interesting. Um I also done some
00:03:09.680 of my own things where I'm trying to
00:03:11.120 take things a little bit further or
00:03:12.319 explore new ideas. Uh probably the one I
00:03:14.400 want to look at is Oaken which is sort
00:03:15.840 of my revision of fixtures and factories
00:03:17.920 and seeds as sort of one unit to make
00:03:20.480 your opcoaph more visible and make it
00:03:22.800 easier to sort of generate a stable data
00:03:24.400 set to drive over time. Thomas is do you
00:03:27.200 want to do you want Yeah, perfect. Okay,
00:03:29.840 cool. Um, what drives me to look at
00:03:32.480 these things is essentially coming up
00:03:33.920 with an idea, sketching it out and
00:03:35.680 seeing if it work. It becomes the fun of
00:03:37.680 expanding what's out there. Because the
00:03:39.360 way I see it, if there's a gem that's
00:03:40.720 out there, then great, it's already out
00:03:43.440 there, but what else can we do? And
00:03:45.519 these tools can also serve as
00:03:46.799 inspiration for other people to then try
00:03:48.319 their idea and spark something for them.
00:03:49.840 The way I see this is essentially the
00:03:51.200 joy of using a language and then seeing
00:03:52.879 where it takes you and and being in a
00:03:54.640 conversation. So, this is what this talk
00:03:56.560 is going to be about today. is
00:03:57.840 essentially going to be my integrated
00:03:59.200 approach for upskilling while working to
00:04:01.760 do this kind of stuff over time. The
00:04:04.640 result is we won't really work that
00:04:06.400 differently. We just work in a way that
00:04:08.159 sets us up for the future. And this
00:04:10.159 involves a bunch of bite-sized learning.
00:04:13.120 These four components where it's knowing
00:04:14.560 your tools, parsing code faster, using
00:04:16.880 network effects, and then these compound
00:04:18.720 exercises. In real life, these four work
00:04:20.479 in tandem and blur together a bit.
00:04:22.160 That's kind of part of the point. And
00:04:23.840 also, I find this is generally fun to
00:04:25.520 work this way, at least for me. So, you
00:04:27.600 know, but okay, we'll get into in a
00:04:30.080 little bit.
00:04:35.759 So, first up, it's knowing your tools.
00:04:37.360 And I think we're going to have to
00:04:38.160 acknowledge the most important tool in
00:04:39.919 the room, and that's you. Um I because
00:04:42.880 when I look out this room, I see some
00:04:44.320 pretty giant tools. Thank you,
00:04:46.560 everybody. Okay. Uh second of all, I
00:04:48.800 pretty much always have a console open
00:04:50.160 whether or not it's just a plain or a
00:04:52.080 Rails console to muck with things and
00:04:54.080 play around with stuff and sort of get a
00:04:55.520 feel for them. And then I like to
00:04:57.199 supplement that with looking things up
00:04:58.800 in the index. You got ruby.org. I know
00:05:01.120 there's more work done on the official
00:05:02.560 docs. I still end up using this for
00:05:04.400 right now. Um or the Rails documentation
00:05:07.039 for all the APIs on there. And that's
00:05:09.120 for when you encounter new work. You
00:05:10.560 want to go either look it up there or
00:05:12.000 maybe play around with the console first
00:05:13.199 or back and forth. The point you want to
00:05:15.280 get to here is you want to get better at
00:05:17.360 looking things up and then skimming the
00:05:18.880 docs. You don't have to understand all
00:05:20.240 of it, but over time you'll get more
00:05:21.520 efficient at this. you look things up
00:05:22.880 faster and understand them faster, but
00:05:25.120 you also end up with a larger vocabulary
00:05:26.720 where you don't always have to look
00:05:28.000 stuff up. And I find that this makes me
00:05:29.759 really efficient in terms of coming up
00:05:31.280 with things and figure out what I want
00:05:33.440 to do and play around with alternatives
00:05:34.800 as well because it's less draining to do
00:05:36.880 so. Okay, further on, if you want to get
00:05:39.039 into the code, I use bundle open all the
00:05:41.600 time. It'll fetch the well, it'll open
00:05:43.520 up the gym you've got installed locally.
00:05:45.120 So if you're on red 6.1 and here do
00:05:47.520 bundle active record, it'll be 6.1
00:05:50.080 versus 8.0 know for instance and then
00:05:52.080 while you're in there you could drop
00:05:53.120 debugger lines or put statements. I tend
00:05:55.360 to just use P because you get the
00:05:56.880 inspect output and it's like one
00:05:59.759 character instead of four and if you
00:06:01.680 forgot where you put all those you can
00:06:02.880 do bundle pristine to get back to the
00:06:05.520 start. Um, I also use method a bunch in
00:06:11.360 the console or in the code where you
00:06:13.120 could do user method has many. You get a
00:06:15.280 source location and then I in my editor
00:06:18.479 I can command click and I'll be taken
00:06:19.600 right to where that source is. Sometimes
00:06:22.000 there's a method that's overwritten a
00:06:23.440 bunch. So, and stay with this uh the
00:06:26.720 method method returns a method object
00:06:28.479 that you can call further methods on.
00:06:30.720 Everybody with me? Okay, cool. And
00:06:32.400 that's what happens in number two here.
00:06:33.840 We're recalling passing and render
00:06:35.840 getting a method object back. I think
00:06:37.759 it's called an onbound method. I don't
00:06:39.199 remember. But then if it's overridden
00:06:41.440 because of the way Ruby works with
00:06:42.639 modules and prepended modules and yada
00:06:44.319 yada, you can then do super method to
00:06:45.840 get the next one and then super method
00:06:47.360 to get the next layer and super until
00:06:49.039 you return nil essentially. Um so you
00:06:51.360 could basically get source locations for
00:06:53.120 each of those and then click through and
00:06:54.479 see where how it's um dynamically put
00:06:57.680 together at runtime essentially.
00:06:59.280 Sometimes you'll also encounter methods
00:07:01.520 where if you call source location on it,
00:07:03.440 it'll return nil. That's actually a sign
00:07:05.039 that it's written in C. So it's not
00:07:06.720 written in Ruby just so you don't get
00:07:08.479 confused. It returns nil. Where's that?
00:07:10.800 Uh half the battle in many ways is
00:07:12.800 knowing where to look and then figure
00:07:14.080 out how to use it. That's sort of the
00:07:15.919 point of this section. Um
00:07:18.400 second up is parsing codes faster.
00:07:22.400 Um for me, the way I like to think of it
00:07:24.400 is it's not so much reading, it's
00:07:26.319 engaging with it. You want to be exposed
00:07:28.880 to new code essentially. You want to get
00:07:31.759 comfortable sort of blasting yourself
00:07:33.280 with new source files and then not feel
00:07:35.280 overwhelmed. Can you have the file on
00:07:37.039 screen and have it just be there and not
00:07:40.160 feel, you know, scared of it or
00:07:42.240 whatever? Um, sometimes that happens
00:07:44.160 like this seems really overwhelming. The
00:07:46.560 other way I like think is I think
00:07:47.840 sometimes people don't do this because I
00:07:49.199 think it's about retention as in holding
00:07:51.919 on to things for dear life, but that's
00:07:53.840 not really the way I like to do it. To
00:07:55.919 me, memory is more about recall where
00:07:57.440 you actually want to catch and release
00:07:58.800 over and over. You don't want to try to
00:08:00.400 hold on to anything. You'll come back
00:08:02.479 over time because over time, what you
00:08:04.479 want to do is build familiarity with the
00:08:06.160 stuff you see. So, when you see that
00:08:07.840 method or class again elsewhere, you
00:08:09.919 know it. This is where it comes into uh
00:08:13.199 using something like the console again
00:08:14.479 to really settle it in. And with
00:08:16.319 language, we know this. We know there's
00:08:18.400 different levels of knowing that there's
00:08:20.080 partial understanding and we can
00:08:21.360 progressively understand more. It's not
00:08:23.360 a binary where it's like you know all of
00:08:25.199 it or none of it.
00:08:27.440 I think what you want to focus on too to
00:08:30.319 gain experience to be more active as
00:08:32.240 opposed to passive. It is not just
00:08:33.680 reading it is engaging with it. Only
00:08:35.680 looking at words won't get you there.
00:08:37.839 You want to work on internalizing what
00:08:39.760 you see. So you can be an active
00:08:41.120 participant and make your own choices.
00:08:43.760 And also acknowledge that sometimes
00:08:45.279 internalizing can feel more vulnerable
00:08:46.880 because you make your own choices then
00:08:48.320 you're on the hook for it. you'll be
00:08:50.000 more exposed because you're making the
00:08:51.680 choice to care. But I also say I don't
00:08:54.240 really see a way out of this. So I
00:08:57.120 recommend just taking ownership of it
00:08:58.800 partly because the rewards are worth the
00:09:00.399 risks but also well again I don't see a
00:09:02.959 different way of doing it if you want to
00:09:04.399 be good at stuff. Uh the first tier is
00:09:06.880 then using network effects. It's where
00:09:08.720 you learn new things through contrast
00:09:11.120 with what you know. So recently I was
00:09:13.120 walking someone through this uh they had
00:09:14.800 never seen like they've seen an enome
00:09:16.720 before and using percent I to generate a
00:09:20.240 symbol array but they hadn't seen index
00:09:22.080 they hadn't seen itself. So they were
00:09:25.200 like what does itself do? So I wanted to
00:09:27.680 walk them through the process I do to
00:09:29.519 learn things itself is itself quite
00:09:32.640 simple. Um but I still want to show you
00:09:34.640 what the process looked like when I walk
00:09:36.000 them through it. So the first thing I do
00:09:37.600 I just want to run it in the console
00:09:39.120 literally just to see what happens. find
00:09:41.360 some object we can call the method on
00:09:43.519 and see basically what happens and in
00:09:45.200 this case we return the same thing
00:09:46.720 seemingly then I want to vary the input
00:09:49.600 or this case the receiver this is the
00:09:51.920 same for ask is the same for array can
00:09:53.440 we call it a nil for instance and keep
00:09:55.200 playing around with that and generate
00:09:56.480 more ideas for what else I want to see
00:09:58.480 this thing does it change somehow and
00:10:00.560 then I like to use something else I know
00:10:03.120 so for instance if I know what object ID
00:10:05.040 is where we'll return the same integer
00:10:07.440 if it is the same object in memory Here
00:10:10.720 we can see that it actually is because
00:10:13.760 itself returns the object itself. We'll
00:10:15.920 get to that. Um,
00:10:18.000 and then I also like to keep going when
00:10:20.240 we're doing this live with the person. I
00:10:22.560 also thought about well what if we
00:10:23.600 contrast it with dub which is just short
00:10:25.440 for duplicate and seeing how it actually
00:10:28.160 seem looks like it's returning the same
00:10:29.839 thing where it's also returning the same
00:10:31.680 string yo there but then if you look at
00:10:33.839 object ID suddenly it's returning a
00:10:36.240 different number because it's returning
00:10:38.079 making a new copy every time so it's not
00:10:40.399 the same instance in memory it's
00:10:42.480 slightly different there so for me what
00:10:45.120 you want to do is compare and contrast
00:10:47.600 to make things more vivid you're trying
00:10:49.600 to use one thing you know in that kind
00:10:51.360 of network to then level to then uh I
00:10:54.720 have it here got myself to what you know
00:10:58.079 helps you poke and prod the next thing
00:10:59.680 from different angles and this is where
00:11:01.920 staying scrappy really helps you want to
00:11:04.079 come up with new ideas for poking
00:11:06.160 something to make it settle and solidify
00:11:08.480 your knowledge of how something works
00:11:10.399 and then we're getting back to this is
00:11:11.920 where it comes back into then knowing
00:11:13.600 the tools playing around with a console
00:11:15.440 maybe looking at the documentation and
00:11:16.800 using both of those to really settle it
00:11:19.200 in then later on that'll then help you
00:11:21.360 parse the code faster because you
00:11:22.720 recognize how it works by looking at it
00:11:25.040 again like the developer I was talking
00:11:26.560 to where they hadn't seen index by or
00:11:28.399 itself and used in that way becomes
00:11:30.640 clearer um over time really what you
00:11:33.519 want to focus on is not so much how you
00:11:35.120 currently navigate but it's growing that
00:11:37.200 extra witness capacity to see what else
00:11:39.839 could I do um how else could I navigate
00:11:42.480 this what else could I try what else
00:11:44.320 would help me and then the fourth tier
00:11:47.440 is really these compound exercises this
00:11:50.000 was a term I learned recently from
00:11:51.680 following Casey Johnson who I don't know
00:11:53.680 if anybody knows Casey she writes about
00:11:55.040 lifting weights and why you should get
00:11:56.240 into it. She's got a great blog and this
00:11:58.160 program called liftoff which is where I
00:11:59.440 learned the term but basically the idea
00:12:01.040 is that these exercises give you greater
00:12:02.800 gains in shorter time again in sort of a
00:12:04.480 weightlifting scenario. example lift is
00:12:06.639 squats where you're combining four or
00:12:08.399 five different muscle groups but then
00:12:10.399 you also get some extra benefits out of
00:12:12.160 this combination where you have to help
00:12:14.959 it helps your coordination and your
00:12:16.639 balance something you wouldn't get if
00:12:18.560 you just made a really simple isolated
00:12:20.320 exercise yet the fact that you had to
00:12:22.240 coordinate all these things together at
00:12:23.279 once improves you faster so I think in
00:12:25.279 programming you want something similar
00:12:26.560 you want to blend things to get extra
00:12:28.959 benefits and to me this is all about
00:12:31.040 exposure to open source where each new
00:12:33.200 thing you encounter out there can become
00:12:36.160 a springboard where you can go through
00:12:37.920 this process again, see it on the
00:12:39.600 screen, figure out how to run it
00:12:41.120 locally, grab pieces of it to explore
00:12:44.160 and then use the look it up in the index
00:12:46.399 as well to help facilitate that more.
00:12:49.040 Over time, they'll become more familiar.
00:12:50.639 So, it'll parse that code faster when
00:12:52.000 you see it again. And you can use that
00:12:54.560 learning that one thing then becomes
00:12:56.800 part of this network. You can use it to
00:12:58.240 learn other things faster. And then uh
00:13:01.040 another thing for this that's kind of
00:13:02.399 weird is I think you want to use rabbit
00:13:04.320 holes when you're exploring open source
00:13:06.079 code. I think people get scared of this
00:13:07.920 because it's like how do you navigate
00:13:09.279 this stuff? It gets really overwhelming.
00:13:11.360 But to me that's the whole point of this
00:13:12.959 compounding exercise. You want to do
00:13:14.720 this because it'll train your
00:13:16.000 discernment. You'll ask questions like
00:13:17.839 is this the right place? Do I need to go
00:13:19.519 somewhere else? Do I have too many
00:13:20.800 things going on? Am I too deep? Do I
00:13:23.279 need to go further actually? And what
00:13:24.720 else do I need? you will start learning
00:13:26.800 how to figure out where to where to go
00:13:29.839 essentially that balance over time which
00:13:32.000 you wouldn't get if it's very simple and
00:13:33.920 what you're looking for is progress not
00:13:35.600 exhaustion again it's not a binary again
00:13:37.680 like language but a pro gradual
00:13:39.519 understanding can prove over time so if
00:13:41.440 you only got 5% this time that's cool
00:13:43.279 you can come back later and get another
00:13:44.800 5% or 10% whatever it is this is the
00:13:47.200 same as language acquisition take the
00:13:48.959 longer term view it'll take time and
00:13:51.120 that's good also take breaks but then
00:13:53.360 keep going and Then we'll encounter this
00:13:56.320 what has happened to me before. I like
00:13:58.079 to call it hitting bedrock. If you use
00:13:59.920 one of these rabbit holes and go in it
00:14:01.600 long enough tracing true, at some point
00:14:04.320 you'll hit bedrock, which is going to
00:14:05.839 feel really good. It might be a method
00:14:07.680 just like returning a true or false
00:14:08.959 where you literally can't go any
00:14:10.160 further. And then what happens is you'll
00:14:12.079 start going back up again. And to me at
00:14:14.720 least, it feels like a real
00:14:16.800 accomplishment. And also just feels
00:14:18.639 really good to start collapsing those
00:14:20.000 things. Oh, I now know that I can't go
00:14:22.240 further in this thing. And hitting these
00:14:24.560 points also becomes kind of a turning
00:14:26.959 point where if you then try the next
00:14:28.560 rabbit hole, you can actually shorten it
00:14:30.000 because you've gone through that
00:14:31.040 process. So a case that happened not too
00:14:33.760 long ago, I was walking someone through
00:14:35.199 how action curl loads helpers. Uh we
00:14:38.320 encountered this line. It said helpers
00:14:39.519 for modification. Ball and bas showing
00:14:42.800 well if you already know what modular
00:14:44.240 ball is, you don't have to go any
00:14:45.600 further. You could stop it right here.
00:14:47.440 And not only that, it will also give you
00:14:49.040 clues for what helpers for modification
00:14:50.560 returns. Of course, this is Ruby. it
00:14:53.120 could return anything if you override it
00:14:54.720 or whatever but it might be a clue for
00:14:56.639 what helpation is which is a module. Um
00:14:59.920 so the whole point of all this
00:15:01.120 bite-sized learning is that eventually
00:15:03.279 it will become intuition. Intuition can
00:15:05.920 bring you a lot of speed where you
00:15:07.440 traverse and know things using a lot
00:15:09.680 less energy and this goes back to this
00:15:11.760 focus on grammar vocabulary. you will
00:15:13.600 suddenly have that capacity and that
00:15:15.120 overhead same as when speaking a
00:15:16.560 language becomes easier to generate
00:15:18.320 sentences or you know par paragraphs or
00:15:20.959 I can see the story now as opposed to
00:15:22.480 just being stuck in the mechanics but
00:15:24.160 for this to work you need to focus your
00:15:25.839 accuracy you need to get in there
00:15:28.079 otherwise it won't be reliable and you
00:15:29.920 won't trust it and you can't get those
00:15:31.600 speed benefit fits what you want to do
00:15:34.639 is develop context over time all this
00:15:38.079 stuff is figuring out how things fit
00:15:40.000 together where would I use this where
00:15:41.680 would I not use this And it takes a
00:15:43.440 while to do. But I also want to let you
00:15:45.519 know that all the people you see who can
00:15:46.800 do the things you want to do, it is not
00:15:48.399 so much smarts, it's context. I built
00:15:51.120 that context for myself with this
00:15:52.639 integrator approach. So those things I
00:15:55.040 want to do are way more in reach again
00:15:57.120 over time and it'll take time. Keep
00:15:59.279 going.
00:16:00.959 Uh I think we'll do we're actually got
00:16:02.800 to do a live demo a little bit, but just
00:16:04.880 again here's where I'm at. You can find
00:16:06.399 all my links here if you want to blog
00:16:08.240 post that kind of stuff. I focus on
00:16:09.759 domain modeling and training beyond the
00:16:11.279 usual. So for the last Rails cup, what I
00:16:14.000 want to do is I want to put all this
00:16:15.440 stuff together. So I want to try to see
00:16:17.120 if we can explain something in Rails. Uh
00:16:19.040 you shout it out. Don't like shout out
00:16:21.199 actor record or something like that.
00:16:22.480 Make it a little bit smaller. Um you
00:16:25.040 could think about a little bit. How much
00:16:26.079 time do we have? Oh, we have plenty of
00:16:27.360 time. Cool.
00:16:33.680 Accent text. Okay. I think it might be a
00:16:36.320 little bit too big. If someone else has
00:16:37.519 something else, let's try it out. I
00:16:39.680 might still go for it.
00:16:42.959 Sorry, what did you say?
00:16:45.360 Meta programming. Uh, I would like
00:16:47.360 something in Rails. We could try metapro
00:16:49.120 too.
00:16:52.000 Sorry, what?
00:16:54.560 Class eval. Uh, let's pick something in
00:16:56.800 Rails.
00:16:58.560 Initializes. Okay. Do you Shelby, are
00:17:02.079 you happy with that? Cool. Let's see if
00:17:04.480 we can do that. Okay. So, what do I do?
00:17:06.880 I need to switch this plate in. I know
00:17:09.280 how to do it. mirror.
00:17:11.439 That works. Cool. And now we got Oh, and
00:17:13.199 now it's very tiny. Okay, let's see.
00:17:16.799 How's the font size looking up for you?
00:17:18.640 This looks good here. I think this is
00:17:21.280 better. Okay, so let's see. So,
00:17:23.360 basically, if we start here, I got
00:17:25.039 plenty of time. Okay, so we got a little
00:17:27.839 more time. So, let's go a little bit
00:17:28.880 through this. Rails is technically just
00:17:30.000 a meta gem. There isn't really anything
00:17:31.919 in it. Load the gems, please.
00:17:36.080 It's going. There it is. It's just a
00:17:37.919 dependency for all these different
00:17:39.120 dependencies. What you know as Rails
00:17:40.799 actually happens in rail ties where
00:17:42.640 everything is sort of tied together. So
00:17:44.240 let's go looking at that. It's here
00:17:48.400 and font size. Okay. Right. Let's see.
00:17:54.000 Okay. Bigger. Bigger.
00:17:56.160 Bigger. Bigger.
00:17:58.720 Bigger.
00:18:00.559 Okay.
00:18:02.880 Okay. We're here. Okay. Cool. Uh so
00:18:06.720 let's see we're looking for
00:18:07.600 initializers. So I think where we want
00:18:10.000 to start is actually what if we just do
00:18:11.840 a little bit trip to if we go into the
00:18:15.200 so rail size is then just a separate gem
00:18:18.320 which is also where the generators are
00:18:20.640 and I'm just traversing through the
00:18:22.880 standard gem structure. It has a lip
00:18:24.640 folder and it has a Rails folder here
00:18:26.480 where it's a bunch of stuff. Here's the
00:18:27.840 generators by the way. Uh let's see. I
00:18:30.400 think I just want to start with showing
00:18:31.600 you the application itself. We're moving
00:18:33.600 towards it in a bit. So speaking of
00:18:36.960 here's the initialization parts of it.
00:18:39.360 This is the stuff that will show up on
00:18:40.480 the API site. So if you look up
00:18:43.440 let's see if I can type it here.
00:18:46.880 I got it. Yes, this is the same see
00:18:49.679 initialization where application and
00:18:51.280 it's here. So the documentation here is
00:18:53.440 what ends up under the API side unless
00:18:55.440 it's marked as no doc. We'll probably
00:18:56.799 see that a bit. Um the application
00:18:58.960 inherits from Indian and then we can
00:19:00.960 click here see engine. Um, and Rails
00:19:03.919 uses a bunch of engines internally
00:19:05.440 action cable. Mate, you're asking action
00:19:08.000 text. Here it is. The engine for that.
00:19:10.480 Uh, let's see where's it find here.
00:19:13.600 Jumping into engine and then engine
00:19:15.200 inherits for No, this is different. Oh,
00:19:17.679 is that new? I don't think I've seen
00:19:20.080 this before.
00:19:21.919 Okay, where was I
00:19:24.480 scrolling? This is what I mean with
00:19:26.720 navigating a bit. Uh, let's see. This is
00:19:29.840 like There we go. In Europe.
00:19:33.120 is an engine inherits from this thing
00:19:34.640 called rail ties. And now we can jump
00:19:36.160 into this. Uh and then there's also a
00:19:38.320 bunch of rail ties in Rails. The
00:19:40.720 difference between a rail town and
00:19:41.840 engine is that engines can also have
00:19:43.120 like an app folder where you can include
00:19:44.799 your own controllers and views and it'll
00:19:46.559 just be in your Rails app. Caveat here
00:19:49.679 because there's some more configuration.
00:19:51.200 Let's see where is the one I want. Not
00:19:53.360 this one. Not this one. Is it here? No,
00:19:56.640 it's not this one. That's the one I
00:19:58.720 want.
00:20:01.039 configuration configurable.
00:20:03.919 Let's open this up.
00:20:06.080 Splitting these two. This is not the one
00:20:08.400 I want.
00:20:10.080 This is also not the one I want. Where's
00:20:11.440 the defer? Okay, we have to skip it. I
00:20:14.320 want to make it like this.
00:20:18.400 There we go.
00:20:20.880 Uh, let's see. Here we go. Here's more
00:20:23.039 about the initializers. So, there's an
00:20:24.480 initializer method. So, what we could do
00:20:26.400 is head over here and see that.
00:20:29.600 Calizer.
00:20:35.039 Will it load?
00:20:37.360 Oh, site. Oh, okay. Nice. Well, okay.
00:20:43.200 Not doing that then. Um, so I'm thinking
00:20:45.520 of initialize like here where there's
00:20:47.679 this block that you can pass a uh I
00:20:49.600 should probably mark it here. You can
00:20:50.720 see the cursor, right? Yeah, it's there.
00:20:52.400 Okay.
00:20:54.000 uh where you pass it a string and then
00:20:58.080 you can run a block to it and the
00:21:00.559 initializers that you put in config
00:21:02.480 initialize sort of work the same way I
00:21:04.400 think right China's
00:21:07.360 not cool let's see plenty of time cool
00:21:12.480 we'll just keep finding them let's see
00:21:14.799 what is that at is that in here or is it
00:21:16.480 a module see find command f in here see
00:21:20.159 analyzer
00:21:21.760 it's in here it's in here do F not in
00:21:24.159 here. Okay. I think it's in a module.
00:21:27.440 So, this is where I've been here a
00:21:28.559 little bit before. Yeah, that's the one.
00:21:30.640 Click on that. I think this one.
00:21:34.799 Cool. Now, we talk about a little bit of
00:21:37.120 mirror programming here. There's a hook
00:21:38.559 on modules that you can override. It's
00:21:40.720 called included where then you can do
00:21:42.240 further extensions. It's pretty common.
00:21:44.880 So, if you ever seen access concern,
00:21:46.480 this is kind of what it does in part.
00:21:49.360 Um, and here we got a whole bunch of the
00:21:51.440 context. This is slightly complex. Uh
00:21:54.080 there's a collection here. We're doing
00:21:55.280 something with T sort which is 12
00:21:56.880 logical sorting. That's kind of complex.
00:21:59.760 Uh there's a whole bunch of things here.
00:22:01.840 We're appending here. Shovel operator
00:22:04.880 running the initializers.
00:22:07.120 So we can grab all of them, sort them,
00:22:09.200 and then run them passing all the
00:22:10.559 arguments if it belongs to the specific
00:22:12.480 group. Okay, that seems to make sense to
00:22:14.799 me so far. Class methods.
00:22:18.000 Okay, so we're taking all these
00:22:19.280 collections and gathering them together
00:22:21.840 from I guess what is it? Ancestors.
00:22:24.320 Okay, and I can't remember if ancestors
00:22:26.400 something in here or if it's in Ruby.
00:22:28.159 Nothing in here. Okay, let's see if we
00:22:29.520 can do that. Is it in here? Module
00:22:32.320 ancestors. There you go.
00:22:35.440 Okay, then please.
00:22:38.559 I'm doing a live demo. Please. Okay. No,
00:22:43.280 there it is. Uh, retention list of
00:22:45.440 modules included propended in mod
00:22:47.120 including mod itself. Okay, all these
00:22:49.600 ancestors.
00:22:51.280 Do you want to see if we actually show
00:22:53.440 that? I cannot do that here. I have it
00:22:56.320 on the other screen. Here we go. Okay.
00:22:58.080 So, what if we do here's me working out
00:22:59.919 some of the other demo stuff you saw
00:23:01.280 earlier. So, what I want to do is I'm
00:23:04.159 just curious to see does module
00:23:05.280 ancestors actually work here? Does
00:23:06.880 module have ancestors?
00:23:09.520 Anchov is cool.
00:23:12.720 Oh, it does. Interesting. So, what if we
00:23:15.120 do our own class?
00:23:18.080 Uh, just like this.
00:23:21.039 Hello.
00:23:23.840 Okay. And now we're our own answers to
00:23:25.679 two. And then we got object. We're not
00:23:27.120 module is not in it. Interesting.
00:23:29.679 I just compared the two. Uh, let's see
00:23:32.400 anything else we want to do. What if we
00:23:33.600 do class? Uh, this I use yo and hello
00:23:37.039 all the time for these kind of. Let's
00:23:38.640 see what we do this ancestors here.
00:23:42.640 Okay, so we're again embedded in there.
00:23:45.039 We got hello to super class. Then we got
00:23:46.640 object and all these different I guess
00:23:48.320 they're included in there. What if we do
00:23:50.720 included modules?
00:23:53.919 I just thought of that to see what else.
00:23:55.440 Okay, so these are included modules.
00:23:56.799 That explains what's in here.
00:23:59.600 So now we know roughly what the
00:24:00.799 difference is except for basic object is
00:24:02.799 an object, but the rest are in here,
00:24:04.559 right? Yeah, it's the same PP object.
00:24:08.000 That's probably for my BS and next gener
00:24:14.320 cool.
00:24:15.919 Okay. And now I got to figure out my own
00:24:17.520 rabbit hole because I forgot where we're
00:24:19.760 at. Ancestors, here's where we came
00:24:21.520 from. So we're looping through. We get
00:24:24.640 our own classes included as an array and
00:24:26.799 then we're reversing them. So I guess
00:24:28.240 we're pulling it from the subasses first
00:24:29.919 and then up superass and then down. I
00:24:32.480 think that's how it works. Okay. And
00:24:34.960 here's the then the definition for that
00:24:36.480 initializer you saw in the documentation
00:24:38.240 not here elsewhere
00:24:40.960 uh arrays putting in the after pending
00:24:43.520 it grabbing making like a internal
00:24:46.400 object here this inizer that has some
00:24:49.200 attributes some context as well belongs
00:24:52.240 to this whole group thing uh there's an
00:24:55.200 instance exx so we're doing a little bit
00:24:56.559 more meta programming I think the
00:24:58.559 context here is like the rails
00:25:00.720 application instance I think that's what
00:25:02.799 it
00:25:05.279 See, we still got time. Uh, I wonder if
00:25:09.279 do I want to see what if we figure out
00:25:11.039 if I configure new slices? Can you see
00:25:12.720 that? How do we find that? That's the
00:25:15.840 dummy applications. That's not what we
00:25:17.279 want. How do I find that? We do this. I
00:25:21.520 think it's going to be in what's past
00:25:24.320 RV.
00:25:27.520 So, do that in here.
00:25:30.159 That's not the one.
00:25:34.320 Okay,
00:25:36.080 so I'm going back through some of the
00:25:37.440 stuff I remember. There's a load pass
00:25:38.880 eope pass. I want to see if I can find a
00:25:40.880 place where we're actually loading the
00:25:42.320 directory configures, but I don't think
00:25:45.039 it's in here. So, Rails internally
00:25:47.279 maintains this path object with a bunch
00:25:50.159 of paths in there. This is how it
00:25:52.880 figures out. You saw it up top in the
00:25:54.240 documentation. Let's go back up where
00:25:56.000 you can have these like root paths and
00:25:57.520 some custom directories. You can then
00:25:59.120 get them expanded. So all the files that
00:26:00.640 are in there and then only the files
00:26:02.159 that exist within there. So like
00:26:03.600 globbing essentially. Uh cool.
00:26:07.760 I'm a little bit lost now. So what do I
00:26:09.200 want to do? Only extern.
00:26:12.960 That's not what I want. I find a config.
00:26:17.200 Oh, and the reason I'm doing this on
00:26:18.559 github.com is just to not feel like
00:26:20.559 you're need to have a checkout locally
00:26:23.760 or that let that stop you or whatever.
00:26:25.440 It's not too bad to navigate here.
00:26:28.400 This is probably the time where I would
00:26:29.520 do it. And you see uh I can't spell
00:26:31.679 anymore. Can you find it like this?
00:26:34.880 There really nothing here. There's
00:26:36.080 something in there. That's the
00:26:37.279 generators. It's cool. That's cool. Not
00:26:39.760 what I want. Not what I want. Figuring
00:26:44.480 DB generator
00:26:46.640 generators actions.
00:26:48.880 Interesting. It's not quite what we
00:26:51.039 want.
00:26:53.360 Cool. So I think if we actually go back
00:26:56.640 to this does not work anymore. Got like
00:26:59.279 three minutes left. Okay. Uh we should
00:27:01.279 probably start wrapping up. Let's see if
00:27:02.480 we can find one more. Do this.
00:27:10.240 I forgot what I was looking for. Run
00:27:12.080 load hooks. That's almost it. Okay. I
00:27:14.240 don't think I'm going to be able to find
00:27:15.200 that. Uh cool.
00:27:18.159 But yeah, this is kind of what it looks
00:27:19.679 like. You just keep going at it. Keep
00:27:21.440 trying new things. Come up with
00:27:22.559 different ideas for exploring. You can
00:27:23.840 keep using the reference pull out our
00:27:25.520 console to double check how it works and
00:27:26.960 get a feel for it. I haven't run module
00:27:29.039 ancestors before, so it's new to me that
00:27:31.520 the class itself was in there. Where is
00:27:33.760 it? All these tabs here. Here it is.
00:27:36.480 That yo was in itself in ancestors here.
00:27:39.440 I hadn't seen it before. So that's kind
00:27:40.880 of interesting to just play around with
00:27:42.080 it. Uh
00:27:46.400 yeah. Yeah, I guess. So I don't I'm not
00:27:49.679 quite sure if you're basically saying
00:27:51.679 that maybe ancestors is a version of
00:27:55.760 prepended modules. Is that not there
00:27:57.840 prepended? I spelled it right.
00:28:03.440 I can't hear you. What are you saying?
00:28:06.559 Yeah, let's try it. Uh so this is we can
00:28:09.600 do it this way.
00:28:13.039 Uh just hacking in there. Cool.
00:28:16.000 But is this not the way you do it? How
00:28:18.080 do you get the
00:28:22.799 Is it just ancestors here?
00:28:25.840 Well, it's in there. Okay.
00:28:38.880 Right.
00:28:41.679 You just repeat because I have the mic.
00:28:43.039 You're saying that because we now
00:28:44.399 repended a module ancestors is also that
00:28:46.240 includes that has the list of prepended
00:28:48.799 modules then our class itself it'll
00:28:50.559 basically show you how method resolution
00:28:52.159 works for this class. We'll go to that
00:28:54.240 custom module first then we'll hit our
00:28:56.399 self then we'll hit our super class
00:28:57.679 hello then we'll hit object then we'll
00:28:59.039 hit all these different modules that
00:29:00.159 included somewhere else. Uh cool and I
00:29:02.720 have a minute left so this is kind of
00:29:04.080 it. Cool. Thanks.
Explore all talks recorded at RailsConf 2025
Ben Sheldon
Sam Poder
Rhiannon Payne
Joe Masilotti
Josh Puetz
Wade Winningham
Irina Nazarova
Tess Griffin
+77