Talks

10x Your Teamwork Through Pair Programming

A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.

Find out more and register for updates for our 2023 conference at https://rubyconfth.com/

RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com

RubyConf TH 2022

00:00:00.120 foreign
00:00:21.080 Hi, I'm Selena. Oh yeah, I mentioned there was a new hire coming in today. What's she doing here? Maybe she's a designer.
00:00:29.279 Well, you know, it's nice to meet you! I'm really excited to get started. Can you fill me in on how things work around here?
00:00:41.280 Well, I'm not sure about people like you who don't code, but we’re having a stand-up over there. Catcher, what thinks I can't code? Oh yeah, I'm a woman.
00:00:52.379 That's probably why he thinks I'm a designer then. It's a bit up himself, as well, Michael. Men's slinsky over there probably shouldn't judge a book by its cover, though.
00:01:06.080 My card for today: to-do list, delete functionality. Huh, is this a joke? Selena, are you a developer? Oh, you don't look progressive enough to have me as your CTO, so I might as well cut some code. How are you?
00:01:21.600 Come join us for stand-up? Yeah, cool! Do you want to tell me a bit of background on the story? Uh, yeah. So, we’re doing delete functionality and, you know, this is going to be some serious coding, not just some CSS honey.
00:01:30.459 Great point! I didn’t say anything. All right, keep it that way. Let's go. I think I'm going to need Stack Overflow to help me out with this one.
00:01:37.560 Really? Um, you guys use React, right? Sounds like you're just going to need a simple callback function to respond to your delete action. Shouldn't be that difficult.
00:01:59.579 I messed up the line. Start with a bit of kickoff to get some background. You know, when Sam started he wanted to make us agile and bring in story points, Scrum—things like that. But, you know, somebody like you, I think you would need a kickoff.
00:02:08.839 So we have a to-do list, and we need delete functionality. Why do we need it? To delete the to-dos. Okay, I think we're kicked off. Let's go. No, but hold on. Why do we need it? What's the point? Where’s the business value?
00:02:24.420 Whoa! Going a bit above your pay grade there. All you need to know is that this is a React app, and we have a list of item components that need the ability for deletion. We're probably going to write a callback function.
00:02:41.099 You know, in the old days, they used to call them call-after-functions. Don't you all just love a good spline? All right, come and join me at the machine. Yeah, all right, we've got the code here. We've got some tests over here. What’s that test not passing?
00:03:18.900 Okay, cool. So we've got a failing test there. Just open the editor. Uh, sure. Yep, I reckon app test. Yeah, go down about line 39. Yeah, just straight down. You can see the line numbers on the side. Can I just have a look at the structure of the code first?
00:03:39.960 Uh, yeah. Yeah, just type debugger. Whoa, hang on a sec! What, I got it! Why would you put a debugger in here? I mean, clearly, I've just closed the file that I should have had open. And my skills in this... why would you put a debugger in here? I think it's an order problem.
00:04:22.440 You got to get your 1, 2, 3s before your ABCs. Look at that! It passed! Great pairing! Uh, let's get this over here. Get commit minus Ram. Get it? Ah yeah. All right, is that your camera? What is that? Baby, this is how we pay here. What? Yeah.
00:05:15.060 You've never used LOL commits? No. Um, there you go! Oh my God, what the hell? Yeah. Coffee? Coffee! All right, look. That was some great pairing. Let's go get a coffee. Can you believe that he was recording me? What a creep! I had no idea. A little bit uncomfortable now, to be honest.
00:06:20.100 Uh, how do you take your coffee? Well, it's pretty hot here, so lots of ice. Yeah, well you know the barista? Whenever he asks me, I say very, very seriously... a joke. Yeah, okay. Well, so how long have you been here at Aviato? Ah, my time at Aviato? You know, I was one of the first internal developers to be hired on this project.
00:07:16.740 Oh, so you must be really across the whole code base there. Yep, pretty much. Well, apart from John, the CTO who hired you. Yeah, right, John. And he's known to be pretty big on TDD, right? So why was it that we started on this card with a failing test? Oh, failing test—test driven development. You seem to know a lot about it. Why don't you jump on the keys when we get back?
00:08:05.820 Yeah, okay, I'd love to. Oh, Jane's phone left unlocked. All right, so... Yeah, keep going! Keep going!
00:08:18.160 Yeah, okay, so, um... Yep, so I think what we want to do is we’re going to want to write a new test. And if we look and see what's here already, we kind of have this describe block that's set up with a couple of items. And we've got this test that checks it marks an item as complete.
00:08:38.280 And I think we want to... what we want to do is we're going to want to add a new test. And... Oh, no, don’t do that! Oh, okay, I won’t do that. Um, well it's gonna... you know, we want a pretty similar describe set up so we could add a new describe block here. And I wouldn’t do that.
00:09:24.349 Oh, okay, well look, I really think it's going to be very similar to the same setup we've already got, so we could probably just copy that and base programming however we're doing that. Look, let me just get my thought out, okay? Yeah, yeah, I mean keys, your hands on the keys. Yeah, yeah, you do it. Yeah, cool.
00:10:02.820 So it's going to be really similar, slightly different expectation. And what it’s going to do instead of marking an item as complete, it is going to delete an item when remove item is called. Right? Something along those lines? Yeah. Look, I know it's your first day. Great try.
00:10:50.340 But look, let's just understand how this code kind of goes, right? So what we’re going to do here, we’re writing a test, so we’re going to have an if statement, okay? Inside of here, we're going to do delete the item when remove item is called. Isn’t that kind of what I was just writing?
00:11:22.860 Look, if that's distracting you, I'll just comment that out, okay? Now we're going to pass that into an arrow function. You are across those, right? ES6? Yeah.
00:11:29.640 And then in there, wait, let’s just use that. Just use that, we’re just going to call that, right? So it's almost exact, like it's exactly kind of almost what I was going for.
00:11:56.940 Yeah, look, let's have a clean start so we can all understand what's going on here. We're just going to do that. And then, importantly, we're going to have to call the remove item function.
00:12:28.020 Remove item function, right? That's what I said, remove item. Yeah, cool! So what does it do? Removes the item. Oh yeah, but I mean, like how does it work? Like what does it do?
00:12:53.820 You can tell from the name of the function. It removes the item. It's a remove item function. You’re passing the item and it removes it. That's what it does; you can see it clearly right there; that's what the function does. It removes the item. You get it, right? You get it; it's a remove item function. It removes the item.
00:13:57.300 It removes the item by the name—you can see what it does. It's clearly right there. Uh, yeah. I'm not quite getting it. Perhaps I'd like to see how it's defined, but anyway, whatever. Look, it might be easier to see in a different font.
00:14:17.370 A different one? Hey, you know, I used to work with this guy, Brad. Brad! He had a different—what? Oh my God, don't save that! Why would you put that in an editor? Who would even think of coding with spider webs?
00:14:25.560 Oh God! But you know, 2005? Wasn't that like when Monaco was all the rage? Everyone was on Monaco. Yeah, that looks good. I don't know. I guess I asked for this, didn't I? Can we run the test now?
00:14:43.860 Think about that? Yeah! Michael! Michael! Can we just run the test now? Uh, yeah, I think that's good. Yeah, okay, cool, yeah. So if we jump in and see our test—oh, it's failing dismally.
00:15:17.460 The code you wrote doesn't even compile. Right. Look at that! Ah, and there we go! A delete item when remove item is called is meant to be deleted. Got it? Yep, okay.
00:15:43.500 Okay, should I take over? Now? Cool! All right, so now that we have a test that... yeah, at least what’s that? Look at that! Is that Cal San wrong?
00:16:04.740 No, no, no, no! That's soy Cowboy at the front of the shadow boy club. Have you ever been there? No, neither have I. Hey, this is Jenny's phone. Let's take a photo, Michael. Oh, Jenny's not going to be happy about that; that's her phone you threw across. What, this is my phone actually.
00:17:14.760 You know what? Checking by the time—it's about time I did some fitness. I'm going to go for a quick lunch run and get some Pad Thai on the way back. I'll catch you soon.
00:17:30.780 foreign. Oh my God! I can't believe I just lost it like that! Something is really not right here. Oh, actually, I know what it is. No, it's not that! Oh my God...
00:19:07.560 Functional! Functional! That's the way to become a 10x developer. Yeah, yeah. Okay. All right, do you want to kind of get back into the code?
00:19:33.259 Uh, yeah, sure, sounds good. Um, maybe you drive? Okay, I'll drive. Just do you want to run that test again? Look, why don't we take a longer lunch break?
00:20:05.640 No, no, it's good. We've got to get our designated number of lines of code out today. Look, we take a lunch break... you could go get cleaned up, finish your lunch. We could meet back here in, you know, 15 minutes.
00:20:27.680 Um, you know, yeah, I think you're right. Let me go grab a shower, and yeah, I'll be back in a sec. Hey, Jody! Hey! Yeah, no, first day's okay. It's not too bad.
00:21:00.720 Well, actually, you wouldn't believe the guy that I have to code with today. He must be the world's biggest keyboard hog. And honestly, you should hear this guy explaining callback functions to me.
00:21:41.060 Hey, yeah! No, no, he's not my type! Like he came back from his run, dripping sweat all over me! He had like noodles in his bed! Oh, it was so gross!
00:22:22.740 And do you know what? It's perfect timing! Mr. Noodles is on his way back now to tell me how to hang up the phone. Look, I better go, but, um, could you just check and see if my old job's still open, you know, just in case?
00:23:56.040 Awesome! Awesome! Okay, thank you so much. Bye! foreign. Look, I've thought about it. Me, coming back here straight after my run, sweaty, with Lycra clothes and everything. Pad Thai with my beard! I mean, that must have made you feel really, really uncomfortable. Sorry about that.
00:24:14.540 Wow! Thanks for acknowledging that! You try and write that test now? Yeah, yeah! Um, let's just—um, that's where it is. You go. So we'll chuck that in there and run the test.
00:25:09.060 Yeah! Yeah! So we do want that to delete to-dos, and if we run that test, we can see... are you going to cut your toenails next? No, no, Selena, there's a line! I wouldn’t step over the line!
00:25:27.460 Whoa! You see the notification? It's cake time! See you at the lunchroom. Oh my God! This guy is so hard to work with! There is a new distraction every two minutes, and he's disgusting! Have any of you ever worked with someone who's cut their nails at the pairing desk?
00:25:48.719 Yeah, I literally have! Um, even when you're remote, you can actually hear it through the microphone. So just a warning, guys. Um, I suppose he did apologize for sweating on me, but still, you know, he clearly has very, very little consideration for others.
00:26:06.859 I bet he's one of those guys who lives in his mother's basement, playing video games and watching girls fight on the weekend. Ah! New girls got lucky, paired up with me. I know more than anyone about the code base and the architecture of this project; I’m going to help her around.
00:27:22.160 But, uh, why am I feeling like I'm having like a pissing contest with her? Why am I being so competitive? I mean, after all, John did hire her. And I don't even know if I'd get hired at this company at the moment. And he said, you know, she certainly has good ideas and a clear understanding of test-driven development and everything else.
00:28:07.720 Maybe if I tried a little bit harder, I could actually learn something from her. Maybe if only I made a little bit more effort. Hey, here you go. Cake's pretty good! Actually reminds me of the cake I had on Saturday when I picked up my son from one of his friends' birthday parties.
00:28:25.840 Oh, you have a son? Yeah, I got four kids! Four kids? You must be so busy! I bet you don't have much time for coding outside of work. Yeah, pretty busy, but you know, managed to squeeze in a hobby project or two on the side every so often.
00:29:09.480 You're working on anything interesting at the moment? Yeah, I'm working with the ABA... maybe. Set a framework? Oh, framework—no, no. ABA, it's the Australian Breastfeeding Association. My wife used to be a practitioner there. Yep, doing volunteer work on their website.
00:30:43.680 No, no, it's not that. It's just, you know, even at a high level, it doesn't seem like anyone can explain to me the purpose of what we're trying to do here. No, maybe it hasn't been as clear as I thought it was. You know, when we go back, maybe I should draw you up what we’re doing on the whiteboard and see if I can give you a better run-through.
00:31:18.000 Good idea! Let’s get back into code. What? Oh, it's not what you think! No, no, that's a good friend of mine; she's a professional kickboxer. I was just compiling some videos for her. Really? And skipping lines? That's cool!
00:31:59.500 That's cool too! Uh, she looks pretty badass! Did she win that fight? We can talk about that later on at the bar! All right, so you know what? We probably should have started with a whiteboard overview of the problem we're trying to solve right at the beginning.
00:32:39.540 So, as you can see here, we have a component structure for our to-do list, and this is the way it's implemented. We have an app component which renders a new item form where you're going to add your to-dos, and a list of items.
00:33:04.740 Right? And we want to be able to delete an item, so there's probably going to be some kind of delete button on that component.
00:33:21.780 Correct? However, that's the app component, whose responsibility it is to tell the item list which items to render. Ah, right! And so we’re going to need a new function to add a function to the app component, which gets triggered when we call the delete button.
00:33:52.640 Precisely! And in order to call it, we'll have to pass a reference to that function down to the item component. I think we're on the same page now. You know what? When we start coding, I reckon we should try some ping-pong for a bit.
00:34:20.800 Ping-pong? Ping-pong? Show that doesn't seem appropriate for the workday! No, no, no! Ping-pong pair programming, where one person writes the test, the other one writes implementation and then we swap. We ping-pong. Oh, okay! Well, that sounds like a good way to stay focused! Let's give it a go.
00:35:51.640 foreign! Cool, so we have our failing test here. Hang on a sec. Uh, you can hardly even see the screen. Look, I've got another keyboard here. Let’s give you that, and let’s put the screen a little bit more in between us so we can both see what we're doing.
00:37:02.580 And then that way, we can both contribute equally to solving the problem. Yeah, that's much better. Do you think we could put the font up a little bit as well? Yeah, uh, do you want me to change the font? No, well, no, no, you're happy with that one.
00:37:23.700 Okay, cool, good call. All right, cool! So if we go back to that failing test, uh, yeah. So we have a failing test because it's not finding the function; because you’re not passing it through. So given I wrote that test, I'll get you to implement?
00:38:03.300 Yeah, cool! I might just get rid of that nail? Yeah! Who does that? Cool, so in the code here, we've got that failing test. So if we just jump over to the app, and here we can see—oh look, there's a function, remove item. That's what it does.
00:38:27.740 Oh, you actually wanted to see the implementation, right? Should have been a bit more forgiving for that. Yeah, cool! Okay! And so down here we can see we're rendering a list with items, and what we want to do is we want to pass that a remove item function. And if we run that test again now, it's passing! Whoa!
00:39:34.420 I think we're ready to commit! Let's ship it! Well, hold on! Before we get so excited in our perfect code, let’s jump into the browser and see if it really does what we expect.
00:40:12.860 So if I jump into the browser, we've got, obviously here, our list of items. What do we want to do? We want to get a beer, and we want to get our Pad Thai. And nah, I don’t drink personally, so I might delete that one.
00:40:25.300 But there's actually no delete button. All right? So we’ve written the test, but we haven’t actually written all the tests yet. Correct! So if we just—uh, still in the ping-pong, I’ll write the next test!
00:40:47.780 Uh, jump back into the... um, the editor. This is a concern of the item and we can see here in the item test, when there is an item, yeah, we can check the checkbox and call toggle complete.
00:41:01.420 We're going to do something again really similar. Cut and paste is your best friend. Um, this is going to call remove item when the, probably some kind of button, yeah? Button?
00:41:38.920 I think that's a good idea! It's cool! So, on the wrapper, what we're going to do, we're going to find a button element. We're going to simulate the click, and we're going to use our mock remove item method which has been prewritten for us.
00:42:06.300 Uh, and if we jump into the was that the terminal now, we should get a new failure. Cool! We couldn't actually find a button to click on.
00:42:49.900 So, right, and that's what you showed us in the browser. So maybe now, we'll swap across to me? Yeah! Um, right, so on the ping-pong side, I will go in here and go, okay, so we need a button.
00:43:05.300 So if I go into my JSX component and in here, we can throw in a button and maybe we can just see what that does, because before it couldn’t even find the button. But now, do we get a different failure?
00:43:26.740 Oh, we do! Um, it found something because it clicked it, but it hasn't called that expected method at the end, so I can now do an on-click equals—um—and it's remove item, right?
00:43:56.300 I think you want that to be an arrow function. You’re across those, right? Oh yes, six! Yeah, right! So on click and that—oh, why did I even put that as a string?
00:44:35.440 You know, sometimes you get a bit nervous in front of other people... ID? And you said arrow functions, so we'll throw that in there. You reckon that looks good?
00:45:28.060 Always! Best way! Oh, there you go! Nice! Let's commit now! Well, do you want to just check in the browser to see if it works?
00:45:45.740 Good reminder! So you didn't want beer? No, look at that, we've got a bug and we've got remove item working! Hey, um, look, this is great! Let's do a commit now. Are you good if we did a lull commit again?
00:47:04.620 Um, you know, checking the time, um, it’s probably just enough time before the end of the day for a quick retro. Um, what do you think went well today? I think that last piece of ping-pong pairing was a huge success! We smashed that feature out in no time!
00:48:16.620 Let's call us team ship it! Yeah, I agree! Stepping back to draw it up all on a whiteboard really helped to get both of us on the same page. There were a few things that didn’t go so well, though.
00:48:35.830 Hmm, yeah! Actually, when I think about it, there was one or two distractions throughout the day. One or two?! I can recall a lot more than one or two! You playing on your phone, switching up the fonts every five minutes! Oh! And not to mention clipping your nails at the desk!
00:49:47.540 Yeah, you're right. Maybe I should have left that at home! You seemed really distracted when I came back from my run too.
00:50:09.600 Um, you were dripping sweat and Pad Thai all over me! I think it was definitely much more productive to take a longer lunch break in that case!
00:50:26.160 Yeah, well, it did work out for us in the end! But maybe next time we pair, if we had some sort of guideline to help us get started, then we'd be effective sooner, right? And the first thing would probably to sort out ergonomics.
00:51:11.600 So once we buy vanilla, we both access to the machine, it was much easier for us to both contribute. Uh, yeah, that's right! And, uh, that's a great starting point. Another one might be just to eliminate all distractions from the beginning.
00:52:02.460 Yeah! And, you know, take regular breaks for things like, you know, social media, tea breaks, snacks, and personal hygiene outside of core pairing time!
00:52:41.620 Right! And lastly, regardless of how small or simple the work seems to be, talking through it and coming up with a plan early on means we can both focus on coming up with an improved design. And most importantly, we have an opportunity to both contribute our ideas and 10x our pairing.
00:53:24.760 You don't need much to get started; just a few simple guidelines and an open mind. I hope you've enjoyed our presentation today. We have been Selena Small and Michael Milewski.