Summarized using AI

Compose Software Like Nature Would

Ahmed Omran • November 13, 2024 • Chicago, IL • Talk

The talk titled "Compose Software Like Nature Would" by Ahmed Omran at RubyConf 2024 explores the analogy between software design and the adaptability of living organisms. Omran emphasizes that software must be adaptive to prevent it from becoming unwieldy, likening poorly organized code to a 'big ball of mud'.

Key points discussed include:

- Importance of Adaptability in Software: Just like living organisms, software should have the capacity to adapt and change based on user requirements. Challenges arise when software becomes rigid, leading to complications during updates or feature additions.

- Inspiration from Nature: Omran draws parallels between software components and biological structures, suggesting that adopting principles from nature can lead to better software design. He discusses the adaptability of organisms, such as dung beetles and cyanobacteria, and explains how these systems have evolved to thrive in various environments.

- Building Small Components: The speaker advocates for constructing small, manageable components in software, likening them to cells that communicate and operate independently while contributing to a larger system. Smaller components are easier to reason about, change, and test.

- Component Interaction: He highlights that components should have strong boundaries, meaning they should have few inputs and outputs. This idea leads to reduced complexity and risk when managing changes across the codebase.

- Addressing Side Effects: Omran expands on the importance of managing side effects in software, which are similar to how living organisms interact with their environments. Strategies for pushing risky interactions to the edges of the program help maintain a stable core.

- Iterative Design Process: The process of designing software is compared to the 'run and tumble' approach of certain microorganisms—constantly trying, adapting, and improving. Omran encourages developers to embrace iteration in their design processes and to balance perfection with the need to ship functional products.

In conclusion, Omran advises developers to focus on creating small components with strong boundaries, utilize informed naming and structure practices, and be cognizant of the risks associated with external interactions. The overarching message is to view software design through the lens of biological adaptation, fostering more robust and flexible systems.

Compose Software Like Nature Would
Ahmed Omran • November 13, 2024 • Chicago, IL • Talk

The only constant in software development is change. When our software cannot adapt, it turns into a big ball of mud. It becomes hard to reason about and hard to change. On the other hand, living organisms have the incredible ability to adapt to their environment. Over eons, they evolved innumerable adaptations. Let’s explore together how we can create adaptable, maintainable, and resilient software with some inspiration from nature.

RubyConf 2024

