Coding Blocks - Clean Code – How to Write Amazing Functions

Episode Date: October 17, 2016

We continue talking our way through Clean Code, taking a deep look at the building blocks of programming in the quest to write the best functions. Oh, and everybody sings. The original version of the ...show notes can be found at: http://www.codingblocks.net/episode48. Podcast News iTunes Reviews: BrokenDev, Simontheu, Hruncito, TerrenceD, Rich11145, HardCoreRockstar, Bcmsco, FriendofEntropy, Fredstban, […]

Transcript
Discussion (0)
Starting point is 00:00:00 you're listening to coding blocks episode 48 subscribe to us and leave us a review in itunes to learn more using your favorite podcast app or visit us at codingbox.net where you can find show notes examples discussion and more send your feedback questions and rants to comments at codingblocks.net follow us on twitter at codingblocks or head to www.codingblocks.net and find all our social links there at the top of the page. With that, I'm Alan Underwood. Joe Zack is back. Yes, sir. And I'm Michael Outlaw. Welcome back, sir. Thank you. Good to be back. Excellent episode, by the way. Really enjoyed it. Appreciate that. We missed you. Oh, thank you. you all right so sappy stuff out of the way
Starting point is 00:00:47 let's get into some podcast news awkward moment aside let's get into more awkward moments where outlaw tries to read names bro hugs all around all right so do you want to do the itunes or the stitcher ones oh no I was really joking. I think that because Joe was out, he should have to read a bunch, if not all. Although I will say, though, that I think it was Russell Hammett commented that maybe people are just making the names more difficult on purpose so that it's more difficult for me. Hey, before we get into reading these i think the first one should have like a soundtrack to it like take this broken dev oh my god really that just happened it did all right are we recording we are so go ahead joe
Starting point is 00:01:41 you could you could read these off this time all All right. I guess now you got to sing it because he's like really up the game there. I'm really going to have a hard time next time. I don't know if you guys would like my singing. What was that? That's my metal voice. That's the only way I can sing. All right. What you got? Let's do this thing. Broken Dev, Simon the U, Hruncito, Terrence D,
Starting point is 00:02:07 Rich11145, Hardcore Rockstar, BCMSko, Friend of Entropy, Fred Staban, Ibanki7, Islander201111, IamQuaz,
Starting point is 00:02:23 Adam Hennigan, and for Stitcherer we've got Snapper109 Brian Place Vesso7 Zellig880 Cube00 Joro550
Starting point is 00:02:35 Phillip Laudy And Rocket Raccoon That was nicely done sir I feel like I might have practiced There were some tough ones in there I made it sound easy though He did have some time to practice these. While I was singing.
Starting point is 00:02:48 Yeah. So what else we got going on? I think somebody might have gotten in front of a camera while they were missing from the microphone. Yeah, I did. Yep. So I made a couple videos doing some code war problems. Just kind of wanted to give a shot. The idea is basically to do the problems in such a way that's similar to the kind of stuff that might happen in an interview,
Starting point is 00:03:11 the things you might talk about. So I tried to talk through solving the problem, and I've gotten some pretty good feedback so far. So you guys should check it out and let me know what you think. And we'll have links to that in the show notes at slash episode 48. Yep. And also a heads up, too. We don't have it in the show notes, but it will be there here in a second. You can also go to youtube.com slash coding blocks and see any videos that we've uploaded. So that's an easy way to see all of the current and future videos that will be there.
Starting point is 00:03:40 So definitely check it out and leave Joe a thumbs up on that video. It's pretty excellent. And speaking of Joe getting his interview skills ready, um, Peter Nelson and our Slack channel posted a great link. Um, then I'm kind of phrasing like how to become an engineer at Google, right?
Starting point is 00:04:01 And he had posted a link to, uh, a Reddit article that was just a link to this GitHub page that had the Google interview university and like basically everything you needed to know, uh, if you wanted to get in at, um, at Google. And the idea was that, uh, where's that post? There is this guy that wanted, wants to get a job at Google, and so these were his notes of what he needed to do to get the job. But then I also found two, which is an incredibly impressive list of things to study. But Google also has a student's guide to technical development
Starting point is 00:04:42 and has a lot of the same information on it. I thought, oh, all of this is great information. So we're going to include some links in the show notes to both of those. But, I mean, it's things like knowing the different data structures, knowing trees, sorting, recursion, processes and threads right um you know just you know a lot of things that you know you may have heard people talk about in class or in the work environment maybe we've mentioned it um yeah just a great resource of information though like even if you're not trying to get a job at google this was stuff that would be good to know yeah, just a great resource of information though. Like even if you're not trying to get a job at Google, this was stuff that would be good to know. Yeah. And just a heads up,
Starting point is 00:05:29 if Google's looking for these type things, so are the Amazons and Microsofts and the big tech companies of the world. So this is something that would help you out in any type of interview that is super technical. And, and the Google, the Google link that we'll have up there has on their page, they have things like, hey, you want to learn cryptography? Here's some online resources for learning cryptography. You want to learn web development? You want to learn Android development?
Starting point is 00:05:57 Depending on what you want to do, they're sending you to a link to something else that can teach you that, right? You want to learn about machine learning? There you go. Here's a link from Stanford University on machine learning. Excellent. Very nice. And I should mention it is a multi-month study plan.
Starting point is 00:06:14 Oh, yeah. So there's some serious content here. Yeah. I think if I remember right, when I read the GitHub post, it was – well, no, I guess it just says multi-month. I thought it was a year long process, but maybe I read that somewhere else or maybe I just made that up in my mind.
Starting point is 00:06:32 It looks like there's a translation that might be Mandarin or some other character-based language. So the Google Interview University link is apparently offered in another language as well.
Starting point is 00:06:48 And this is all self-taught. So no CS degree, right? This is, this is this guy's study plan to become an engineer at Google. That's awesome. So a heads up, I know,
Starting point is 00:07:02 I think on the last episode, outlaws tip was, you know, get out there and find out which meetups are coming up. So a couple of ones that we want to bring up here are Atlanta Code Camp is this coming weekend, which this will be helped by them probably. Or actually, this won't, this episode won't be. So I hate it. We'll probably tweet this out and maybe put it on our social things but you can still register for it it's this saturday october 15th so hopefully you'll be there and if so maybe we'll run into you uh so that's a big one coming up and if someone did run into you would you have anything you could give them high five maybe oh yeah we can probably give him a high five. Do we have anything else? Oh, are you referring to my plethora? Are you talking to me? You want to say hello to my little friend? You want one of my stickers? I saw a picture on Twitter there of some hot stacks.
Starting point is 00:08:00 Yeah, man. So coding block stickers are now a thing. Yes. And they turned out amazing. Um, they're not, uh, gigantic. So, uh, I think it was like a two inch by two and three quarter inch roughly is the dimensions of it. Um, so, you know, perfect for your laptop and, uh, I'm pretty sure that it'll make the performance of it that much better definitely um and uh so yeah we can include a link to the tweet some of the
Starting point is 00:08:33 tweets about that but definitely there's a links to sticker sticker mule and uh you know hey if we happen to see you in person we're going to be giving them out yeah we'll hand them out and and i'm going to i just took a picture of the back of Outlaw's laptop, and I'll put the picture on this post so that you can kind of see in reference. If you know how big that Apple is on a MacBook Pro, you'll see about what size it is. It's not obnoxious. Maybe it should be.
Starting point is 00:08:58 But, you know, it's a good-looking, in our opinion, it's a good-looking sticker, so we're excited about it. I mean, it's pretty much everyone's opinion. Actually, I read a Wikipedia article about how good looking that sticker was so it's actually fact because wikipedia is like really factual true that yeah um so what else have we got going on uh you're going to a conference yep there's a atlanta uh here in the atlanta area connect.tech previously known as ConnectJS, is October 20th through the 22nd. So that's always a fun one. I'm really curious because in previous years it was more JavaScript-based.
Starting point is 00:09:37 But now that they've kind of gone more general purpose with connect.tech to see where that's going to go. So I'm looking forward to that. And then, unrelated to conferences, I wanted to ring up this story about, did you know that your web browser hates your SSD? What? Have you heard about this? I have not.
Starting point is 00:10:01 Yeah. This is making the rounds here lately. It was an article that someone published based off of their findings specific to Firefox, but they're finding out that Chrome is as bad too. And the short story is this guy, there's this tool called SSD Life, and he had found that on a day that he wasn't using his computer it was just sitting there idle um 12 gig gigabytes was written to his ssd in the day that he wasn't really using it 12 gigabytes and it turned out to be firefox so you know how chrome and firefox have this amazing feature where like uh if you crash the browser you can just, on a Mac, you could Command-Shift-Tab and reopen all your tabs or Control-Shift-T on a Windows.
Starting point is 00:10:52 I'm sorry. I think it's a tab on the Mac. I meant Command-Shift-T on the Mac. And it'll just reinstate all your browser sessions, right, all your tabs back open, right? Well, it turns out that that comes at an extreme cost. So basically what's happening is in the case of Firefox, it's writing the state of the browser out to a file called recovery.js. And it's doing it once every 15 seconds. And it turns out it's not being very efficient about it so rather than looking for deltas and writing the deltas it's just full dumping the state out every 15 seconds um and
Starting point is 00:11:34 you know that is costing your ssd over time right it's wearing it out prematurely dude and we all have at least 10 tabs open at any given time right Right? So, yeah, it turns out that's pretty bad. So I did see in the Mozilla bug tracker there was a ticket to have it fixed. It wasn't addressed yet. But there is a setting. We'll include a link to the original story at, uh, serve the home.com. And, uh, you can basically the quick fix for it though, was that you could go into,
Starting point is 00:12:09 uh, specific to Firefox. You could go to browser dot session store dot interval, and you could change the, um, setting there from some, something other than 15 seconds, whatever you feel is appropriate for your setting.
Starting point is 00:12:23 Uh, I personally, I'm just going to wait until they fix it in the browser. Man, that's crazy. Yeah. It was interesting, though. And again, Chrome has a similar issue. So the author, he did update it to say that he was investigating that he was seeing 24 gig a day of writes from Chrome.
Starting point is 00:12:47 So Chrome is definitely just as bad. No word on Safari or Edge. Maybe it's too early. But I'm not enough of – honestly, I guess I just stick to Firefox and Chrome more than those two. Right. Pretty sure that Safari at least has the same Command-Shift-T feature, doesn't it? Never tried it. Yeah, so, well, I mean, if it does do it, though,
Starting point is 00:13:13 then you would assume that it might be doing something similar. Right. But, yeah, it hates your SSD, so. Unreal. Well, I have some unfortunate news. My tip from last episode, which I was really excited about, and I mean, even Outlaw had clicked and seen it while we were doing the show notes. Well, I mean, once you got the link right. After I said it right. Oath for ASP.net.com has been down basically since our episode was released. They're getting a DNS gateway failure or some garbage garbage so i'm hoping it comes back up but
Starting point is 00:13:47 just a heads up for you guys i think that's just the strength of our audience is like hammering on that site you know the poor guy is like oh my gosh why is my site getting so much traffic are we the new kardashians of the internet oh i wasn't gonna go. Did not see that one coming. Yeah. I mean, I feel like you're trying to say something about my backside here. And I really don't appreciate it. So that's unfortunate, though. I mean, seriously. And it was an excellent resource. I even tried to go to the Google Cached version of it, and it wouldn't pull up either.
Starting point is 00:14:18 So for the time being, that's just down. If it doesn't fix itself, then we'll pull it from the tip, the show tips. And that's it for the news. Or is it? I feel like. That hurt. I feel like Alan might have a little bit of news he wants to share. Or did you want us to announce it?
Starting point is 00:14:42 Joe, you want? Yeah. You want me to announce it? Yeah, you want? Yeah, you want me to announce it? Yeah, you do it. All right. Whisper it. Just whisper it. Just mumble it. It's actually really exciting.
Starting point is 00:14:51 I don't know why we're dancing around it. Alan has become an official Microsoft MVP. Yeah, man. You know what? It's actually super duper exciting. Yeah, congrats, man. I honestly didn't realize I was going to be that excited about it until it happened. You didn't realize how bad you wanted it.
Starting point is 00:15:09 You didn't want to admit to yourself how bad you wanted it until it was done. I think it's one of those things, right? If you're playing a sport or something, you're not going to feel like you really want it that bad because if you lose, you're going to feel kind of crushed. But yeah, man, it's pretty exciting. A lot of cool stuff that goes along with it. So super stoked about it. And, yeah, man, you know,
Starting point is 00:15:33 anybody that wants to give back to the community or whatever, I'm hoping that both Joe and Mike will get it here in one of the next go-arounds because it really is kind of cool to have that. Well, congratulations, man. Thank you very much. We are very excited for you. next go arounds because uh it really is kind of cool to have that so yeah well congratulations man thank you we are very excited for you it's also you're afraid to say like i don't know they might take it away but yeah i mean you can't i can't say anything i've got an nda so i can't actually talk to you guys anymore so you'll be doing the show by yourself and let's not forget the trophy oh i have a trophy i'll have to i'll have to put a picture of that
Starting point is 00:16:05 up there that's that's actually really exciting too so um all right yeah man um so thank you and uh super stoked all right well uh there was an email that we got in um between the last episode and this one that i thought was an amazing question that I really loved. And I think Joe, you're going to like this question too. I think this is going to be one right up your alley as well. And, uh,
Starting point is 00:16:31 so Brian writes in, says he's listening to the back catalog and he's currently on the episode about unit testing and that he's a grader for an undergraduate class. And, uh, you know, he's grading the, uh, code grading the code that the students have submitted, and that a lot of the students, they've developed it,
Starting point is 00:16:52 they tested it to make sure that the app worked, but he was able to quickly break their apps, right? So, I mean, you can imagine it being a calculator app that maybe he's just doing very large numbers to get overflows or whatever. Who knows how he's breaking it, but the point is he's breaking it. So he asked the question, how balanced do you guys think the testing should be between showing that something works and trying to prove that it doesn't? I honestly like the approach of proving it doesn't work well the first the first thing that i loved about this question was like what an amazing way to like just boil down
Starting point is 00:17:32 the testing into like you either prove all of your unit tests are either fall into one category either you're proving that it does work or you're trying to prove to yourself that it doesn't work right or to other people right joe what's your take um yeah i like trying to prove to yourself that it doesn't work right or to other people right joe what's your take um yeah i like trying to break things but uh i mean it kind of depends on the site that you're working on like if you're a google or an amazon and you expect you know 200 billion you know clicks per second whatever a day then um you know people are going to find stuff like that but if it's your little calculator app or something then uh you know i run a little calculator site and sometimes people do weird stuff and get errors and i i feel like if they do something weird every once in a while you get an error i don't really care that
Starting point is 00:18:12 much uh it's just not that high on the priorities as making sure that the happy path works well so um but you know your audience but say what but in your unit test oh in the unit test oh no i don't even do that much weird stuff in the unit test i like to make sure the coverage is good when i'm doing unit testing and just try to um make sure that you know the normal stuff kind of works but i don't go too crazy trying to do like fuzz testing or passing you know extremely large negative numbers or anything it's totally out there oh but i think if unit testing is more of a design tool anyway for me it's my main purpose isn't correctness it's just uh you know design tool and um for for shortening my feedback cycle and making sure i don't break things well it is important to note though that
Starting point is 00:18:56 you could have amazing coverage uh you know from your unit test and still have errors, right? You could still easily have flaws because coverage, unit test coverage does not equal thoroughness. Oh, coverage could just mean that you hit that method one time. That's it, right? Yeah. Yeah, I mean, it doesn't matter. Yeah, exactly. So it doesn't have any measurement about how many different types of states
Starting point is 00:19:24 you passed in, maybe. Literally, like you said, it just got executed at least one time. But I guess, so that's a different approach, though, than what I take. And so I was really surprised to hear you say that, Joe, because I'm normally trying to throw random things at, you know, when I'm writing my unit tests, I'm trying to throw like random things and trying to come up with in my mind, like,
Starting point is 00:19:46 Hey, what about this scenario? If I pass this in or that in, like what happens here? Or what about the extremes? Am I handling the extremes correctly? You know, what happens if like,
Starting point is 00:19:58 okay, nulls, for example, what happens if a null gets passed in? Is that properly being dealt with? Which that definition may vary depending on case. Things like that. But maybe throwing an exception is the right answer in that case.
Starting point is 00:20:14 If you try to divide by zero, you should get a divide by zero or you should get some sort of error that relates to that. But you could test that. Exception isn't wrong. Exception does not mean error. Throwing an exception is a very valid thing. So in your unit test, you could say, assert that a certain exception type is thrown. Yep.
Starting point is 00:20:38 I mean, for me, like when I was reading this and I thought about it just internally, so, you know, it depends on how core it is to something and how controlled it is at the time when you're writing the unit test. So like for a calculator, you probably do want to check the edge cases, right? Because it's a calculator. If it's something in your app that you know at the time that the unit test was created that there's controlled inputs and outputs, then maybe you just check for those certain types of controlled things. Like I don't know that I would go crazy on something that didn't allow negative numbers,
Starting point is 00:21:07 trying to test negative numbers and that kind of thing. So I don't know. It's, that's such a tough one. I think that when you're writing your unit test, at least to me, you should try and think of the different ways that it could break and write your unit test against that.
Starting point is 00:21:22 So I kind of like the approach of how can this break? Yeah. Yeah, another thing that came to mind too, though, which isn't exactly related, but I know that, like, I've done this where, you know, someone will report a bug, and they'll say, like, oh, if you do this scenario, it's broken and then i'll be like okay great i'll take that scenario i'll write up a unit test to mock that scenario and then
Starting point is 00:21:54 code until that new unit test passes yep and that's a good way to do it so i'm like literally adding on uh you to the to the, library of unit tests in that scenario. Yep. But I do think there's a point of going overboard, right? Like you can't check for every single little thing that's going to happen. So I don't know, man. That's, again, it kind of depends on how core it is to what you're doing. So I don't know.
Starting point is 00:22:23 Great question. And obviously there's already, I i mean between the three of us we've we've kind of we've kind of got different opinions so i mean for a professor that's even got to be a little bit more difficult right yeah i don't know if he said he was he was a professor just a grader he was grading yeah it wasn't clear on that point but yeah it was totally amazing question though like i like i said i really loved the fact that it was broken down into you know either you're trying to show something that works or something that doesn't work um because i never really thought about unit testing either way like i
Starting point is 00:22:55 was just testing that it um you know it works but then when i when i got this question i started thinking about i guess then that's when it kind of made me you know a moment of introspection there and i thought well i guess I actually am trying to test that, you know, to prove to myself that it doesn't work and that I need to fix something. And then I'm happily surprised when, oh, it actually did work. What do you know? Got it right. Awesome. All right. Well, we're going to get into the next section here of our Clean Code series. And similar to the last episode, we will be doing a book giveaway. Last episode, we were doing three books, so one from each of us.
Starting point is 00:23:39 And we were going to do – when are we going to do that drawing, though? Were we going to give like one episode between it? So we'll do the drawing for episode 47 when we record episode 49. Yep. And we'll do the drawing for this episode 48 when we record 50 is the plan. And then that way that will give everybody time to listen and comment if they get a chance. So there will be one book giveaway for episode 48, though.
Starting point is 00:24:09 So your chances are dwindling. But if you are in, say, episode 47 and you want to enter in 48 as well, you can. But obviously, if you win in 47, then it won't count in 48. Yep. And same same rules last time go to the show notes for episode 48 uh so www.codingblocks.net episode 48 and leave a comment there to enter yourself into the giveaway yep and there have been some fantastic comments on 47. So, you know, feel free to add to that one, too, because there's still time to enter to win. Again, 47 is three books we're giving away. 48 is one. So your chances on 47 are a little bit better. So definitely go up there and continue to leave comments and and we'll revisit this in one more episode. All right, so here we go. This is chapter three that we're diving into, which is functions. And this is an absolutely fantastic chapter. A lot of meat in here, so let's jump on in. Yeah, so this was the, you know, I gave it away in the last episode,
Starting point is 00:25:26 but this was specifically the chapter where it time-boxed the function and says, can you look at a function and understand it completely within three minutes? Because if you can't, if you have to study it for longer than three minutes, then that function is too complex. There's something wrong with it. Yep. And three minutes and that method is or that function is too complex there's something wrong with it yep and three minutes is a long time you know but i kind of think that nowadays attention spans have shortened a little bit and now it's more like one minute yeah you know
Starting point is 00:25:56 actually though is that even fair because uh have you seen some link queries yeah so it's funny they had their first and second rule of functions the first one is a function should be small and then the second rule was it should be smaller than that right so i mean that's pretty much it and they say that it should be barely 20 lines long i love that 20 lines i mean 20 lines in java is like. That's like no code. That's hello world. That's just your declarations. Well, yeah, but they're talking about the entire method,
Starting point is 00:26:33 not all the usings and everything along with it and the class declaration. No, this is specifically the function or a method, right? Not all your headers at the top of the pile. Oh, so that's actually a great point, too, to call out. We're not talking about – there's a whole other chapter for classes yes this is not a class so this is you know specifically like the previous chapter was on like the guts inside of a function and this one is in you know is about the function function i mean one of my very favorite things in this entire chapter was when you're looking at a function, it should
Starting point is 00:27:06 read like a story. Like you should be able to just kind of scan down it and it say something like do this or get this or, or do this. And then, you know, stop that. I just love that idea that it's almost like a narrative. Yeah. And I love this broken down too. So like, let's say you hop into a public method and you're trying to find something in there to change and you see less than 20 lines and it's like do this, then do that, then do something else. And you know, oh, I need to go to something else.
Starting point is 00:27:34 So you can hop right into that function and you've just skipped possibly hundreds of lines that you didn't have to scroll through. And I know, I'm sure you guys have been on the phone or on a web app or something with somebody and you're talking through and they're like, yeah, scroll down about 190 lines down to 414. Oh, man.
Starting point is 00:27:49 You're just scrolling, scrolling. You're watching the ifs go in and out, you know, like a waveform, and you're just trying to keep track of where you are. Well, here's like the classic, though, is that the function should do one and only one thing. So if you had to describe to somebody what this function does and you have to use the word and, chances are your function is doing more than one thing. Yeah. And this one, and I love this one, but there were even parts where they say,
Starting point is 00:28:19 this may seem sort of contradictory when you say it's only doing one thing, because what if you do have a logical statement in there? Like if this, then this, right. And what they described was basically when you say it's doing one thing, you're actually only accomplishing one task. That doesn't mean there's not a decision in that task, but you're only doing that one very specific thing. Well, yeah. And actually I'm pretty sure this was the same section too or maybe it was another one where it was talking about um switch statements and how that felt kind of uh wrong oh actually it was the next section it was in a uh uh later section within the book but um where... I'll go ahead and skip ahead to it. Where the switch statements felt kind of like a betrayal to the one doing one thing, right?
Starting point is 00:29:12 But the one blessed place where they said, you know, use a switch statement was in the case of, say, a factory, right? Yeah. That was an example where i was like okay well this is okay this is an acceptable version but it's only doing one thing right it's creating instances of class returning some instance type right yep uh and so the switch was acceptable there but if you're doing a switch inside of some other function and you're using
Starting point is 00:29:43 that switch to decide, determine logic, then it's doing too much. And the thing with switch statements, they're like gremlins being fed after midnight. You hardly ever see just one unless it's in a factory. The deal is you do a little switch statement somewhere and you're like, oh,
Starting point is 00:29:59 this word, if case A, case B is this, inevitably you end up doing another one to kind of translate it back at some point. And then next thing you know, you're doing a third one. Next thing you know, you've got like 16 freaking switch statements, and you're starting to think maybe I should have encapsulated this somewhere. Yep, and they're almost always doing the same type thing. And they even talk about that.
Starting point is 00:30:19 If you're doing a switch statement, chances are you should have some sort of method on a class that will return something, right? So like instead of saying, you know, case when, you know, origin is American, then return first, middle, and last name. Case when, you know, some other thing, then just return first name and last name. Instead of that, you should have different classes of those types that say get full name, and then they can do their own thing. So there's no switch statement there. You literally had an interface that had get full name as the method, and then when you call it, it does its own thing. Well, I did remember a little meta here.
Starting point is 00:30:59 It was that I'd forgotten that we wanted to do the code review, the live code review. Remember that conversation? Oh, yeah. You said that there was something that bothered you in a code thing that I'd done, and I don't remember what it was. Well, there was some code of mine that you had, you know, I'm going to quote it, cleaned up, right? Okay.
Starting point is 00:31:20 But I remember, and the reason why this quoted that is because after the after you did it and you sent me the the pull request you said yeah i guess uh you know everything that we've been talking about with clean code kind of got to me so i decided to clean some of this up and then i was like that's what was kind of like like not a stab at me but it kind of like well i was like whoa hold up wait a minute oh because because i think you took that wrong first off i didn't even know it was your code i know you didn't that was the beauty of it but but because like there was there was um because like where the the method that you cleaned you quote cleaned there was there were uh there's two things that
Starting point is 00:32:04 i thought like, that was honestly bravo. That one part was good. Because one, there were some hard-coded numbers in there, and you identified, made those constants, basically. So I was like, okay, yeah, that one I agree with. And then there was this other one
Starting point is 00:32:20 that was actually a hack specific to IE that you put into a method named as much and i thought okay you know yeah that makes sense but the rest of it though the quote cleaning of the rest of it where yeah it was reducing lines i was like well that's really not fair because i had i had like maybe because of the the way i var things and this is in javascript so the way I var things, and this is in JavaScript, so the way I var things up is I'll have like one per line, right? So I had like var some variable comma,
Starting point is 00:32:50 some other variable comma, some other variable. And so a part of your cleaning of that was just getting rid of that, and you had replaced it with method calls to return back those values. But nothing was ever being varred, so it was constantly having to return back those values. But nothing was ever being varred, so it was constantly having to go back
Starting point is 00:33:07 and reestablish what the variable was. Okay, so I'll tell you why I did that. And I mean, out of context, this might be hard to follow, but basically what it was, there were the same chunk of like four or five vars in every single method. No, this was only in one.
Starting point is 00:33:21 No, there were several. And the reason I know this was because the reason I even did it in the first place, because you moved them into multiple methods. That's why, but the original method was one method. No, they were in multiple. And the reason I remember this is the whole reason I broke them out was because I was trying to chase down a bug that was completely not obvious. It was in the core framework that we were using and it wasn't actually in the code we were doing. But in order to identify it, I kept having to put breakpoints all over the place where these same things were happening.
Starting point is 00:33:52 Okay, and this is why I'm bringing this up now, because at least— But you're not going to let me finish. So the reason I broke them out, though— Well, you said it, because you said they were repeated. So I wanted to make it to where I had one place to go to to debug the code every single time. And that's what it boiled down to was instead of having to put breakpoints all over the place, I could put them in one method and say,
Starting point is 00:34:13 okay, did this give me back what I needed? Yes, okay, so cool. I know that's good. So I can't comment on that because the pull request that I saw, my code was one method that had a section of stuff varred. And then that one method was split into a bunch of methods and a bunch of the, several of those methods were one liners that returned back something.
Starting point is 00:34:34 But instead of them being able to use a variable to get, so like picture you have a class that has a, you know, some other class that has some other class. And instead of each one being able to, you know, having a reference to it, it was like recalcul that has you know some other class that has some other class and instead of each one being able to you know having a reference to it it was like recalculating you know the other class to get to their class no actually what the point is but the point is here's the point here's the point is that specific as it relates to this section is that like how do you know when a function is doing more than one thing right and it's it's if you can extract another
Starting point is 00:35:07 function from it where it does where the where you can extract a function from it with a name that is not merely a restatement of the implementation then it's doing more one thing and that's what i'm saying here in this example was you had you had like methods where it was returning back like uh you know some some object but it was literally a one-liner that where i had it as a var statement before and that reference was saved and kept now it was something that was going to be called three more times by something else not true but basically but basically what it was. So here's the way it worked. There was a var block. I'm going to pull up this.
Starting point is 00:35:48 There was a var block, and we're not going to go on this for too long because it's kind of ridiculous, but there was a var block where the first variable set the second variable will build off the first one, third one build off the second one, fourth one, and it's the way that the framework works, right? So the problem was I needed to be able to access these things in different ways in different points. So it wasn't like it was rebuilding it all the time, it would just be
Starting point is 00:36:09 able to get to a reference because these things would look something like it's ext js is what we're using. And it would be something like ext s dot lookup reference dot something dot something. And I was like, well, this is kind of of ridiculous because I just need that tree so I would say get tree right and so instead of having all these dots dot dot to do something I was like hey just get tree so again it was basically just so I could get things back and so it would read better because when you have a bunch of dots on a line that are you know 60 characters long it's hard to see what's going on so anyways i think i mean we beat it up enough did that part really need to be there not so much but the cleanup that i did was more
Starting point is 00:36:51 the reading well yeah but this was i mean specifically this was one method um to go back so point is that the effect can be a little controversial sometimes totally well no but but i'm totally lost absolutely Absolutely, it can be. On what this function looks like. But the point that I was trying to get at was that if you're only creating a method that's just... How do they word it?
Starting point is 00:37:16 If you're... Restating what the variable is. But here's the thing. Yeah, merely restatement of the implementation. When there's a bunch of dot, dot, dot, dot, dots, then that's really just a bunch of garbage, right? Because now you're saying, okay, I'm calling lookup reference to this, and I'm doing lookup reference, then I'm getting controller, then I'm doing this.
Starting point is 00:37:31 So the whole purpose was I need this to read more like a narrative. Get me the tree instead of get this variable and then get its controller and then get it some value, right? That doesn't read well. So the purpose was readability. Read it like a narration. So again, I didn't even know this was his code. No, that's why this was so beautiful. That's why I was like, oh man, this would be awesome.
Starting point is 00:37:53 Let's talk about this. But the restatement thing was more so along the lines of the clean code was, you should be able to read the thing, right? And that was not readable because that got into the, okay, which variable am I using? Just for the audience to be able to follow along here, okay? This method that I'm talking about had four var statements. Then one method called one if statement where the if if statement has one line the else statement had one
Starting point is 00:38:26 line and then the the ie hack that you pointed out there was also one line now calling out the the ie part into its own thing i thought oh that's awesome that was that was a great idea i liked renaming that specifically as an ie uh hack because that's what it was so really there was this if statement that you know even with know, you have an if and else, and then the two lines, one for the if, and then one for the else. So four lines there, right? And then there was this other one check that was like, okay, you can make the argument that, you know, is it doing more than one thing? Well, it's setting this state here and doing this if portion over here. So maybe you can make the argument there but the point that
Starting point is 00:39:08 i was getting at was that the four lines of the vars i was like well that's not fair to call that as like cleaning up if i think you took it out of context though because the cleanup was the entire pull request it wasn't those four lines of code, right? So, I mean, again, I think this is way past being blown out of context in that the entire pull request was trying to fix a problem. And the only reason those things were pulled out like they were was so I could more easily debug. And the end state ended up being a little bit more readable than the beginning state. And so that's really what it boiled down to. The callout wasn't the four of air lines. Well, I guess as I go back to this chapter this chapter though or this entire book rather is like there
Starting point is 00:39:49 are things that they'll that they've said and done in this book that it's like where where like i just clearly don't agree with right and and uh you know even in later parts of the book like you mentioned it last time when we talked about there being um i guess you said, I forget how you worded it, but something along the lines of you felt like there were not discrepancies. Contradictions. But contradictions. Thank you. And so there were things like that here too. But there are definitely things where like, you know, I didn't agree with, but then things that I did more agree with.
Starting point is 00:40:21 But here's my question though. Let's boil it down to the very end state. Was it better at the end of it than it was at the beginning? Not the VAR statements, not any particular one. Was it easier to read the method in the end state of the pull request? Man, way to put me on the spot. No, I mean, but that's really what it goes down to. I felt that there was part of it that I liked,
Starting point is 00:40:45 but then there was definitely part of it that I didn't like, which is what I'm getting at. And that's what I'm going to say. It's easy to dissect things. And this is my take on programmers in general. Oh, yeah, we're a finicky bunch. No, no, it's not that. If we took 10 programmers and we put us all in a room
Starting point is 00:41:00 and we give us all the same exact task, you will get 10 different programs on that outcome. And so my thing is, and even with this, because I remember when you said something bothered you about it, I was like, what in the world bothered him? And I mean, seriously, I thought about it for five seconds and I was like, well, it couldn't have been a big deal. I only changed like 20 lines of code. No, but it was just more about like, you know, I enjoyed this conversation. But on the flip side of it, I guess my point is, is everybody's going to have a slightly different take.
Starting point is 00:41:29 And as long as you're leaving the code, as long as you're not making it worse, right, then you're doing a good job. And I would argue that anybody that looked at that, minus the VAR statements, minus anything else, if you look at that entire method that was done now it's very readable from top to bottom like a narration because really the one thing that stuck in my head was that it will be able to read it yeah and so and so this is where i'm going with that and so like you know you asked me if i thought it was better like you know there were some parts of it that i thought like like i said like i liked the fact that the ie8 hack was called out
Starting point is 00:42:01 but then there were other parts where i was like well i feel like i feel like you can over refactor something like like we talked about in the last episode the boy scout principle and and going back and and fixing cleaning up something and i thought that well you know you can over refactor something or overdo something right and so i why the beauty of this was like this was a live example and you didn't even realize that it was mine that you did and then made the comment to so i was like oh this is awesome right like this is a great great example but whatever there was another point too like going back to things that i i strongly don't uh share an opinion or same share the same opinion with the authors of the book is this step down rule right where they were saying that you know to have their have the methods within the class listed uh i believe this
Starting point is 00:42:58 was the section right where they wanted to have everything listed um you know like one method as you to the next. Wait, is this the same one? Well, the step-down rule. I think I'm thinking of further up in the book. Well, the step-down rule. No, it's down there. He just marked it in the show notes.
Starting point is 00:43:12 The step-down rule was everything should be at the same basic operating level. Yeah, so it's like a nice hierarchy of organization. Yeah, and that's actually the hardest. Okay, that's not the one I was thinking of then. I was thinking there's another that I thought was referred to as the step-down rule. There's another section in here where they talk about organizing your functions so that the caller is above the callee. So you always have your callee function below the callers. Does that make sense?
Starting point is 00:43:42 Yeah, I don't remember if I saw that. And I hated that when I saw that. Basically, like, if you had a method, oh, gosh, you know, that would be like create user, and inside of the create user method, it has a method called set name, let's say that it calls, then set method would be listed below create user.
Starting point is 00:44:10 Yeah. And the reason why I specifically hated that was I was like, well, as you refactor these things over time, that's all going to change. And here's the thing is like, I don't even have a good answer for this because my preference for this – oh, why?
Starting point is 00:44:27 Something crazy is going to happen. We've argued about this before. I just had a flashback to you and I like three years ago having this exact same conversation. Oh, really? And I won by the way. You did? What did you say? Yeah, I convinced you.
Starting point is 00:44:37 I guess you must have forgotten. Well, we'll find out because my preference is to just put them in alphabetical order. I hate that. Yes, that it totally wrong the ide gives you a drop down for the methods and it puts it in alphabetical order so what so you just put them in random order yeah yeah but see that makes even less sense like the so the author of the book privates and my publics together and past that i don't care okay fine i i i'm okay with organizing the privates and the publics, having some categorization there,
Starting point is 00:45:07 or whatever the level is. That part I have less of a problem with. But to say that always categorize it so where, let's assume they're all public, and the create user is definitely ahead of the set user or, you know, and let's say that there was a git, you know, let's see, set user. No, I said set user name, right? So what could set user call that would possibly be alphabetically after? But, you know, let's say it calls some git method.
Starting point is 00:45:41 The set username calls some git method that you know it just doesn't make sense to me to do that so i would prefer to just have all the methods in alphabetical order but you know even with refactoring the names the names could change too so therefore the order is going to change but to just do them at random order as what you're saying no no i'll take it i'll take it back i actually don't do random i usually put if we have sets and gets i I'll put those together, but I'll put the newest one at the end. That's almost always what I do,
Starting point is 00:46:10 mainly because I don't want a bunch of things jumping around in code. Like the whole thing about renaming, I can't stand that. Like, I don't know. Wait, renaming? No, no. If somebody renames, I don't want them to also move it because it just wreaks havoc on like – Yep.
Starting point is 00:46:26 So what you're saying about putting them in alphabetical order, if you rename that thing and move it, you're going to confuse every single piece of comparison software. Well, that's why I said I don't have a good answer for this because if you rename it and you leave it as is, now it's out of order. Hey, Joe, I feel like you were going to say something. What's your take on this? Yeah, I'm blowing my top over here, guys. That's totally incorrect. The book is spot on. And actually, I think I probably got all of my functional habits from this book because I agree with pretty much everything in this chapter.
Starting point is 00:46:53 But, I mean, you've got to have it in order. And these things do not move around like that. They don't swirl around like crazy. And if you're worried about stuff being called multiple times by multiple different public methods, then your class is probably too big and it's a monster class and doing something. That's an interesting thing. different public methods and your class is probably too big and it's a monster class and doing something. If your class is small, then you should have mostly private methods and most of those guys shouldn't really move around. You've got your function basically divided and your
Starting point is 00:47:13 public function divided into major sections like this part gets the data, you do some logic and then you do some presentation type stuff. And that stuff doesn't really move around too much. It's nice that you can scroll past your public into your privates and then you basically see them in the order that the public method calls them it's so great to read like that no man because you're gonna if you refactor some stuff and now all of a sudden some other method is calling it or you know you
Starting point is 00:47:38 break stuff apart now all of a sudden the the order could get out of whack i don't know man i still don't like the alphabetical thing because i don't like if a name changes that you're moving it around i would actually i mean but the same order could change based off of their recommendation about the function the way you call it you know the callee should be below the caller agreed that's why i put my new ones at the bottom of that section like i don't even worry about it we have ids to answer these problems there's no reason for you to manually alphabetize things. They had IDEs back then, too. Yeah, I don't know.
Starting point is 00:48:11 Don't get me wrong. I'm not saying that I'll go and throw in a pull request where I've done nothing but change the order of the methods listed in... You actually complained to me about a PR a while back because I didn't put something in alphabetical order. I was like, I didn't even notice this. Oh, because it was my code. That's why.
Starting point is 00:48:29 I was like, really, man? I was totally not changing this. I do hate seeing that. I'll see like 40 things in a row, say it's some sort of config file, so I didn't do it in alphabetical order. I can't stand it. I figure they're both equally arbitrary. What does it matter? figure they're they're both equally arbitrary
Starting point is 00:48:45 like what does it matter because they're going to get refactored things are going to change so really you know alphabetical is just as good hey so going back real quick so getting back to this whole thing this actually comes from that pr that you were talking about earlier that i didn't even realize i had modified your code one of the things i is, and I like this in the book, and they actually say right here, code with an if blocks or statement should be one line long, meaning they should call a function. I don't know if that's overkill or not, but I ended up taking this approach because there was something like, hey, if this is the micro nav bar before it said something like set with the 50 or something, right? Right. That was the hard-coded part that I liked.
Starting point is 00:49:26 And then it would say else if it's not the micro navigation, then set the width to 300, we'll say. And instead what I did, and I liked it because it made sense, I said set micro nav size, right? And then I had another method that was like set, you know, large or full nav size. And that whole narration thing to me was just beautiful because it's easy enough to see that, hey, one was 50, so it was smaller, and the other one was 250. But it's not – it doesn't explain things as well, right? Basically, for anyone trying to visualize what this piece of code did is if you've ever seen a navigation of an app or a site
Starting point is 00:50:04 where you have a hamburger on the upper left or upper right and you click that hamburger and some navigation grows out, right? Then that's what this is. So this navigation could have either a miniaturized version of itself or a full width version of itself. And depending on what the state was, this method that was refactored, this method was responsible for flipping the state to one or the other. So you would pass in what the, or it would determine what the current state is and flip it to the other state.
Starting point is 00:50:39 And so that's what he's referring to. So yeah, just the readability, like, hey, set micro nav size or set full nav size. And that really stuck with me. I liked it. I think overall, I usually code that way. But definitely in a lot of cases, I would have probably just said set width 50, set width to 300, right?
Starting point is 00:50:57 Just because you know in your head, this is what you're doing. And so it's real easy to not just break that into another method that's really a one liner. But it's very easy to read it when you go down through that. Yeah, so those are the parts that I liked. Yeah, so... Unvarring my vars. Oh, whatever. The next one that I'm curious as you guys' take is the indent shouldn't be more than two tabs, which basically means you shouldn't have much more than an if else if anything else in there i think we may have covered something similar to this concept before with the uh code calisthenics
Starting point is 00:51:30 concept i don't know does that i know joe remembers that right you you know what i'm talking about i know i always complain about this in program images particularly python oh the the tabbing actually means something to the language? Yeah, well, I mean, with Python, I've seen terrible scripts that have five levels of indentation, and because Python doesn't have braces, it's like I end up holding a piece of paper on the screen and scrolling down in the eye like,
Starting point is 00:51:57 okay, where's this if end? Because someone wrote a really long function and had lots of levels of indentation, and both of those are pet peeves of mine. That's interesting. Yeah, I mean, I like the idea that a method is really only, you know, you might have one conditional and that's pretty much it. Or you have a bunch of method calls that each are doing different things.
Starting point is 00:52:18 So I like it. I don't know that it's practical in every sense, but I do like the idea behind it. So here was one that's kind of in the same vein as our last conversation, which was to use a descriptive name, and that long names are not a bad thing. Don't be afraid to use them. Where was that? Right here.
Starting point is 00:52:43 Oh, that's way far down. Here, look. I'm going to show you my book. Can you see that? You're not looking at the show notes at all. I'm just joking. Oh, man, that's boring. Yeah, totally.
Starting point is 00:52:53 I mean, the name should tell you exactly what it does at an instance. But with that, there also came the whole idea that you should use standard type names, right? Like set or get or standards in Java or do or something like that. Oh, man. It drives me crazy when gets do other things, which happens all the time. Yes, totally. To say get first name, it goes out, queries something in a database, stores it in a cache, and then returns.
Starting point is 00:53:20 Man, that's not getting. That's doing a bunch of stuff. Yeah, yeah. Well, I think the idea was that your functions should be verb names and your properties should be noun names. Yeah. Yeah, I do like that. I just don't like when functions do too much, and so you might do something like, hey, get me elements out of this array,
Starting point is 00:53:44 and it actually removes the other elements or it just modifies some sort of other state and stuff and or it sorts it in order to get it apparelant from the yeah yeah none of that but you know as it relates to the names though especially the long names like it made me think because especially my unit tests are my unit test names get really long. Like really long. Yeah, they should be descriptive, right? Yeah, because I try to write my unit tests to where, you know, there's no comments there. From the unit test name alone, you can get an idea as to what I'm testing, you know, the method that I'm trying to test, and the scenario that I'm trying to test
Starting point is 00:54:27 and what I expect to happen as a result of that, all in the name. And so you can look at it and know. So they get really long. Yeah, but it's nice because when you see that they've passed or failed, you know exactly what passed or failed without going and looking at the code, which is what you want.
Starting point is 00:54:43 Getting into your, well joe's got this highlighted one way to know if you named it well is to put two on the function name and see if it does what you think it should oh right i don't understand that at all yeah but no wasn't that um to get first name right to get last name does it actually do it to set first name to set last name you know or no that was that was based off of the the logo language which is one that i'm not familiar with but it used the keyword to in the same way that uh ruby and python would use def and so they were saying like you know if you could if you can describe it in the to format. So I'm not defining this function.
Starting point is 00:55:29 I'm saying to do this action does this. Yes. Which is a different way of thinking about it. Okay. Yeah. We can describe the function by describing it as a brief to paragraph. Making it a verb. Right. The thing that we started to talk about earlier, the step down rule was kind of interesting.
Starting point is 00:55:45 And honestly, I think is probably one of the most difficult things to do was keeping things on the same level of abstraction. Like they, in the book, they had a code example where they were doing like a, a set up and a teardown of some sort of method. And it was doing things like getting HTML and setting paths and all that kind
Starting point is 00:56:04 of stuff. And they said, you know, keeping things on the same level you actually have to think about because get html doesn't belong in the same place as get path doesn't belong in the same place as path.append like they're all different levels of abstraction and that that can be difficult oh man i tell you the worst methods i've ever written in my life have all been refactors of existing code where I just started like kind of starting to separate stuff out. Like I'm going to grab these six lines, refactor those to a new method,
Starting point is 00:56:34 and then, you know, the refactoring tool will grab all the arguments and stuff that it touches, and next thing you know, it's like, whoa, I'm passing in seven arguments. Two of them are out, and it returns something. Oh, God. And you start looking at the code, and it didn't look so bad when it was in the function, two of them are outs and return something. Oh, God. And you start looking at the code, and it didn't look so bad when it was in the function, but then when you realize,
Starting point is 00:56:48 when you start to refactor that, that the reason it's doing that is because it's all mixed together. It's grabbing data, it's doing some logic on it, it's rearranging it for output, all in the same kind of spot, and then you've got like a 400 line function
Starting point is 00:57:01 that does this sort of stuff, but once you need to start rearranging these things or changing the presentation, you realize that now you've got to also start changing your data code and your logic code and your all sorts of stuff. And it just got its fingers everywhere. And you can see that it's total spaghetti, but none of that was visible when you first looked at that function.
Starting point is 00:57:16 Cause if you read it top to bottom, it kind of made sense and that it just wasn't organized very well. Yeah. And that's where you just give up and you're like, I'm just going to commit this as is and move on. And sometimes you have to. And you know what? That's a killer comment and a call-out
Starting point is 00:57:30 because what you just said with those refactors is the problem is there's not enough abstraction, right? Because what you were just saying with all those, you know, these out variables and all this setup and it's going and doing all this stuff, because it's not abstracted well, you can't pull it it out you can't just refactor it into a new method you've really got to start thinking about do i need to create another class that'll do this right and then does that need to have another class that does some other things and it becomes a major effort yeah
Starting point is 00:58:00 and so i figure it's like kind of the boy scott rule so by first just kind of extracting out those um those methods for the part, even if it does mean having multiple arguments and other really gross stuff, I do think of it as an example of the Boy Scout rule where I'm not changing things too much, but I'm at least showing what the problems are because before they were hidden. And so I'm not actually making things worse. I'm just exposing the problems that were there. So what about breaking your function up
Starting point is 00:58:25 into sections? It means it's too long. That's what they say. What about SQL though? Because that's where I do a lot of banners. Like here are my declares. Here's the 60 line query that does this part. Well, I feel like the one place where this is totally acceptable
Starting point is 00:58:41 and this is fighting words if you don't agree, would be in the unit test though because i like the the i think they call it something else in the book if i remember right but i i know it now as the uh arrange uh act act and assert uh format so you'll have like three sections of your code one section is where you're just arranging the state that you want to test there's the act where you're going to actually do whatever action you expect you're trying to test and then the assert is where you're going to test the result of that action that's interesting i mean you could break those down into private methods right that do the arrange the act and that's exhausting it would and the range would be annoying because
Starting point is 00:59:24 you're usually setting a bunch of variables. So it's like, are you going to write a class then and return that class for every unit? Yeah, that'd be horrible. Yeah. And it wouldn't be as readable. Yeah, every test would be three private methods and a class. Yeah.
Starting point is 00:59:34 Yeah, I think in unit tests. That's what I'm saying. Unit tests is the one place where I feel like this is acceptable. Yeah, I would agree with that. Because also, too, yeah, because what happens now when you want to have, okay, let's say you did break it out into methods. Let's not even talk about classes.
Starting point is 00:59:49 But, you know, you have one methods where, you know, I don't even know what that method name might look like, but it's got to be descriptive because that's what they said over here on page 38. It would basically be the same name of your method with arrange, right? It'd be something arrange. And then here's the state name, whatever you're going to set up. And arrange
Starting point is 01:00:13 integers that might overflow the buffer as the method name maybe. But then as soon as you start having more than that one method using that same thing, and they need to change something, then it's like, okay, well, I'm going to have to have two versions of this method. One that's slightly different. Yeah, that's just gross, man.
Starting point is 01:00:35 Just keep your, I think in unit tests this is okay. Because also, your unit tests should be small enough anyways. Yeah, agreed. What's the longest unit test you've ever written, Joe? You don't want to ask me that. I'm sure it's been terrible. Three lines. Where I was going with that, though, is the unit
Starting point is 01:00:53 tests are normally 10-ish lines, maybe? They're not terrible. They're not usually big because there's a couple where you're setting the variables and then the rest is just one method and one assert. I've done some terrible things though, like initializing
Starting point is 01:01:09 huge objects and stuff. Some terrible things. I really have. And you can watch all that on YouTube here in the near future. I've been that guy when you're looking at some code and you're like who did this? Apparently Alan thought that when he're looking at some code and you're like, who did this?
Starting point is 01:01:26 Apparently, Alan thought that when he refactored some of my stuff. What am I saying? Next time, I'm not sending him the pull request. Yeah, I know. That was the most amazing part. So this next point, the smaller and more focused a function, the easier it is to name. That kind of just goes with the saying, right?
Starting point is 01:01:43 That kind of makes sense. Don't be afraid to make a long name name that's what we said a little while ago um oh this one this one i am absolutely i have been the person who did this in the past and after reading this i felt so ashamed a long name is better than a long comment. Very true. I mean, I've read some of your comments. Hey, look, man, our buddy will, our buddy will argue this with me a while back. And I think he might've even referenced clean code. I was like, get out of here, man. And then after, you know, when I, when I read this, I was like, you know what, man, he's so right. Like if you have to write a super long comment to describe what the method's
Starting point is 01:02:26 doing, there's something wrong. Right. Right. And sometimes I found myself writing these comments about methods that existed. Right. And probably I should have done the boy scout rule and gone back and cleaned
Starting point is 01:02:37 it up to make it more. Just rename the method. Descriptive or something like that. Right. Um, so, uh, plus one to will on this one i definitely took a
Starting point is 01:02:46 negative one and it kind of hurt a little bit when i read that yeah i feel like with today's tools man to refactor you know to change the name of a method or a variable it's so ridiculously simple the only reason why i could even think that you might want to hesitate on it is if you're fixing you know bug a and then to make this other change b would it's so such you know like a class for example or a method that is so widely used that in order to make that change and commit it you're gonna you know completely hide the bug fix that you're trying to make that that's the only reason why i think that well maybe do that in a separate commit yeah and that can happen i've definitely seen it where a whole page is cleaned up and you're like man i don't even know what i'm looking
Starting point is 01:03:34 at here you know we've actually talked about this too i think going back to um it might have been what's the source control etiquette episode I think, maybe. Was it that long ago? Yeah, it was a while back. But I remember we talked about it at one point, like this pattern that I've followed before that maybe I haven't been as diligent about here in recent months. But I've
Starting point is 01:03:58 definitely done this before where, like, let's say I have some ticket, and I like to create my branches off of whatever the ticket number is, just because it makes it easy for me to see what it is later. And a lot of tools, if you include that as part of your, uh, commit message, you know, it can link it up as well. Um, so if I have a bug one, two, three that I'm working in, in branch one, two, three. And I see an opportunity to do a refactoring, but it is gigantic. Then I'll put the pull request in for branch one, two, three,
Starting point is 01:04:33 and then I'll create a new branch called something like a one, two, three cleanup. Nice. And then, and then it builds off of the bug fix of 1, 2, 3, right? Yep. And then it does all the cleanup, and it's a pull request back into 1, 2, 3. I like that. So it's like, okay, here you can see this pull request by itself in isolation. But if you also like this other fix, then you can approve it too.
Starting point is 01:05:03 Yeah, I like that. It's a nice way to separate it, yeah. So it came up, I think, in the last episode, and I forgot. I remembered after that episode about that workflow, so I thought I'd mention that again. Cool. All right, so the next one, we are definitely not getting through the next chapter.
Starting point is 01:05:24 What? We're like a third of the way through this one, so are definitely not getting through the next chapter. What? We're like a third of the way through this one, so we're going to have to. No, totally. That's crazy. All right, let's talk about function arguments. Well, I mean, we've already done enough arguing, so can't we just get along? It's all done. Functions have arguments.
Starting point is 01:05:41 That's what you need to know. Now you see how our pull requests go. Do you remember, like, this is where i started like the the difference between good code and and bad code was that drawing where it was measured by the number of what uh wtfs per minute right that's the that's the difference that's so accurate well this was interesting because it was very specific about how many functions you should or how many arguments you should pass in totally yeah it's hard to use in words i was like well i guess it's a word yeah and so i thought that was really interesting so how many arguments you should pass in. Totally. Yeah, it started using words. I was like, well, I guess it's a word.
Starting point is 01:06:07 Yeah, and so I thought that was really interesting. So basically they say never use more than two arguments, which seems small to me, but maybe I'm terrible. Nah, man. You know what? I totally agree with this one. I remember back in the days, and I'll go back to JavaScript, you would see things where people would just keep amending a function right and all of a sudden there's 12 arguments in it
Starting point is 01:06:29 and i was like i can't deal with this and then i don't remember if it was jquery or what came out where you started seeing people pass around configuration objects and i was like totally that's how it should be done and it's the same thing in oo right you have classes that you pass in or whatever. I can't stand passing in more and more arguments. Yeah, but I do hate it, though, where I feel like it's easy to get into a DTO clutter. Oh, it happens. You have a bunch of these little DTO objects or POJ pojos or pocos whatever you choose to call them
Starting point is 01:07:05 that just clutter up your code just because you needed to be able to pass something around yeah I hate creating one class just to pass something to or from a function I mean that this is where like maybe if I take the opposite stand here
Starting point is 01:07:22 and get into bizarro world and tonight I'm going to like on JavaScript and say, like, this is the beauty of it is you could just have these free-flowing types. Objects, yeah. That you don't have to have these definitions hanging around. Yeah, but how many times have you had to look at a function just to see what the options are for passing in? And you go down to, like, line 17 in the function and realize,
Starting point is 01:07:44 oh, okay, I could have passed this argument too. Yeah, okay. So now we're back to normal Michael and I'm back to hating on JavaScript. Forget it. But hold on. When you said, Joe, when you said you jump down
Starting point is 01:07:57 and you look at something and it says, oh, well, I could have passed this too. Are you talking about within the object itself? Yeah, I'm talking about functions that take a config object or something or some of those optional arguments. And so the config object in particular, sometimes it'll accept all sorts of stuff,
Starting point is 01:08:13 and you scroll down, and you have to look and see what all is being used there, if there's not good documentation for it, and there rarely is. Yeah. But I think we're, maybe if I remember right where they were going though is that it might be that uh if you're taking that many functions or parameters arguments in that maybe you're doing too much well they also say testing becomes extremely difficult because the permutations
Starting point is 01:08:37 of those arguments you know every time you add one that's one more factorial towards the the number of of you know testing scenarios you've got to deal with and that's a more factorial towards the number of, you know, testing scenarios you've got to deal with. And that is an awesome point, right? I mean, it really is. The more arguments you add, the more difficult it is to isolate things to that one particular method. Yeah, but to play devil's advocate, I like to create functions and classes that take in the minimal required
Starting point is 01:09:01 information. So I don't like to take a person object if all I need is a name, something like that, because I want to express to my callers, this is what I need, this is what I'm acting on, and I can operate on more than a person object. I operate on just the things that I need. And so if you don't take this stuff in via functions, then you have to define them as properties
Starting point is 01:09:23 or some other way of getting that information. And so when you do it as a property, then you're kind of hiding it and it's harder for people to see what exactly needs to be passed in order to get your function to work. But I still, I don't want to have six arguments, but it just too seems a little too few for me. Well, in your example though, too, though, a side effect of doing the way you described it is you're also increasing the potential for reusability because you're not tying it to a specific type. I think you said name, right, in your example? Then you're opening up the possibilities
Starting point is 01:09:59 for other callers to use their own types but still be able to call it. Yeah, and sometimes i'll even do a interface you know call it like i name haver and i'll go slap it on the person object or anyone else that has a name or you know whatever properties i need and so then it's a clear signal like these are the guys that i need and i won't use the interface that has more properties that i'm not using because then i'm you know i don't want my callers to think okay well i'm not actually passing anything except for name.
Starting point is 01:10:25 What should I set all these other properties to? It's just confusing. But I name haver? We got to work on your naming there, buddy. You wouldn't want to do I name haveable or I nameable or I namey? That reminds me, though. Somebody in Slack recently,
Starting point is 01:10:40 I think in our Dev Talk channel, said something like you should never name a method with ER on the end, right? Like manager or or oh no that was or was that in here that was part of this we were talking about this last time about but they were talking about um like properties i think it was like you shouldn't have controller manager helper yeah those were the names to stay away from and i brought it up last time that i thought that that wasn't fair because as it relates to mvc everybody knows what a controller is so if your variable name had the word controller in it then it's immediately obvious to everybody what it is and actually
Starting point is 01:11:16 we got a comment about that in the uh in the episode uh 47 comments here, and I'm trying to remember, find who it was so I can give proper credit, but I may not do it. I might not be able to find it in time, but you know, someone wrote in saying something along the lines of, well,
Starting point is 01:11:38 you know, I think that that's, that's probably not what they meant here. It is. It was Brian. And he said that the proposal that he thinks that the proposal against using controller as a class name will be in the context of controller versus manager and not in controller in the context of MVC. And in the case of MVC, controller seems like the standard programming nomenclature like factory or visitor or compare. Yeah.
Starting point is 01:12:03 Right. So, you know, and i agree with that i i'm i at least i hope that's where the author's uh you know head is that yeah i agree the now going back to your name though joe you need to make it so it's like something like i has name yeah and then you can put some sort of beam on it you a cat, right? You know what? Alan, you just started something, and I'm going to have to go back and name all of my interfaces I has. I has name.
Starting point is 01:12:32 And it's going to be H-A-Z, because it's got to be like a cat meme or something. Some little ASCII art above each declaration. And so, going back to what you said a second ago, though, Joe, is like you don't like hiding things in properties.
Starting point is 01:12:48 Like this author was kind of more for that, right? Like they were talking about no latic methods that take no arguments, basically meaning that the object already has state and you're just acting upon that state, right? Yeah. I think it's more pure OO. And these days I kind of lean a little bit more functional so i do more staticky type stuff i take more arguments and um yeah i try to modify state as
Starting point is 01:13:10 as little as possible so i think it's just kind of a my personal evolution and hopefully it's not a devolution well the argument that they were kind of going with though and just to to build upon what alan was saying is that these arguments that – what they were arguing for here in this section was that instead of passing the arguments in, that those should already be properties of your class that you're acting on. And the more – there's more cohesion if your classes – if your methods are acting on more of those variables right um but i'm with you though like uh joe where if i can make something act more functional then those are a heck of a lot easier to test so right unit test for i like that but i still like the idea of passing it in in one object as opposed to six arguments or seven or eight or nine or ten or whatever so you can pass in the state of something even though if we're talking about functional the only
Starting point is 01:14:11 real difference is it can't modify it right like you can't mutate what you passed in but it can return you a new version of whatever it's looking for so i still like the idea of smaller or fewer arguments well yeah so like the concept too, that if you need that many arguments, maybe you're doing too much. Possibly. Like really, what's an example of where you might need something? I mean, like in the last episode,
Starting point is 01:14:32 we had talked about my inability to tell you the ingredients of a particular pizza. A supreme pizza. Which you found difficult to believe. I mean, that was an example where, you know, okay, you could have this pizza constructor, and, you know, if you're not careful about how you think about the structure of your code,
Starting point is 01:14:55 sure, you could have one that takes no variables, one that takes one variable, all the way up to one that takes 15 variables of different things that you want to try to make. Instead of what the book recommends doing would be to use the factory method pattern where you have a create supreme pizza method that doesn't need you to pass in the ingredients. It already knows and it just returns back to object type. That's about the only example that I could think of where I might want a really long list of variables that isn't like a params type, a list of things. So in the case of what you might pass into a string format method
Starting point is 01:15:49 or a string buffer or something like that, where it could be some infinite list of things. That's not being counted here in this particular section of the book. That is one argument. Well, they're counting it as one. Yes, they're not counting it as the infinite list. They're counting it only as the one yep so then the other one that they mentioned that they brought up in the book was called monadic which is it takes in a single argument and that's usually
Starting point is 01:16:13 a decision argument like you know do this or don't do this you know like if you had something like make visible you'd pass in true or false right so it was kind of like a decision thing so well they wouldn't word it that way though right because there was a section in the book where um they referred to that i think that was the flag section where uh they were saying like this felt wrong because then depending on what was passed in the method does one of two things so if you have a like a boolean was a particular example um you know if you're passing in true then the method is going to act one way versus if you have, like a Boolean was a particular example, if you're passing in true, then the method is going to act one way versus if you pass in false, it's going to do something completely different.
Starting point is 01:16:50 So that's why I'm saying, don't call it the decision. Yeah, it's actually wrong. So when you take in a single argument, you're asking about that argument, transforming and returning. So you're actually acting on it. It's not a decision point.
Starting point is 01:17:02 So I take that back. You are correct. The flag stuff is further on, and they don't like that. The monadic was when you were actually trying to either modify or change something about it. Oh, that reminds me. There was actually like a – oh, here it is, the command query section. That pattern?
Starting point is 01:17:23 Yeah, command query separation. So let's finish up on these function arguments. The other ones were the monadic. They typically use events. We'll come back to command query separation. Yes, we'll be going down to it. And then the other one was they were basically saying don't use output
Starting point is 01:17:40 variables, which I can agree with, but it is funny. If you look at a lot of the .NET stuff, you've got triparse, pretty much anything that has a triparse has an out variable on it. Right. And that's, those are kind of nasty to, to test out properly. And it's not obvious, right? Like you got to put out in your call. And so it's just, it's not a clean read. It's a way of cheating the system to have out in your call. And so it's just not a clean read. It's a way of cheating the system to have two returns. Yes.
Starting point is 01:18:09 So the counter to that would be to have some object that you return that has the multiple things, the multiple values, instead of having them each independently yep uh yeah i don't know if i feel as strongly about that but i definitely i guess i do though because i really don't like having to use the out keyword and every time i do i feel a little dirty especially like you mentioned like the tripod parse examples which you know specific to dot nets syntax here you know um so for those not familiar if i want to uh parse some string as a as an integer there's call and the try parse method itself returns back a boolean as to whether or not it was successful or not so you could say if
Starting point is 01:19:16 int dot try parse um string you know or my string comma out my int, right, and then carry on about your day, then you know that the triparse either failed or not versus if you didn't do that and you only had the triparse return back a number to represent that integer, then how do you know if it didn't right like how do you know how do you know when like because this is an example where zero could be a valid uh you know
Starting point is 01:19:53 value for that integer so you can't use zero as your uh false right right yeah and like he said instead of doing the out and the method call, you could have just had that method return an object that had successful true or false. Try parse result. Right. Something like that. So,
Starting point is 01:20:12 you know, there's, there's a way around those things. Yeah. But I mean, imagine like what our code would look like if we did have that, that like, let's,
Starting point is 01:20:19 let's talk about the try parse example. Like if you had a try parse, so you want to say, if int dot try parse example like if you had a try parse so you want to say if int dot try parse now you have to have some you know some value so in if if int dot try parse and then open close parentheses and we'll ignore what's in there dot uh successful yeah dot successful right now it's a little weird but that's a little weird too still reads a little bit better though right because otherwise yeah because otherwise you're
Starting point is 01:20:49 having to set a variable to it right and then you're saying hey but you'd have to set that variable because you've already lost the value now oh that's a good point so so you couldn't because you'd be re-evaluating right so you'd have to say like var result equals int.tryparse if result.successful, then my int equal result.value or whatever, right? Yeah, I mean at least it's consistent. And we've also said on here before, consistency a lot of times is just as good if not, than some sort of clean code. Hey, before we get into the next section here with flag arguments, you want to do – how about we get into a little call to action here? Yeah, so I ain't too proud to beg. You guys have been killer.
Starting point is 01:21:40 I mean, we got a lot of great reviews this last go around, and we read them all. I mean, for those that go and just click the ratings, awesome. We appreciate it. You know, that helps too. But for those of you that actually take the time to sit down and write something to let us know what we're doing right, what we're doing wrong, you know, all that, and just the thank yous and, you know, we've helped or whatever. That is a huge payment to us. I know that that sounds kind of ridiculous, but I mean, in all honesty, that is probably one of the biggest things you guys can do for us besides come and join us in Slack for fun. But, um, yeah, I mean, seriously, if you
Starting point is 01:22:15 guys have the chance, if you remember when you get out of your car, you get off your lawnmower, please do take, take, you know, five minutes, go up there, head to www.cuttingblocks.net slash review, click on either iTunes or Stitcher and, you know, take the time to pin something into us because it really does make our day and it truly helps us out in more ways than you can imagine. So thank you. And please do if you get a chance. All right.
Starting point is 01:22:42 So with that, I want to get into my favorite section of the show this the survey says yeah we're gonna we're gonna family feud this guy all right so uh joe you weren't uh there but you get to participate anyways so the question asked in the last episode is, do you regularly attend meetups or conferences? You had three choices. Yes, I need to get out of my cave every now and then, which really, you know, I think it was supposed to be command center. It's supposed to be, you know, I got to get out of my command center because it's not just a cave. It's a command center. See all my monitors?
Starting point is 01:23:22 It's a command center see all my monitors it's a command center and then there's the other option which is uh no ain't nobody got time for that right or uh the third option is oh i think this is the one where i sang last time and you changed it right this is this is i left it in there did you know i left it in the show but i didn't i didn't know in this show yes okay yeah so the third option is no i live light years away from any meetups or conferences because i live in the jungle baby hey man you you sang about broken death. I did. All right. I didn't even sing. We all sang tonight. How about that?
Starting point is 01:24:19 So now that we have serenaded you with song, those are your three choices now, Alan. Well, no, I tell you what, Joe, since you're back with us, I'll let you go first. You get first pick. Yes, i need to leave my command center no no one's got time for that or three no i live too far away there's no uh irscp and then don't go option i feel like that applies to both of the news. Can I give you like a 1.2 or a dot B? I think number one with 60% of people listening to this podcast do go to get out of their caves. All right. You were crazy optimistic. So, yes.
Starting point is 01:24:58 Wow. Listen to Mr. Pessimistic here. The glass is only half full with this guy. I feel like people at the end of the day are tired of Cody, and they're like, ain't nobody got time for that. So I'm going to say that was the majority at 40%. I feel like he cheated. Did I get it right?
Starting point is 01:25:16 I have not looked at anything. You liar. I have not looked. How close was I? All right. So here's, okay. So by Price is Right rules, I'm going to go ahead and say that he cheated, Josie. You won. All right. So here's, okay. So by Price is Right rules, I'm going to go ahead and say that he cheated, Josie. You won.
Starting point is 01:25:28 All right. But unfortunately, by Price is Right rules, you lost, too. I went over. No, because I say you cheated. Oh, here. So the winner was, no, ain't nobody got time for that. And it had 40% of the vote. Are you serious?
Starting point is 01:25:48 Now you see why I know that he cheated. I got skills. Nobody pulls that off. That doesn't happen. That's amazing. All right. So, I mean, we'll let the cheater keep playing. But so the survey for this episode is define your preferred work environment.
Starting point is 01:26:09 Do you prefer to work in a cubicle or an open floor plan where there's no dividers between you and your coworkers and you can hear all of their conversations and they can hear all of yours? You might say that I've already shown a little slight preference to the cubicle over the open floor plan but you'd be wrong because also you have work from home yay get to work in your pajamas or there's the private office uh where i guess that would be in an office building so let's define let's make that clear that's in an office building but you know you have your own private office you can close the door if you need some quiet because everyone out there in that open floor plan is just way too loud. Or you don't even like that. You want to work remote but from a place of your choosing like a coffee shop. So that's going to be our survey for the next episode.
Starting point is 01:27:03 And that came from slack that that was a conversation we had on slack today which you can join in on the fun by going to www.coding blocks.net slash slack and you can put in your email there and join the party yep and hear all the crazy things that we say starting with uh oh we've already passed we've already talked about the flags. So let's get into verbs and keywords. Did we hit all that? Where did we go? Yeah.
Starting point is 01:27:33 Yeah, we talked about that. Yeah, pretty much. So. Well, we're up on my favorite one. Can I introduce this one? Please do. Oh. Your function should not have side effects.
Starting point is 01:27:45 If it says it does one thing, it should only do that one thing. And I even take that to mean, and especially mean, actually, you should not modify the arguments that are passed in. So if you have a git, it should not also do some setting. I don't, you know, smart properties are nice for some things, but I try to minimize them for the same reason. But to me, the biggies are just not modifying unexpected things, especially the arguments that are passed in. It's very clear via the function name that it is destructive. I hate the JavaScript slice and splice. Splice sounds so similar, and one ruins your array and the other doesn't.
Starting point is 01:28:25 That's a great point. Yeah, I mean, this goes back to the point. And substring and substr are the same way. One of them ruins and the other doesn't, and I never remember which one. This goes back to the point that you made earlier, though, about don't set something if you're just trying to get something. Right, right. And we've probably all done it at some point, right? You're like, oh, man, this thing wasn't initialized.
Starting point is 01:28:49 No, come on. You've seen my code. Man, I did it yesterday. No, I probably didn't. I wasn't coding yesterday, so I could say that. I totally did not do that yesterday. It was last week sometime. Oh, no.
Starting point is 01:29:04 I'm going to check your pull request now. Ruby, and actually we should have mentioned Golang. I think there's a few other languages that are really good about passing back more than one argument. That kind of avoids more than one return. That avoids the problem with the out. But just like that, Ruby has a great convention for functions that are destructive. And the convention is to put a bang, an exclamation point at the end. So if you do like string dot, I don't know, slice, bang, that means that your original argument will be modified.
Starting point is 01:29:35 No bang, then it returns a copy of it that has been modified. Man, I forgot about that. Hey, if you, this reminds me of a previous tip. Go to codeschool.com. No, wait. What was the name? Codecademy. Codecademy.
Starting point is 01:29:50 You can take a whole class on it, and it teaches you things like that. At any rate, go ahead. That's amazing. I forgot about that. Teaches you things like Ruby? Well, you can take the Ruby class, and it'll teach you like that. Bang does the destructive versus the not. You learn a lot of cool things about that.
Starting point is 01:30:03 And that is a great... But you were saying that was by convention, not by... Convention, yes. By compiler or whatever. Yep. Yeah. So no guarantee.
Starting point is 01:30:15 But yeah, if I pass you an object, don't muck around with my object. Although I do that sort of thing in private methods all the time. Because a lot of times I write like little helper methods because I'm lazy and don't want to copy paste stuff and so i'll do gross things like picking a list and then add items to it based on a condition or something but with privates i feel like you can get away with that sort of thing a little bit but i just have to be really careful
Starting point is 01:30:36 and a lot of times i'll put comments and say like warning this appends to the list this will clear the list out before it it refills it or something like that i didn't understand what you meant about the smart properties though or i didn't know where you're going like that. I didn't understand what you meant about the smart properties, though, or I didn't know where you were going with that. It's a lot of times you'll have a getter or a setter that just does other stuff. Like you'll say, you know, class name dot name, you know, you'll be getting it and it will go out, fetch the record from the database and then return the name. And it's not apparent to you that you are querying. so you may be doing this object.name in several places and it turns out in the
Starting point is 01:31:08 background you've run eight queries whereas if you knew that it was doing that you would have you know cached it off to a variable and only used it once if it was called get name from database right yeah and so smart properties in particular are easy to hide stuff like that i've seen stuff like that where you know every time you call the git, it wipes out the old collection, repopulates it, whatever. It just does some work. And I probably wrote that code, which is nasty because I know I've done stuff like that before.
Starting point is 01:31:37 But I just don't like stuff that does that. And so I try to avoid smart properties even though I understand the whole benefit of doing properties versus just variables is that you can make them smart later without changing any code, but don't make it smart. Yeah. I mean, I'm trying to think, I know I've done examples where like, I'll have some property and you'll do a get on it. and then the get will check to see like whatever the backing uh field is for that you know hey is this thing has this thing been initialized if not let's set a lock and then initialize it and release the lock and then i'll return it back. But I mean, I guess technically you could say like, well, that might be doing more than
Starting point is 01:32:29 it should be. Is that where you're going with it? Well, I actually just came up with a joke right now on the fly that I think exemplifies this pretty well. Oh, this should go over well. Yeah. When is a property not equal to a property? DateTime.now.
Starting point is 01:32:50 Okay. Oh, interesting. If you did, if DateTime.now equals DateTime.now. It won't equal. Or, well, actually, it probably would. They're both properties. But they probably would. I don't know.
Starting point is 01:33:00 That's a good question. Because it could be one tick off, right? Yeah, don't ever write that code. Because.now is actually acting like a method right it's not right it's acting like a method even though it's a property so i get what you're saying it's a method in disguise yeah i get what you're saying that actually bugs bad about it that actually bugs me too by the way anytime i'm using the date time dot now that frustrates me because i think it needs parentheses i put it on there and then i get an error and i'm like okay okay i'll take them off um the next thing that i actually like and this bugs me to no end so as passionate as you were about it only doing one thing i do not like it when i have to go look at a method signature
Starting point is 01:33:41 to figure out what that thing needs or is doing, right? Like it says right here, avoid making methods that are required to inspect the declaration. Your method shouldn't be named something or it should be named something that identifies its true intention. I totally agree with that, man. I can't stand it when I've got to go read a method to figure out what in the world is actually happening in that thing, right? It drives me absolutely crazy. And that goes back to the whole three-minute or
Starting point is 01:34:08 one-minute thing that we said earlier, right? Oh, right. You should be able to know just by reading it exactly what you're getting. That still might be my favorite takeaway from this book, though, is the three-minute method. I feel like... Seven-minute abs. Yeah, I feel like that's where we're going. No, man, it's a two-minute method. I feel like... Seven-minute abs. Yeah, I feel like that's where we're going. No, man, it's a two-minute method because it's better.
Starting point is 01:34:31 One-minute method. That's just stupid. Nobody would do that. For anybody who gets that reference, that's golden. Brett Favre. He would get it. All right, so let's go back Brett Favre. He would get it.
Starting point is 01:34:45 All right. So let's go back to the command query separation concept here. So functions should either do something or answer something, but not do both. Woo-hoo. So that's really the idea here. Yeah. That's just what Joe said. If you have something that says get, it shouldn't be doing anything.
Starting point is 01:35:08 It should be returning a variable, right? If you have something that says set, it really shouldn't be doing, well, what if you go to set something and it requires other information on an object for it? Yeah, you still, eh. This is where it's doing more than one thing you're not mutating state though that's really if you have to if you if you can't separate those two then your method is doing too much yeah i think you might be right okay i didn't write the book yeah true prefer exceptions as opposed to error codes i 100 000 agree with this i to error codes. I 100,000% agree with this. I hate error codes.
Starting point is 01:35:46 You too? Dude, SQL Server, man, store procedures are the worst, right? If you return a zero, then that means everything's good. If you return 10, oh, well, you've got to go look at the proc to figure out what the author meant by 10, and then 20 and 30 and 100. Man, I cannot stand error codes at all i hate them yeah and yeah somewhere you have to define them and it just gets nasty and then you know
Starting point is 01:36:14 what inevitably happens is like you don't want to create another error code set so you end up like using one from somewhere else and somebody adds to it and now yours can potentially return something that it would never return and and it just gets ugly. So I won't say, I'm not as passionate about it as you definitely have a lot of hate in your heart. I do. I don't like Ericos.
Starting point is 01:36:34 You know, but, I mean, I see it as dated, is the way I view it. Like, it was definitely, there was a time where this was a necessary thing, right? So if you were chaining together a bunch of commands,
Starting point is 01:36:47 like command line, not parameters, but command line commands, I guess if we could have another command in there. Arguments? No, that's why I said not. No, you're on a command line, and you're going to chain one command into the next right then you're having a non-zero error code you know or value come back right i mean there was a time for that that's you know where it made sense right h result but what'd you say h results
Starting point is 01:37:21 h results so you know you're dealing with C++ code. Yeah, totally. Going back to like Win32 programming. Okay. But I'm not even talking about H results, though, by the way. You're talking about a holdover. But why does SQL Server still use return codes for a proc, right? Like, come on, man. Seriously, come on.
Starting point is 01:37:41 Give me something real. I feel like this conversation isn't fair, though. SQL needs some syntax updates. Because SQL in general, I mean, not just SQL Server, but just SQL in general is just really outdated. It is. You know it is. It's amazing what all we still do with it.
Starting point is 01:38:00 It's amazing we still can. Yeah. Yeah. Okay. But then, you know, you're amazed with that. And then look at all the wonderful things you can do with Pearl. I'd rather not. Oh, sorry.
Starting point is 01:38:14 Hurts my eyes. So what about this statement, which was to extract your try catch blocks? Love it. I'll tell you why. I love throwing exceptions. I'll tell you why. I love throwing exceptions. I love very specific exceptions. I'll have validate methods and they'll take a look at some things
Starting point is 01:38:32 and they'll throw some very specific argument that gets logged to a disk somewhere or something. It gets returned to the UI. It's fantastic. I hate catching. I want as few catches as I can get away with. I want that to be the top most level thing. That's who decides what to do when something goes wrong.
Starting point is 01:38:49 I don't want a bunch of people catching and trying to make decisions along the way. You know, especially if you are a third party, you're dealing with third parties, don't cover it up, toss it up and I will deal with it at the appropriate level of abstraction for my specific purpose.
Starting point is 01:39:03 I agree with that. I like that a lot and and i do like what they said very next was your try catch your try should be the very beginning of the method and your catch or finally whatever should be the very end well yeah it was specifically what i liked was that error handling is one thing. Yes. Right? So if your method does one thing and you have to do error handling, then that's it. That's the one thing that it gets to do. Something else has to be called to do whatever other work that you want it done.
Starting point is 01:39:38 Yep. So you have your try and then you have do something, right? And then that's going to catch whatever happens, and that gets thrown back out. So that's where you catch one of Joe's 15 exceptions. Yeah. Well, they're all just regular exceptions, though. Oh, that's helpful. You know, Java, man, I like the idea that I can call a method
Starting point is 01:40:01 and see very explicitly, like, these are the types of exceptions that I'll throw. Except that everybody gets tired of writing all that and they all just say it throws exception. Yeah, they throw a new exception, right? Just your generic run-of-the-mill exception. Oh, that's actually later called out as a problem in the book. They do address that later in the book as a refactoring problem. Yeah, because it starts out, you're like, oh, well, I throw an IO exception or I throw argument exception.
Starting point is 01:40:26 And next thing you know, you're like, oh, but now I call this line thing and it returns this. And so I need to go add to my function or nope, I just throw exception. Well, it was something that the Java community is a whole kind of addressed or admitted as like a fault of the language. That sounds harsh to call it a fault of the language because I don't mean it to sound that harshly. Something that could use improvement.
Starting point is 01:40:49 It is. It sucks. But because what it was doing is it was kind of carrying forward a dependency here. Like I throw an IO exception. Now you call me. Well, guess what? If you're not catching that, you're going to have to include that as part of your declaration. And whoever calls your method, guess what? If they're not going to catch it, going to have to include that as part of your declaration. And whoever calls your method, guess
Starting point is 01:41:06 what? If they're not going to catch it, they've got to include it as part of their declaration. So in the very end, like I said, IO exception, so that was very generic, but what if I had a very specific exception like coding blocks IO exception because Alan
Starting point is 01:41:21 didn't like Michael's code and Michael rejected that PR right that's a very specific that's a very specific exception that got thrown and now but that that piece of code and its declaration you know it gets uh you know passed all the way up so now callers way at the chain might have to know about it and now let's say I go and refactor that thing because I'm like wow that was a really long name I don't even remember what it was just call it coding box exception because michael's crazy everything then then there's a whole bunch of code that you got to go back and change yeah because well except that everyone got lazy somewhere along the line just
Starting point is 01:41:55 started saying exception yeah throw a new exception so it's totally worthless which is to our benefit thank you which is basically so much easier because i don't even remember what the name of that exception was that i made put the string in there and be done with it right that's what most people do so um the next section i actually love this don't duplicate code i i've actually had people kind of laugh at me like if uh if i have something that's doing something and then there's another thing that's like a like like another instance of that object, and they're checking the same thing. I won't do that. I cannot stand it. I will combine those two things in an array and then do a loop over them to do that same method, right? So let's say that you have a bunch of logic that's happening on object one, and then you've got that same object
Starting point is 01:42:38 acting on object two, because they're instances of the same class. I'll put those in an array, do a loop over them and have it, you know, just iterate over the items and of the same class. I'll put those in an array, do a loop over them, and have it just iterate over the items and do the same logic on both of them. Even though I know it's really not that much code, I don't like the idea that... Or you can just extract that logic out as a method. You could do that.
Starting point is 01:42:57 If it was something that you could append to the class, that might work out better. So this is better known as the DRY principle. Yes. Which we talked about... No, have we talked about this? Yeah, we the dry principle yes which we talked about uh no have we talked about this yeah we have certainly we've talked about this solid it was one of the things in solid well the d in solid though i thought was the dependency yourself right uh dependency uh injection principle was it not inversion we've talked about the inversion principle we've talked about i don't
Starting point is 01:43:25 know when though anyways go ahead but yeah so better known as dry which is do not repeat yourself yep and and they say duplication leads to multiple places to change and more places where bugs can occur we've all had this problem where we know that this code exists in five different places right and if you don't know the next person that comes behind you, doesn't know that when they update this one that they need to update the other four, then you've, you've got a problem.
Starting point is 01:43:53 Right. And that's, that happens. And that happens so much. So if you can break all those out into a common piece of functionality that everything can use, right? Right.
Starting point is 01:44:05 Yeah, this is better known as DRY. Do not repeat yourself. Again. Just do it. I was waiting on one of you to catch it because I said it like a few times. DRY-A. What else do we have? Don't necessarily stick to the single entry single
Starting point is 01:44:27 exit rule uh this is a structured programming they referred to donald newth who used to kind of say that i would basically like you know do ifs or do whatever and the idea was always to have like return you know be the last thing and only one return yeah and i don't do that i like to buck out early so when that you're when you're reading the method as soon as you stop caring about what happens next like return out of there yeah i mean hmm so i try to only i try to have the one return as often as i can and but i'm also trying to keep those methods small so i can do that but there are times where I will return early, but the way I'll try to do that is where I feel like I still kind of structure that okay. It's like maybe if I'm returning back some kind of result of, let's say it was a Boolean result, and I might even name that variable as result. And so I'll initialize it as, you know, var result equals false. And then if there's some condition that I need to
Starting point is 01:45:31 check out early, then it's just, you know, return result right there and there, right? Whereas at the very bottom, then I'll have another return result. But I really prefer to not do that though. Because I really do like the idea of if you have the one, then I think it reads cleaner because then from a testing perspective, there's one control path that's going to get you to that end state, right? But it's going to branch. There's going to be a level of nesting there. Depends on how big your method is. Well, there's going to have to be at least one. If you have that return early, then there's some sort of branch happening.
Starting point is 01:46:06 So you've got to have at least one level of nesting in addition to your function. Yeah. In the case that it needs that, yes. Right, sure. If it doesn't need it, then there's only going to be one return anyway. Yeah.
Starting point is 01:46:18 I would say, generally speaking, I try and stick to one, but I will return early. If some condition's not met and you know that absolutely you can't carry on, then I will return early. If, if, if, you know, some conditions not met and you know that absolutely you can't carry on, then I'll definitely return out. Just like what you were saying. Right. I mean, there's also times too, where, um, so as a, as a stylistic principle, right, there are times where you could take the approach of, I could go ahead and bail out early with a return statement. And now I have two possible return statements, or I could go ahead and bail out early with a return statement and now I have two possible return statements
Starting point is 01:46:45 or I could only have the one return statement and maybe based off of that conditional result if you were to flip that state so instead of returning early because the condition didn't meet your satisfaction if instead you flipped it to where if it does meet your satisfaction, then you do your work,
Starting point is 01:47:07 then you could have the one return statement. And again, if we're talking about small blocks of code here, like if that if statement is only like five lines of code, then you're not going to mind an if statement that's
Starting point is 01:47:23 on a level of indention that's only for five lines of code. I think that's a fair point. That's not going to be so bad. Yeah. So there have been times where I've done that. And here's the thing, too. And the reason why that particular type of example
Starting point is 01:47:39 comes to mind is we've talked about ReSharper in the past. And there have been times where ReSharper, its default rules are pretty good about, hey, you could flip this state and reduce your indention levels, right? But there will be times where I'm, yeah, I agree with you. I could certainly do that.
Starting point is 01:48:02 But I kind of like the way it reads better right now. And since it's only a few lines, I don't feel like it's too bad. I'll take readability over shortness of code any day. Well, I mean, I'm still talking about short code. But sometimes their whole inversion thing is to save you a line or two lines, right? If I remember right. It's been a while since I've used Reef Sharper. Oh, that's blessed me.
Starting point is 01:48:27 Yeah, I mean, I've still been debating buying it, but, you know. Yeah. All right. So how do you make these functions this beautiful? How does that happen? I have a good story. Maybe it's not that good, but I was chatting with someone about a Code Wars problem,
Starting point is 01:48:46 and I sent him my functions. I mean, I had a really story. Maybe it's not that good, but I was chatting with someone about a code wars problem. And I sent him my functions. I mean, I had a really tough time with this. Like, Oh man, uh, I'm ashamed, uh, because your function looks so nice.
Starting point is 01:48:52 Something, you know, something like that. I was like, man, you should have seen it in 10 minutes ago or not even 10 minutes, like two hours ago. Like that's how long I've been done.
Starting point is 01:48:59 And I've been whittling this thing down because it was a beast of a problem. And I knew that there was also the duplication and nasty stuff. And so it was just a matter of choosing to spend that time with it because anyone could have looked at it and known that there was duplication and inefficiencies. So it's just a matter of how much time you want to waste on it. All functions start as trees until you whittle them down to toothpicks. That is so true.
Starting point is 01:49:22 That is so true. Yep. I mean, when we were back talking about fizz buzz, I think in, in our algorithms and the interview, um, episode, we had mentioned one of the fizz buzz, uh, blog posts where somebody took regular fizz buzz and just, Oh, owed it to the nth degree. And I mean, the thing is the, the key takeaway is you never start out in the perfect end state, right? You start out in the state where you get something done, and then you start extracting those out and extracting them out until you get to a point to where you are into a
Starting point is 01:49:56 more, whether it's OO or more readable or functional type state. It's just like you said, you whittle it. You cannot start thinking about the absolute perfect way to go because you'll just think yourself in circles. Agreed. Yeah. All right. Well. So we're ready to do chapter what, four?
Starting point is 01:50:22 I think chapter four is a lot shorter lot shorter than uh chapter three as far as uh commentary we're already almost two hours into this though yeah i'm calling it yeah i think we're good so in the resources we like hey guess what we're gonna have a link to clean code because we like it despite some of the things you might have heard us say. Actually, this is probably the book I agree with the most. I'm a big complainer. I'm an Eeyore, not a Tigger. I usually complain about everything but Clean Code. Just about everything we talked about,
Starting point is 01:50:53 I totally agree with. Man, this guy, he lies. This guy doesn't complain about anything. JavaScript. Let's talk about JavaScript or SQL. He does complain about SQL. He jokes about JavaScript hate, but he about JavaScript or SQL. Okay. He does complain about SQL. He jokes about JavaScript hate, but he really does hate SQL.
Starting point is 01:51:10 Yeah. Well, that's not without good reason. Why can't I sort dynamically? So let's get into Alan's favorite section of the show. It's the tip of the show. Yes, sir. It's the tip of the week.
Starting point is 01:51:27 Yeah, come on. For my tip of the week here, I think we may have talked about conditional breakpoints once before, which are awesome. If you're not familiar with it, this is a tip specific to Visual
Starting point is 01:51:43 Studio, and other IDEs may have similar features but uh you know if you were to right click on a piece of code you know set a breakpoint uh just by clicking in the left area um or also i think f9 will set the breakpoint too is that right i think or is it all yes f9 uh. Oh, it's disable it is control F9. Yeah, sorry. So you could go onto a line of code and either click on it on the far left gutter, I guess you could call it, or F9, that line of code, and set a breakpoint.
Starting point is 01:52:19 But you could also set a conditional on it. So you could say like, hey, only stop at this condition if something has happened, right? So you could do that by right-clicking on the breakpoint and going to conditions or do Alt plus F9 and then the letter C to get to the conditions. But here's a really awesome scenario, though, that I'm going to ask you two guys have you ever found yourself where you will write code that might log some message um based off of some scenario you know that that just just so you can like debug a problem better totally right or maybe you've you're debugging something and you're like oh man i already wrote some code up here that would log this message based off of this scenario so that i
Starting point is 01:53:13 could see what was happening there i wish i'd done something similar over here has that ever happened to you yeah okay well you will do that no more friend, because you have actions with your breakpoints as well. So what you can do, go to your breakpoint again. You can set a conditional for it. You don't have to. But you can right-click on it. And unfortunately, there is no keyboard shortcut for this. So you have to right-click on your breakpoint and click on Actions.
Starting point is 01:53:44 And then you can set what you want to have happen. So if you want some code to be logged out to the console, right, so you could do something like a system.trace or system.diagnostics.writeline, whatever you want to do, wherever you want to write it, you could, you know, put that code in there to write, to output some message, right? So maybe you want to see the value of something. Maybe you want to see the thread name that you're, you know, the thread ID that you're in, or maybe you want to see the call stack. So you have some method,
Starting point is 01:54:22 and you're like, hey, who just called this guy? Right? Where did this come from? So there's, there's some, there's a handful of pre, uh, defined variables. So dollar address, dollar caller, dollar call stack, dollar function, dollar PID for process ID, dollar P name, dollar, uh, TID for thread ID, or $tname. So you could set, you know, instead of, let's say, for example, let's think of an Apache log for net kind of scenario or log for j. If you're familiar with those standard kind of logging formats, right? But so you wrote some code, as you said that you have, to log a message
Starting point is 01:55:08 based off of some scenario, but now you're actually in the debugger and you don't want to stop the session because maybe it took you a while to get to the point that you're trying to debug, right? So you could right click on your breakpoint, select an action, go to the little dialog, which is log a message to the output window, and then write your similar log4net type of style in there so that you can see what's happening. That's sweet. And it's awesome. And then not only that, but you could also label your breakpoints so that you can actually, instead of just seeing breakpoint one, breakpoint two, you could see something more meaningful about what that breakpoint is meant to be.
Starting point is 01:55:52 So this is almost like a way for you to be able to inject code at your breakpoint. Exactly. You're not worried about checking it in. Exactly. Or having to stop and restart your debugging. It's debug code that you can inject at will at runtime that doesn't have to be committed and you don't have to compile it
Starting point is 01:56:11 right that's beautiful now if you write something that it doesn't like then you will get a a little message uh about what it couldn't do and then it'll just skip it you know so it will it couldn't do, and then it'll just skip it. So it won't break the app. But yeah, it is a beautiful ability to be able to inject your debug code that you don't want to clutter your real production code with all this debug stuff, but yet there are times where you may need to see some internals of what is happening. Who just called this method,
Starting point is 01:56:42 and is it on the same thread that I'm expecting it to be on? Or did something else happen? Yeah, it's amazing. It's beautiful when you see it in action. Now, here's the one. I will, like, one word of warning, one caution, okay, is that you could write some beautiful code in that dialogue, but God help you if you accidentally uh hit f9
Starting point is 01:57:07 again let's go or if you click on that you mean to right click on that red ball and instead you left click on it because uh visual studio giveth and visual studio taketh away save those office snippets yeah so but but yeah it is totally a beautiful thing. I was working in some multi-threaded. We were talking about caching a few episodes ago, and I was working in some multi-threaded caching code and trying to debug some scenarios, and the ability to do this was just such a lifesaver because I didn't have to muddy
Starting point is 01:57:47 the code up. And here's the beautiful thing, too, because if you ever found yourself in a scenario where you write... Okay, so when I preface this whole thing and I ask you, like, hey, have you ever found a situation where you write code to actually log some message based off of a scenario, right? And then inevitably what happens is over the course of trying to debug this thing, you end up putting too much of it in, right? And so now the real meaning is getting lost in the weeds, in the noise, because you're throwing so much of it out there.
Starting point is 01:58:22 But because these are just breakpoints, you can selectively turn them on and off without losing your code as long as you disable the breakpoint. Don't turn it off. Disable it. Or don't remove it. Don't remove it. Just disable the breakpoint. So you could say, okay, I think this particular breakpoint message that I have here is a little too noisy.
Starting point is 01:58:43 Let me just disable it right now and then move on, right? And especially if you combine those breakpoints with conditional statements, now you can really get powerful because you could say like, hey, only stop at this breakpoint if this condition is met. And then if this condition is met and then if that condition is met, take this action. And Oh, by the way, I forgot to even mention that as part of the action, which you can,
Starting point is 01:59:12 uh, say one of the other options for that is to, is, um, there's a checkbox continue execution. So you don't even have to have the break point. Stop at the, at that spot. Don't buy your output. It'll just't even have to have the breakpoint stop at that spot.
Starting point is 01:59:25 It'll just dump out your output. It'll just write out the message to the output window and keep on going. Nice. Unless you want it to stop. But I believe the continue execution checkbox is checked by default, if I remember correctly. That's sweet. So yeah, it can be a lifesaver. And I'll have a link in the show notes for an example
Starting point is 01:59:48 of that from some MSDN documentation that is geared towards Visual Studio 2015, but at least in 2013 this was there, and I don't remember about
Starting point is 02:00:03 2012. So your mileage may vary on visual studio 2012 and before but 2013 and later you're good to go pretty cool so mine is on outlaw's favorite topic which is git and i had a situation recently which i'll briefly explain basically we had a situation recently, which I'll briefly explain. Basically, we had a bunch of third-party code checked into Git, and we were upgrading the version of that third-party code, and so all those files changed. So let's say, for example, if it was a log for net, is that what you mean? Yeah.
Starting point is 02:00:43 Like it was somebody else's DLL. Well, I guess it's a horrible example. It's not a DLL. It's the actual source code. If you downloaded the source code from Git and you put it in your Git repo because you might be making changes to it or something, who knows, right? But for some reason, it ends up in your repo. What code were we doing? Your local repo.
Starting point is 02:01:01 And so you're upgrading the version of it. So now all these files change because they've made changes to the underlying system, make it more efficient, whatever the case may be. And you made a few changes to some of your files and you go to do a get status and you just see a ton of red pop up because they've either changed or renamed or whatever the case may be. Right. And, and you know you made some changes to the files, and you did a get add, and you added them to the cache. Now you can't figure out for the life of
Starting point is 02:01:31 you, what files are in your cache that you're trying to commit there, you would think that there'd be a way to do this using get status, because get status will usually show you what you've got cash for for staging and what is modified on the disk. There is no way to do that with git status to leave out the non, what do they call those things, untracked files. What you can do though is this little trick where you can use git diff. So you can use git diff dash dash name dash only dash dash cached. And that will return you a list of the files that you have in your in your cache or your staged area, and just the file names. So if you need to figure out which files you actually touched, and you've got stage ready to commit, that will give you a list of those files. It saved my bacon.
Starting point is 02:02:27 So hopefully somebody else will find that useful. I spent so much time trying to figure out how to do it with git status, it didn't work. So git diff dash dash name dash only dash dash cached. Sweet. Very nice. And please don't forget, dear listeners, if you know what is coming after git please email me
Starting point is 02:02:47 because i'm ready to move on you know what you don't like git i'm fine like i won't say i'm finally i i actually enjoy it it makes me feel like coding is less painful there are some situations that that is not true but for the most part i find it way less painful than anything i've ever used in the past i feel like yeah that's the thing about that's the, I find it way less painful than anything I've ever used in the past. I feel like Joe is missing. That's the thing about it. It sucks less than everything else. But you probably got to that point by putting in a good four hours a week of messing with it for years. Possibly.
Starting point is 02:03:17 Possibly. I feel like Joe misses some version. And that's why. No, not at all. Hey, but hold on joe i feel like you need to qualify that because didn't you get good at c sharp by being frustrated by it for four hours a week for the past several years too what about javascript joe what part of programming wasn't that way i google basic stuff about Git daily. Come on.
Starting point is 02:03:45 Daily. I think you're exaggerating. No, like it's just stupid stuff like how do I amend a message or something. Just things I don't do often enough and I'm always messing with Git. So I just feel like Git is really complicated and there's a lot of problems and every place I've ever worked has just spent so many hours just even arguing about the Git workflow. And so I think that there's got to be something else
Starting point is 02:04:08 on the horizon, right? Please. Got. Got is coming soon. Yeah, got. I type that all the time. Well, if Git were to follow the path of Linux since they were both started from the same
Starting point is 02:04:25 mind, then I guess we should expect to see different distributions of Git coming to a compiler near you. It both did, man. There'll be a Red Hat version, a Debian version.
Starting point is 02:04:42 Is it too late for me to catch Hurricane Matthew? Take me away, buddy. Joe's on his way out the door not running away from the storm he's gonna like point break this thing and run to it with a surfboard in his hand oh by the way so that's another thing
Starting point is 02:04:59 Joe we almost he tried to force us to record again without him because last week when we were going to record, he invited Hurricane Matthew into his backyard. Yeah, what's up with that, man? Nobody does that. Yeah, knocked my fences down. Man, unreal.
Starting point is 02:05:14 They're still down. We're glad that that was all that happened. Yep. Legitimate excuses, though. Yes, yes. So on from my tip, actually, I my tip out um as we were going along because i remembered an excellent ms dev show uh episode that i heard recently um with katrina owen and it was all about refactoring and one of my favorite parts about that talk uh and i always
Starting point is 02:05:35 talks about refactoring was um she mentioned some really good reasons for not refactoring some code what i'll just i'll give that teaser i'm not gonna tell you what they are you have to go listen oh my god but i hadn't even thought of this before when they started talking i was like not refactoring some code. I'll give that teaser. I'm not going to tell you what they are. You have to go listen. Oh, my God. But I hadn't even thought of this before. When they started talking about it, I was like, oh, those are really good reasons. But they also talk about some different things like balancing refactoring with working
Starting point is 02:05:55 and not trying to convince your boss that you need to spend the next six months refactoring. So just really good, intelligent conversation as always from those people. So go listen. Yes, do. Interesting. All right.
Starting point is 02:06:07 You've sparked my curiosity here. All right. So, you know, this is, we've made it to chapter three of Clean Code. So we're really going at a fast pace here. I feel like you could have read the book faster. You know? Just saying. Be sure
Starting point is 02:06:31 to leave a comment on www.codingblocks.net slash episode 48 for your chance to win a copy of Clean Code. And as always, be sure to subscribe to us on iTunes to learn more in case if a friend
Starting point is 02:06:48 happened to loan you their device so that you could listen to this or if they pointed you to the site. And be sure to leave us a review. Go to www.codingblocks.net slash review. As Alan mentioned, we greatly appreciate that. it always puts a smile
Starting point is 02:07:06 on our face and really makes us happy when we read some of those reviews so uh you i can't say it enough totally i think joe's asleep i feel like he should do the next thing so visit us yes us at Coding Blocks. And drunk. Visit us at CodingBlocks.net where you'll find all our show notes, our examples, our discussions and more. That's it for me. Send your feedback, questions, and rants to our Slack channel, CodingBlocks.
Starting point is 02:07:40 Slack.com because you'll get much more better responses. You can also email us at comments at CodingBlocks. Slack.com because you'll get much more better responses. More better. But you can also email us at comments at codingblocks.com if you have any questions or anything. Net.net.net. Oh,.net. Wow.
Starting point is 02:07:56 Wow. You're fired. I am tired. You're fired. Be sure to follow us on Twitter at CodingBlocks or head over to CodingBlocks.net and you'll find all our social links at the top of the page. Wow, I feel like that's his way of saying, hey, I need a sticker. Yes, he could read it off the sticker.
Starting point is 02:08:13 Good thing we put that.net on the sticker. Man, I'm actually putting a sticker on my computer against all the willpower I have. You know, I feel like you're going to come to the dark side here because they are a beautiful thing. Look at how pretty my laptop looks with all of these stickers on there. Your laptop makes my OCD. Your laptop looks like you just bought it.
Starting point is 02:08:33 It's amazing, right? No. It's like 2011. I can't stand it. I look at your laptop and I'm like, when are you going to use that thing yet? Like, how long has that thing been sitting in a box? That's boring. How many stickers you got on yours, Joe?
Starting point is 02:08:49 Oh, zero, but I've got a lot of cat hair, dog slobber, and I don't know, taco shell crunchies on it. Yeah, I put this thing to work. Oh, dude, that's amazing. But your guitar, your guitar is held together by stickers it is like i don't even know that it would work without them now yeah it wouldn't it's it's covering some holes every time you uh put a sticker on it you change the tuning of it a little bit hey suddenly it got deeper uh put another one on the left then
Starting point is 02:09:23 that's awesome. Alright guys, that's a wrap.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.