00:00:15.759 hello hi everyone uh thank you for uh being here uh for those of you who are
00:00:21.640 maybe not very familiar with software design I hope this is a good introduction and gives you kind of a
00:00:27.679 mental model um to get started for those of of you who are very familiar with
00:00:32.840 software design I'm sure a lot of you are uh this should be just a fun kind of fun twists on very familiar um
00:00:40.399 Concepts so I'd like to start with a a story from I think this was probably one
00:00:46.680 of my first jobs I was a junior engineer I showed up I was working on a uh
00:00:52.960 learning management system and one of the features I was working on looked something like this uh you have a a
00:00:58.960 person goes online does a course gets a certificate really simple stuff not not rocket
00:01:04.720 science and uh one day we got a bunch of feature requests right I would like to
00:01:10.080 add my own logos to it I'd like to um add my own branding maybe for some
00:01:16.080 people they'd like the certificate right away for others they want to get it via email and of course I'm eager I'm new I
00:01:23.960 say this is good we're good to go easy I'm going to get this done uh unfortunately this was a code basee that
00:01:31.640 was a big ball of mud I'm sure a lot of you are cringing right now uh I didn't
00:01:38.200 know but I learned very quickly that this code base was really hard to understand it was hard to change um and
00:01:46.119 when I changed one thing here it would break 10 things that were unrelated um so uh really fun
00:01:54.280 stuff uh I mean software as the name implies should be malleable right should
00:01:59.640 be easy to change and when you have a successful product when people are using
00:02:04.759 it they're going to ask for changes it's almost you know the simplest thing
00:02:09.920 around right if you if you're uh doing something interesting people are going to use it they're going to request
00:02:15.040 changes so why is it that a lot of the times we have this friction right we have this these kind of constant
00:02:21.000 conversations about oh well we can't do that because that'll take x amount of time or you know this is too complicated
00:02:28.879 uh uh and so I looked back to my early training I thought a lot about living
00:02:36.480 organisms and how they're really good at adapting uh and thought maybe that would
00:02:42.400 be a good inspiration for thinking about software design um this is a dung beetle
00:02:49.200 um maybe that look like my code base right there uh the dung beetles um they they adapt to H some really harsh
00:02:57.360 conditions right they live in the desert but they're really really um amazing organisms they navigate their
00:03:03.400 surroundings using the Stars uh they live on very few nutrian and then you'll have another
00:03:10.879 Beetle there are 400,000 different species of beetles and you'll have another Beetle that lives somewhere in
00:03:16.040 the rainforest and lives in a completely different environment and then you know you open your backyard and you find a
00:03:22.040 beetle there uh and that one maybe is more of like a hipster Beetle only eats locally sourced organic food uh I might
00:03:29.400 have made that last part uh but at any rate living organisms are really good at adapting but this is after billions of
00:03:36.080 years of evolution so it's it's hard to uh learn from that what we can do is go
00:03:41.439 back uh many billions of years and see what what are the building blocks of life and if there's anything that we can
00:03:48.080 learn from that so 4 and a half billion years ago there's no life on Earth as far as we know uh the Earth is really
00:03:55.480 hot there's no oxygen in the atmosphere the Earth is being bombarded by debris not a great place for life it takes
00:04:02.200 about a billion years but then Earth cools down uh this is a picture that my wife actually took uh on the Ottawa
00:04:09.280 River close to where I live in Canada uh and these are stratales these are
00:04:14.640 remains of the kind of the first living organisms um on Earth uh they're called
00:04:20.239 cyan bacteria um they're little single- celled organisms and what they do is
00:04:25.320 they take carbon dioxide uh and water mix that with a
00:04:32.840 reaction called photosynthesis you all remember your biology from I don't know probably grade six um and then you get
00:04:40.000 lots of oxygen that is being produced actually most of the oxygen that we breathe today comes from these cyan
00:04:45.440 bacteria and these structures are all over the world and some of them are like three and a half billion years
00:04:51.600 old um so that's kind of our first hint at what life looked like the first kind
00:04:58.440 of building blocks of life and if we kind of zoom in what does that single
00:05:04.680 celled organism look like well this is a good illustration of that this is from a book called The Machinery of Life uh
00:05:12.120 this is an ecoi again another organism that you're all very familiar with sometimes uh too intimately familiar
00:05:19.600 with if you get sick from them um but uh really interesting structure so what we have here is the green stuff on the
00:05:26.199 outside there's a the thin layer that's called a cell membrane I'm sure you've
00:05:32.919 all um done a bit of biology and you you've seen that it's packed with proteins so that's all the the purple
00:05:39.479 stuff um and then in the middle there's DNA so it's just strands of DNA uh there
00:05:44.639 so really simple structure and it has this really nice tail this flagella that
00:05:50.880 it uses to swim around in the water so that's what the kind of single
00:05:56.240 cell original kind of life um look like and there's some things we can learn
00:06:01.759 from that we're talking about really really small components of Life uh micrometers as in like one millionth of
00:06:08.720 a meter so really really small um they
00:06:14.080 also like the first innovation in life is this idea of a cell membrane this
00:06:19.120 idea of a boundary you have something on the outside you have something on the inside there's a boundary therefore you
00:06:24.919 have a cell you have a life you don't have boundaries you don't have life so that's the first Innovation uh in
00:06:32.120 life uh this is from that same illustration from that book called The Machinery of life if you zoom in this is
00:06:38.560 what the uh that tail looks like and what that u u cell membrane looks
00:06:44.840 like um so really small things but then
00:06:50.000 you might read in the news that you know we use antibiotics to kill these bacteria if they're bad for us U but
00:06:56.919 over time they seem to get resistant to this antibi itic so they're adapting and how are they doing that so one cell
00:07:03.879 turns into two they multiply but the um replication is not perfect the second
00:07:11.199 one looks slightly different uh the DNA is slightly different most of the mutations are
00:07:17.280 actually um harmless they do nothing but then every now and then there's a mutation that makes something new for
00:07:25.199 example the the structure of the cell membrane might be slightly different and then the antibiotics might have a hard
00:07:32.400 time clinging to it uh and then over time you have a population with a lot of
00:07:37.800 diversity just like the population here which is great to see um so you've got a
00:07:43.199 population lots of diversity we hit it with some antibiotics and they're easily replaced the ones that are susceptible
00:07:50.440 to those antibiotics die and the ones that are not even if they're slightly better at it at surviving the
00:07:56.680 antibiotics well that's good enough and the population over time adapts to its
00:08:02.039 surroundings so it's not the individual but the population that adapts over
00:08:07.240 time and speaking of these populations these colonies they can communicate with each
00:08:14.000 other they can send each other messages and they can talk to each other they can send these molecules across and they can
00:08:19.840 talk to each other and you can actually see them with your uh eyes you can do this at home if
00:08:26.680 you have kids you can do the uh classic experiment go to Amazon search for AAR AG R and you get these Petri dishes with
00:08:35.599 some um sugar on them and then you can do the fun experiment of like getting
00:08:41.919 bacteria from different places of the house like a keyboard and a and a toilet seat or something uh and then you might
00:08:47.600 be surprised what you get uh but it's fun the kids can see them it's very visual um when I taught
00:08:54.120 biology that's what I uh did you know any way to engage the students right
00:09:01.040 so how does this relate to uh software well obviously I'm not the only one
00:09:06.399 who's thought of this in fact Alan K who coined the term object-oriented programming he had a biology background
00:09:13.279 and he thought of objects as um kind of these little cells that were communicating with each other and that's
00:09:20.079 what made our program right lots of little cells communicating with each
00:09:25.279 other um and so our first lesson if there's uh any inspiration to take from
00:09:31.760 this is that uh we should build really small components we should make sure they have really strong boundaries uh
00:09:39.320 and we can compose them with messages so by components I mean things like modules and classes and by methods um by
00:09:46.480 messages I mean like methods or a more advanced topic events we won't get into it here that could be a whole topic on
00:09:53.880 its own so let's go through an example just to see what that might look like um
00:10:00.079 but before that just a quick like when you're building these small components you get immediately some benefits which
00:10:06.240 is they're really small that fit in your head easy to reason about um they're easy to change and they're easier to
00:10:12.320 test but we'll see that in practice so this is our initial kind of big ball of
00:10:17.560 mind we have one uh class it's called certificate and uh it takes in
00:10:24.240 10 inputs and then it accesses the database it goes to the file system it
00:10:30.279 accesses S3 uh it does everything uh and it does some things that we don't even know it's doing uh so there there's no
00:10:38.279 clear boundary here there is no clear idea of what's outside and what's inside
00:10:44.120 it simply does the entire kind of um certificate generation uh
00:10:50.440 experience um and some might say well that's you know a singular thing that it does so it could be one thing but um I
00:10:57.519 think it's a bit too much so what we could do is redesign it into smaller
00:11:02.680 components so we could do one component that looks like this uh it takes in one input and enrollment is just a database
00:11:10.360 entry that says so and so took this course so it takes in one enrollment it
00:11:16.360 does not access the database it just simply gets a data structure um and then it has very few exit points it can um
00:11:24.279 tell you what the title is of the certificate it can tell you what the subtitle is and a
00:11:30.600 um so really strong boundaries because there's only one entry point and only a few exit
00:11:36.040 points and then in addition to that we add a couple of components to do the the rest of what our program should be doing
00:11:43.160 so we'll add a template class and it takes in one component so a certificate
00:11:49.079 that last one uh and then it only responds to one message which is render and then it gives us back some
00:11:55.399 HTML and then for S3 we have a a component that takes
00:12:01.000 in um two entry points so a certificate and some HTML and it has only one exit
00:12:07.600 point you call Save and it simply saves and tells you where it saved it so
00:12:13.720 visually this is what our design would look like instead of having one big kind
00:12:19.639 of organism doing things it's actually like a little colony of little
00:12:25.639 components and they can talk to each other right you can send them these messages title subtitle date render save
00:12:32.800 and each one does its own thing uh one immediate uh benefit as I
00:12:38.480 said is you can refactor one component without affecting the others so now we have less risk instead of many changing
00:12:45.800 one thing and then breaking 10 things that are seemingly unrelated this way
00:12:50.959 when you isolate one component you want to change and change that you might not affect the other
00:12:56.959 ones uh another nice benefit is that we can replace components so we have an S3
00:13:02.680 file component and we could replace it with a temp file component as long as it
00:13:07.760 responds to that method called save then it can easily fit into um that place
00:13:13.880 there and now instead of saving to S3 maybe it saves somewhere temporary and then somebody might download that
00:13:21.800 file so sometime goes by uh I'm sure we've all done this you build a bunch of
00:13:27.680 components and then over time time our system has a thousand of these little components uh and someone will tell you
00:13:33.720 oh wow this this code base has too many components there's a lot of indirection
00:13:38.959 if I want to figure out um how these three things fit together I don't know I
00:13:45.199 would have to read everything and that's fair it's a fair criticism and I think our design can be made better so let's
00:13:52.320 go back to life and see how does life deal with multicellular uh structures
00:13:59.399 and one of the early um life multicellular life would actually look something like this uh so
00:14:06.880 this is a stove pipe sponge really cool organism so the
00:14:12.560 individual cell actually looks a lot like the ukoli that I showed you with the cell membrane and the tail but what
00:14:18.800 it does is it secretes a protein called collagen and then a lot of these cells
00:14:24.639 come together they secrete this collagen structure and that forms the pipe and
00:14:30.600 then their tails are actually pointing inside the pipe and they move their their tails in unison to pump water uh
00:14:38.759 through the pipe and when they're pumping the water through the pipe nutrients flow and they filter that and
00:14:44.680 get their nutrients so rather than needing to you know go around and get
00:14:50.120 their nutrients they actually just sit there in a pipe that's made of this collagen uh and they get their nutrients
00:14:56.800 so the structure is not only giving them a distinctive look like you can look at it and say oh that's a sto pipe sponge
00:15:03.199 but it's actually also giving them additional functionality um and collagen is
00:15:10.759 actually such a great innovation in life that you find it in in our bodies our skin our hair our nails have a lot of
00:15:18.959 collagen so life doesn't waste Innovations right you keep seeing things
00:15:24.120 repeat so that's what we want to do we want to give our design a bit more
00:15:29.160 structure kind of like a protein mesh around it to both give it a visual distinction and also maybe give it an
00:15:35.680 additional uh capability so there's a few few ways you can do this um the first example here we made a
00:15:44.160 folder called compliance and a lot of you might be saying well what what is compliance uh so that is domain specific
00:15:51.440 uh knowledge meaning this is domain specific language this is language that is specific to that um those people
00:15:59.040 right the customers what we're working on and in this case compliance means you have to take that course CPR training is
00:16:05.959 required you have to take it and so that's what we did here we created a folder named it
00:16:12.160 compliance uh and in Ruby it doesn't need to be a namespace it doesn't need to be in your code it can just be a
00:16:17.800 folder and now anytime we have anything compliance related any compliance related feature we'll put it there we
00:16:24.399 create another folder called certificate and that's a namespace so that'll be a module called
00:16:30.160 certificate and that's how we bring together these three components so now
00:16:35.240 if somebody is interested in the certificate code how does how do we you know print certificates in our code base
00:16:42.319 well they just open up the certificate folder and they'll see those three components right
00:16:47.759 there we also added a coordinator class that's the generator.
00:16:53.240 RB and this is what it does so namespace certificate our class is a generator and
00:17:00.600 there's a couple ways you can compose components so this is showing you two options uh one is we assume the name of
00:17:07.480 the components right we just assume that our three components are certificate base certificate template certificate S3
00:17:14.720 file and it just puts them together generates a certificate uh another way to do it is
00:17:21.839 to actually expect that whoever calls the method to tell you what those names
00:17:27.280 are um so you might see this referred to as like depend dependency injection uh
00:17:33.000 and in that case um there's a bit more flexibility because for example for our
00:17:38.760 saving strategy we don't have to assume that we're saving to S3 whoever is passing us the name of the classes can
00:17:45.320 give us that temp file uh component that we talked about earlier so instead of S3
00:17:50.600 they send us the temp file component and now instead of saving to S S3 we
00:17:56.120 actually save to uh the temp file
00:18:04.840 so two ways of doing uh composition um but really uh relatively simple stuff
00:18:12.520 and we have I think a much better um uh design
00:18:18.520 now but of course um there are always
00:18:23.640 going to be uh things that we have to think about so one thing we haven't thought about
00:18:29.400 uh is this idea of side effects so if you if you've done some functional programming you're familiar with this uh
00:18:34.480 but for those people who are not I'll just give you a quick intro to what side effects are so anytime you interact with
00:18:41.159 the outside world uh in this case if our program is interacting with the database
00:18:46.559 or going to an API or um making um
00:18:52.320 raising errors or printing on a screen on a device somewhere anytime you're interacting with the outside world it's
00:18:58.280 risky it might fail right we have to deal with both the success State and the error State uh and in that case um
00:19:06.280 things are risky and we have to be mindful of side effects uh so a quick example of uh the
00:19:14.080 one kind of outlier here is mutable data but here's like a quick example if you're working uh with like a rails
00:19:19.880 application um you can assume that param is like a hash right uh and it has some
00:19:25.240 data in it name John now you call some method that I know a colleague wrode or
00:19:31.320 a t a gem somewhere do something with this uh params right um and there's a
00:19:37.039 type with though that's a params with an S uh so uh you give them that hash and
00:19:42.440 they modify it they mutate it uh and then when you call that Pam's name again
00:19:48.400 you get an unexpected result which is the data has changed um I've seen some bugs in our code base with stuff like
00:19:56.480 this where the data mutates the data Chang and you don't know that it changed you expect it to be the same so just
00:20:03.080 something to be uh mindful of so again we'll go back to life and see is there
00:20:09.000 any inspiration we can get from um living organisms uh so about 600 million years
00:20:15.559 ago we start seeing uh the first signs of a nervous system uh and in fact life
00:20:21.559 becomes very Dynamic at that point lots of um organisms kind of interacting with each other uh and in and the fossil
00:20:29.600 record fossil record is called the Cambrian explosion where there's just so much uh different variety of
00:20:36.000 Life uh this is a common jellyfish uh and it has a really simple nervous
00:20:42.600 system so it's called a nerve net uh and the way it works is you've got uh a
00:20:48.039 bunch of organs on the outside that interact with the outside world uh and then they send electrical signals
00:20:54.360 through nerves and then the organism responds in a deter terministic way so
00:21:00.440 always in a similar way uh so for example it has a a a an organ that
00:21:07.200 senses touch so you touch the bell and it will sense that you've touched it and it will move away so always the the
00:21:15.039 responses move away it also has something like the human eye of course the human eye uh forms images but for
00:21:23.120 the the jellyfish it doesn't form an image but it can sense light and so can then respond according to where the
00:21:29.400 light is uh it also has something like the human inner ear which is a crystal
00:21:35.880 uh suspended in a solution and depending on where the crystal is it knows what's up and what's
00:21:41.760 down so really simple organs that tell it specific things about the outside
00:21:47.840 world and then it responds in a deterministic way as in same thing every
00:21:55.720 time so we can do that we can push the side effects or our interaction with the
00:22:01.440 outside world to the edges of our program just like a uh Jellyfish would
00:22:09.039 do so here's what our design might look like we'll have a nerve net if we're
00:22:14.400 interacting with a database or we're interacting with a
00:22:19.840 um uh a device or something like that then that'll be on the outside of our
00:22:26.159 program uh it's just a mental model right we're just imagining that that's the outside and then we have our code on
00:22:32.120 the inside and then deterministic responses in code the simplest example
00:22:37.919 is this right an add function takes in two arguments you give it one and one
00:22:43.400 it's always going to give two so our design just visually this is
00:22:49.039 what it could look like right we have our three components they always respond in the same way so when we call Title or
00:22:57.200 subtitle or date on our component uh it's always going to respond in the same way if we
00:23:03.480 give it the same data uh same thing with the HTML rendering right it should be
00:23:09.279 rendering the same HTML given that we give it a specific certificate uh and then our I put the
00:23:17.600 generator class that's the coordinator class I put it kind of like on the outside this is just again visualizing
00:23:23.480 what our design looks like because it might do some database access so that one is a bit risky I put
00:23:30.559 it in red uh um and then let's imagine that S3 is actually a gem that we're
00:23:36.480 interacting with maybe S3 is a gem or maybe you've wrapped an S3
00:23:42.159 API in that case that's the outside and we're just being mindful of what's on
00:23:47.480 the outside and what's on the inside um and then for our components we're going to try to be as deterministic as as
00:23:54.559 possible that way it's it's easier to test um if you don't have to um you know
00:24:01.760 take care of errors and things like that and then as time goes on obviously
00:24:08.960 we're going to be asked to do some changes and let's say for example delivery method changes based on some
00:24:16.039 logic well we want that logic to be to be deterministic right um given a
00:24:23.000 student in an organization it it it it will always be you know by email but
00:24:28.159 they get their certificate or for this organization they get it right away or in this condition they get it right away
00:24:34.320 so that we wrap that logic inside and then any interaction with HTTP or email
00:24:40.559 we try to keep kind of on the
00:24:49.320 edges and if you're curious you know what does an edge look like um we're
00:24:55.679 talking about things like controllers where you're interacting with the user and then you can give them an error
00:25:01.640 message or backround jobs you could retry um or a mailer or rake task or or
00:25:07.480 something like that so that's the edit of our program and we can do some riskier stuff there um and then for our
00:25:14.399 core of the of our program we'll try to do less risky stuff
00:25:20.360 there so we started with um this beautiful ecoi and I'd like to give you
00:25:26.720 one uh last example with um our familiar ecoi so this ecoi
00:25:32.960 doesn't have a brain it does not have a nervous system but it swims around and
00:25:38.120 Finds Its food it's really good at swimming around finding food sources and eating it um so how does it do
00:25:46.200 that uh the way it does that is called a run and Tumble so two step process uh it has a
00:25:54.960 tail that it moves clockwise and that pushes it forward so in a straight line
00:26:00.440 and then what it does is it senses the concentration of sugar in its surroundings if the concentration of
00:26:06.080 sugar is going up uh that means that it's heading in the right direction right the food source is somewhere out
00:26:12.640 there um and the concentration of sugar is telling it it's heading in the right direction but if the concentration of
00:26:19.600 sugar is going down it means it's actually the wrong way it's heading the wrong way it's moving away from the Food
00:26:25.880 Source uh so what it will do it will do uh uh tumble and instead of moving its
00:26:32.399 tail clockwise it will move its tail counterclockwise and that will spin it
00:26:37.520 in a random Direction and it will start all over again uh and then it will do a run move forward sense its surroundings
00:26:45.360 oh it's heading in the right direction if it's not it'll you know keep doing a run and Tumble uh so visually this is
00:26:51.559 what it looks like uh they don't necessarily know where they're going they're just they
00:26:57.360 keep trying right and then at some point they'll get to uh their destination uh
00:27:04.080 and I share that because software design can sometimes feel like a runand tumble all right you don't know what to name
00:27:10.440 things or you'll name things wrong uh you might not know the domain um
00:27:16.080 language right you're new to a company you don't know that space uh you might uh be too eager like
00:27:24.039 I've done in the past and uh build too many components right and then somebody will say uh could you
00:27:30.600 just scale that back a bit and then you'll take that that feedback in and maybe redesign it with fewer components
00:27:38.039 or again I've done the same build too few components right and the components start getting really really big and then
00:27:45.440 what you could do is start extracting uh components so our designs aren't going
00:27:50.559 to be perfect um our goal is to ship working software our goal is to uh ship
00:27:56.960 uh products and so we need to find a balance right ship something that you're happy with
00:28:04.200 but give yourself um some Grace give yourself um some space uh do the best
00:28:11.240 you can but also ship it because I've seen Junior Engineers who will sit there and like retry and keep on redesigning
00:28:19.799 um but you know you can go ahead and ship it and if the software is being used if it is uh helpful to people
00:28:27.240 you'll get another opport opportunity right somebody will ask for a change and you'll come back to it or maybe the performance isn't great and you'll
00:28:34.640 notice that in your logs and you'll come back and and try to improve it so
00:28:40.279 um design is irritative it'll take some time so in conclusion um build small
00:28:47.880 components right make sure they have strong boundaries a few inputs a few
00:28:55.360 outputs uh naming and structure it's surprising I know but a lot of people don't think that you can go beyond you
00:29:02.200 know model view controller but you can and Ruby makes it really easy uh so give them struct give structure give folder
00:29:08.640 structure and naming structure um uh make sure that you know you're you're
00:29:13.760 imagining your design is not um uh modeling the real world necessarily but
00:29:21.000 actually building a living organism or or a set of living organisms that that
00:29:26.559 talk to each other uh and then be mindful of the risky stuff right the side effects and try to
00:29:33.200 push that as far away from you as possible so that you know what's risky
00:29:38.399 and what's not and keep that in your head and then last but not least uh run
Explore all talks recorded at RubyConf 2024
+64