 This is Mike Moore. Has anyone heard of Blomage on the internet? Yeah, Mike. Blomage. I didn't even actually know that. I'm not French enough to say it that way, but I'll try. Blomage is someone who has spoken at Ruby conferences before. I don't know if you've seen him around. Primarily pony content. A lot of ponies, bronies, different ponies, and ponies talking about ops. Mike likes to speak. Mike likes to organize. He organized Mountain West JS last week, right on top of Ember Comp. He's primarily known for organizing conferences on top of Ember Comp. Then he flew here and then he wrote a talk and then he's going to give that talk here at this conference. Then he's going to fly home for Mountain West, where I assume some number of you are also going. Who's going to Mountain West? Yeah! Mountain West train. All right. I mean, we're way better in stuff, but you're okay too. All right, Mike Moore, please. A round of applause. Thank you, John. All right. So I love Ruby on Ails. I think this is my third time being here and I just can't get enough. So thank you guys for staying and I can't wait to have a good time with you. I'm curious about the makeup of the audience. Who here is the first time at Ruby on Ails? Wow, that's at least half, if not more. Who here has been coding less than a year? That's good. Good job. All right, so Tenderlove is kind of known for what would Freddie Mercury do, right? That's kind of what he tells himself when he's not sure what to do. And I don't, that's not me, but today I was just thinking, what would Corey the front man for Slipknot do? Because I know like, I don't look it, but you know, I'm a moderate kind of Slipknot fan and I had this live album and they're gonna play this song that was off their first album but they've never played it live before. And Corey says, it could be a trainwreck, but we're gonna do it anyway and that's kind of how I feel about this. So this could be a trainwreck. I literally wrote it last night in this morning. So we'll see where it goes. The title is Stupid Ruby Tricks. Now there's three things that you could focus in that title. You could focus on the Ruby. You could focus on the fact that we're gonna show some sort of trick, some sort of, you know, piece of approach that's gonna help you or you could focus on what it's really gonna be about, which is stupid. So this is a stupid talk and I hope to lower your expectations and then we'll just be fine. So like John said, my name is Mike Moore. This is kind of the picture I was, I'm usually known for. It's not my Twitter avatar. I probably should have changed it back, but I didn't. But my name is Mike Moore and I go by Blumage. But everyone says Blumage. It's kind of like mirage or fromage. But when you say Blumage, everyone thinks I'm like a medieval sex worker, but that's not me. I'm okay with Blumage. I will answer to it. So I loved all of the talks that I've seen so far. One thing I'd like you to know about me, kind of like Akira or Akira, is that I too have a GitHub profile and it's got full of all sorts of really wonderful things. The thing I'd really like to point out first is I have a URL up there. Now, it's not a long URL. You could probably commit it to memory. Just kind of think about that. It's not too many bits to kind of fit in the old brand there. I've got a lot of stuff on here. The other thing that's on my profile is my name, which is important, which I think is pretty neat. Also, I've got my username on there. So it's like two names. So that's pretty neat. It's not my full legal name. I can only tell that to people that are really meaningful to me, like the bank and the IRS. But you can find that on there. So that's great. I'm from Cedar Hills, Utah. So there's like a Utah contingent here of at least two people, right? Who's from Utah? Yay, we've got three, four, including me. I'm from Cedar Hills. Utah is a wonderful, beautiful place. The mountains are awesome. The people are friendly and nice. And there's a really wonderful Ruby Conference that starts in two days. So if you want to keep this party going, absolutely come on down to Utah and come to Mountain West Ruby Conference. The other thing I'd like to point out in this, and this is here, this is on my GitHub profile, is that my company name is Humane Code LLC. And I think Ernie Miller should expect a cease and desist letter from my lawyers pretty soon. It's very clever, Ernie. Glad you thought of that before no one else did. The other thing is I've actually got some contributions. So here you can see my repos. The thing I'm most known for is many test rails, which is a really fun little project that I run. Now many test ships with rails, right? So this doesn't really do anything at all. It's of no value. And that's my most starred gem. So, yay me. The other thing that's kind of embarrassing on my GitHub profile is it shows you your contribution calendar. And I want you to point to this section right in the middle. Can anybody guess what was going on in my life at this point? Vacation? Alcoholism, yes. I will get to the alcoholism a little later. No, I was at a startup during this time. I like to consider this my trough of disillusionment period. This was after the peak of inflated expectations. And before the slope of enlightenment and plateau of productivity began, unfortunately they didn't. And so, in October, late October I started, I went somewhere else, so I'm contributing again. That's nice. The last thing I want to point out is that something that, you know, like Acura's got to GitHub profile. I've got to GitHub profile and we're both really close to a thousand followers. Like, really, really close. So, anyways, I guess what I'm trying to say is that I'm kind of a big deal. Really, if you think about it. Yeah. Yeah. Who was here for my pony talk like two or three years ago? Yeah? Okay, yeah. This is going to be worse. Just letting you know. Right. Again. It's about stupid. This talk is all about stupid. So, actually, I do feel a little bad. Before the conference, I've got the run up for Mountain West JavaScript and then here and then going back to Ruby. And so, I was messaging Josh and I was like, dude, is there any way we could move me? Because I was supposed to talk yesterday morning, right? And I literally did not start until last night on this talk. I was like, can you tell me if you could move me until later on in the conference so that I actually have something? And Josh, being a super nice guy, he's like, no problem. We'll move you to Thursday and we'll just move Terrence up. And I'm like, awesome. That's so sweet. Thank you so much. Then, of course, when we get here, like Terrence shows up and is like, guys, Friday hug is my thing. And so I was like, oh, we'll bring you up and you can do Friday hug. But then Ernie shows up, right? Totally takes over the Friday hug. Seriously. All right, so those who know me, I'm not a big beer drinker. I'm a lot like Ryan Davis, you know, Ryan I think of as like a mentor and I like to follow him. And so, I also prefer Scotch on the rocks. Yeah? All right, so I think I should apologize. I feel like I'm starting to lose control a little bit. No? No, see, the difference is that tender love is what would Freddie Mercury do and blowmage is what would Corey the front man of Slipknot do, right? Totally different. Very different. And all right, so I know what a lot of you guys are thinking right now. Is this going to go on much longer, right? Because you're like, it's full of puns. And this is for Jonan. Like I got a space picture in. I am on the theme, right? Today's theme. I'm moving it forward. We're just going to happen. We're going to make this happen today. Again, the purpose of my talk is stupid. All right, so let's talk about a stupid ruby trick. Something that requires no brains at all. So let's talk about file.write and file.read. So this is the way, like, I've been in ruby since 2004, late 2004, early 2005. And when I came to ruby, this is how you open and read from a file, right? You open the file and then in the block, the closure there, you actually read from it. And then the file takes care of closing the file for you, right? And then when you read the same type of thing, you use the open block and then you have to pass the W flag in order so you can actually write to the file. And then, oh, I'm sorry, I got those reversed. I wasn't even looking at my slides. I'm so nervous. Anyways, you guys get what I'm talking about, right? All right, so we have that today. Instead, you can just call file.write now as of, like, ruby19. Like, who has used file.write, right? Okay, only like eight of you, so it's still good advice. It's still good. This is knowledgeable, right? And then the same thing for reading. You can just read right from a file without having to open it and it's stupid, right? Yay, stupid tricks. All right, the purpose of this talk is stupid. All right, here's another awesome stupid trick is optional parentheses. Did anybody here know that ruby has optional parentheses? All right, so here is the code that we just had written. Everything's uncommented. Now, look at all of these parentheses. I'm gonna highlight them in fuchsia so you can really stand out on this projector. I did miss one. Dang it. It's so stupid. All right, you can remove all of these. None of these parentheses are required, right? You can come up with something like this. I actually think this is a huge improvement. Can somebody point out, like, what's the thing that bothers people who like parentheses the most? File.read. File.read, okay, here we go. So, how does this work, right? That last line, it's like, you've got put s that's receiving file.read, that's receiving the string and what's the priority and you don't have the parentheses to help you out, right? And so, I'm gonna break the format a little bit and stupid ruby advice number one, don't overload lines. If you can't remove all the parentheses on a line, you have doing too much stuff on that line. Just add another line. If you're at a place where you've got to, like, keep all of your methods under, like, 10 lines of code, then, you know, don't just jam all that logic into a single line. Don't use ternary and stuff. Like, actually respect the absence of parentheses and don't overload it. Just make it simpler, right? I think it's good advice. So, I imagine, like, all of you knew this already, right? And, like, what am I doing up here to present these tips to a self-slucting crowd and those, everything? I would just like to point out that I do have the necessary qualifications to present. I've been programming professionally for 20 years. I've been in ruby for a decade. You may think that my qualifications are irrelevant, but they are not. And don't worry, this will be over soon enough. All right, let's talk about default hash values. This is kind of fun. So, let's imagine we have a hash and we got a phoonabar key with a phoonabar value. And what we want is we want to ask this hash for Baz and we want to get Baz. But Baz isn't in it, so when we ask for Baz, it says nil, which is the default value when there is no key that we're requesting. But we would really like to have Baz return. We know that we want Baz. And maybe this hash is really, like, only an exception hash. So, one of the ways that we can do this is that we can just call fetch and provide default value. So, now our hash will go out, look for the key if it doesn't find it. Instead of giving nil, it will give this value instead, right? So, if we instead put a new exception in this hash, like TrollFace, when we ask for TrollFace, even though we give it the default value of Baz, we're gonna get TrollFace back out. So, I don't know, I think it makes sense for this presentation. What else can we do with the default value? When you create a new hash, you can't do this with the curly braces, but you can, with the new method, you can pass in an object that will give you for the default value so that we don't have to call fetch. You can just use the square brace accessors. So, in this instance, we have a brand new hash list. It's completely empty, but we're gonna wanna get an empty array when we come back out, right? So, when we call nope, right, we expect to get an array. And when we can even start adding stuff, like we can add an x and a y and a z symbol. And so, this nope array, even though we haven't really set it to an array. And we get, you know, x, y, and z in that array. The problem with this is then if we ask for not even on this hash, we get the same values. And the reason for that is because the object that we gave for the default value is being manipulated for all of the times we're accessing the hash. So, even if we don't use the square brackets, even if we use array.new, same behavior, right? So, the way we get around that is instead of passing the object, we're gonna pass, oh, I'll illustrate this again. So, let's say our default value object is a string called default value. We create a new hash. When we ask for nope, we get the default value. And then we modify that original default value. We ask for nope again, we get the updated object, right? So, that's why this happens. So, we can instead pass a block that takes two arguments in the PROC object. It'll take the hash that it's being requested for and it'll take the key that it's looking for. And then you can decide what you're gonna do. You could convert the key to a string or do whatever, right? In my case, with Baz, I would have just converted to a string and upcased it and gotten the same behavior. But we're dealing with lists here. Because this is a PROC, we can create a new object here. And then whenever we ask for the default value, this PROC will get executed. We'll create a brand new array in this instance. Now we won't be sharing arrays. So, we can add x, y, and z to nope. And then ask nope. We got the x, y, and z. We ask for not even. And we don't have, we have an empty array. So, yay! All right. What else can we do? Oh, we can do the same thing with another hash, right? So, maybe instead of a list, we want like some sort of recursive hash. Like a PHP dictionary or something. So, you know, we use that same constructor block. And we just say if we don't have a value, we're going to use a brand new hash. And so, our hash is empty. We ask for x. We get an empty hash again. We ask for x is y. And we get nil. And if we ask for x is y is z, we get a no method error. Because that hash only goes the first level down, right? So, x is a new hash according to our default proc. But y is nothing and then calling z on nothing is an error. So, how can we make this even better? I meant to break this into two lines. But you can actually reference the original parent hash's default proc object. And set that on the newly instantiated hash, right? And that's pretty cool. So, you call x, you get a hash, you call x is y, you get a hash, you call x is z, you get a hash. And when you look at the original hash, you've got all that structure in there. And every time you access something, it just adds a new hash for you. Which is pretty cool. All right, so, let's make a mess out of this. Let's torture Ruby a bit. Let's create a Frankenstein hash, Frankenstein object. And we're gonna start out with the list behavior, okay? So, we're gonna add x, y, and z to nope. And then we're going to call not even. We're gonna get our empty array. We print out Frankenstein, right? And we get that array. We get nope with the three and get not even with nothing. Then what we're gonna do is we're gonna change the default proc, right? We're gonna set it to the recursive hash proc. And then we're gonna call x, y, z. And then when we look at Frankenstein, now we've got the different behavior. So that default proc object, you can swap it out, change it, even on instantiate hashes. So if you have a hash that you're using, you wanna add this behavior, just update the default proc object, right? That makes sense. You guys following this? I'm gonna leave the code up here for a few seconds, just so we'll let that sink in for a bit. Okay. Let's talk about include and prepend, and our friends super. This is one of the things that I really like about modern Ruby. I actually, I wanna find a really great use for prepend because I think it's a really fantastic facility. So let's take this example. We've got our foo module that does a thing, right? And we wanna include the foo module into me, right? Because I do a thing and then I also want foo to do its thing as well. So, you know, foo does a thing. I do a thing. We should both do a thing together. When I call this, though, me.new, do a thing. It only puts out me because we're not like calling super to tell foo to do its thing as well. But see, I wanna do my thing before foo does its thing. So to get around that, right? To make this work when you're dealing with calling up the call chain of your inheritance here, you need to call super. So I'm gonna go ahead and add that. I'm gonna call super. And now when I create a new me and I do the thing, I do the thing and then foo does the thing. That's kind of the way that it works. And that's kind of nice. Now, what's nice about the new prepend method here is that instead of being at kind of like the end of that inheritance chain, it'll put it up before you, right? So if you looked at the ancestors of me, foo would actually show up before. So I wanna switch that to prepend because I could call super beforehand but I wanna keep super at the bottom. I want foo to do its thing and I wanna do like all of the other modules that potentially do a thing that I'm including to do it before me as well. And I don't wanna change my code to do it. So you can call prepend and it will just put it at a different spot in the inheritance chain. Now, when I call to do the thing, foo does its thing but I don't do the thing anymore, right? And that's kind of a bummer because foo is not calling super. It's not going up the inheritance chain. So let's have foo also call super, right? Does that make sense? So I'm gonna create a new me to do the thing. I do the thing and then foo does its thing which is good and then I do my thing which is good. But then we get this error because I calling super and there is no super, right? And that's kind of a pain. Now, there's lots of ways that you can go and guard against this. You can be really anal about, you know, which modules are intended for include versus which are intended for prepend. But I think a better way and I didn't know that you could do this until, you know, relatively recently is that you can actually check to see if super is defined and if super is not defined then just don't call it, right? So put a guard conditional on this and now it doesn't matter, right? If foo does its thing, I do my thing. We added a bar that does a thing or a baz that does a thing. They just call super. It's not up to the module to determine if it's gonna be included or prepended, right? It's just gonna kind of do the thing and then call super if it can, right? So I'd like to see more of this. I'd like to see more defined super in code. And then we can switch it back to include. Create a new me to do a thing. Now, I do it and foo does it. Code doesn't change. The only thing that's changed is include to prepend. So, yeah, I think that's pretty cool, right? Yeah? All right. I think this next slide really says it all. That obviously did not work. I'm sorry. These are very terrible puns. Okay. So you may be asking why am I doing this to you? And the truth is, the truth is that I love t-shirts. I love conference t-shirts. That's one of my most favorite things about coming to conferences and putting on conferences is the t-shirts. In fact, and this is, God's honest truth, last night I had a dream that all of us together, we went to China, right? And we are going through customs. We're all going through customs together. We all had our passports and we all had our visas and we're waiting to get through and we're hoping, you know, like the customs lady is asking this like a year for business or for pleasure, you know, who is your visa signed by? Where are you staying? What hotel are you in? And everyone was getting through and we were all happy. And everyone looked awesome, by the way. You all looked fantastic in my dream. And everybody was wearing a white-pressed dress shirt except for me, I was wearing a t-shirt and I could not get through customs, right? And so you're all like, let's go, let's go. And I'm like, I can't. Like, they're not letting me out. They're going to arrest me. And you're all like going to China without me, so. Anyways, I love conference t-shirts, right? I'm here for the t-shirts. I'm also here for the stickers. Like, I love stickers. I like to make stickers. I like to put them on. So I just want you to know that this torture I'm doing with the puns, it's not about what I know. It's not about who I know. It's not about whether or not you know me. It's about whether or not I get a t-shirt and a sticker and whether or not I can travel through China. All right, stupid trick number five, data and end. How many people have code like this? We've got a constant with like a lot of data, like strings or just values in their code. Like I've got some files that are like, I don't know, like a hundred lines of just all this data stuff in a constant. And it's kind of ugly. You got to scroll through it. So here's a neat little trick that is pretty cool. There is the underscore underscore end keyword, right? And what this will do is it will take everything after underscore underscore end and it will throw it into data, all caps data, right? It's an IO like object, right? So what you can do is take all those values, throw it at the end of the file and then read from data and then split on commas or however you're formatting your data and you don't have to scroll past all of those constants because we all put our constants at the top of the class declaration, right? And then we have that long list of data. So you can just throw it at the bottom of your file and it's still diffable. You're not like going out to a config file or something. So that's, I thought, pretty neat. You can even go a little further and you can even format that data. So you have structured data with YAML or with JSON under the end, right? So it's, I think it's a pretty good crap. All right, I'm running out of time. I need a wholesome ass because my ass is on a line here. So I'm there on the line. All right. Pstore, who here has used Pstore or is aware of Pstore? Cool, only like a third. Oh, cool, this is nice. All right, Pstore is in the standard library. You don't have to do anything to get it. It's pretty nice. You require Pstore and then you create a new Pstore. You give it a path to where this file is going to exist and it's going to create a binary file that is transactional. So you can have multiple processes work on this file and it will lock and do all the things the right way. But it is the simplest database, the file-based database and you can, within the transaction block, read or write from this object, right? It acts like a hash. You give it a key and you shove in an object. You access a key and you get an object back out, right? So I think so far this presentation has had two useful pieces of information and that's like eight nines of puns, right? And then to pull it back out if you pass through the transaction, it's a write-only transaction, or read-only, sorry, got those reversed again. And then it just shows you how you pull it out, right? So you can kind of see how you could use Pstore, create like some sort of repository object. Maybe you're doing like an IRC or a Twitter bot and you don't want to actually spin up a whole other service for this. You could just use a flat file and access it and that's actually really useful. Here's another example. Like here we can set the useful information for Pstore. We can increment it, right? And then we can set puns to infinity and we can pull them back out and it actually works and it'll actually say so far we've had infinity puns. So that's pretty cool. The other thing which is nice is that it's not just like the raw values, you can actually do something like an open struct object, right? So here I'm going to create a new me with my name and my username. I mentioned that earlier on my GitHub profile. I've got the two names which sets me apart. Create that local object in my database transaction. I'm going to set my user to that object and then in a separate transaction I'm going to get that object back out and those objects are two instances of that same data. The object IDs are not the same but they're both open structs. They both have a name and a username with the same values. The object IDs are different but they're all for all intents and purposes the same, right? Which is cool and it's not just the kind of the standard library types. You can also create your own class with accessors. Create a P store. Create a new user instance. Write to the P store and read from the P store and it works the exact same way, right? And if you ever wanted to look at the file it's all binary and you can't read it. But you can, this is really fascinating. I like this as well. You can just swap out P store for YAML store and P store for YAML store in your code and it's the exact same code, right? So the only thing that's changed is what the database object is but it's API compliant between the both and then you can open up that YAML file and see all of the structured data, right? So I know you're, I think this is pretty cool. Like who thinks this is cool? Raise your hands. Everybody raises their hands. It's like hit, thank you. All right, so I can feel what you're asking. Like you're hoping that we've got a lot more tips and I'm afraid not. That was my last one. That was my last tip. But don't worry, everything's going to be all right. You get that a moment. Think about it. Yeah. You all right, John? All right. So I thank you so much for letting me speak. I'd thank the organizers for having me back and I hope that I get lots of fan mail from everybody who's watched us today. Please, it would be fantastic. If you want to, if you want like useful Ruby information there's a couple of links. There's a James Overgrave video from RailsConf 2010 where he goes through like 101 useful Ruby tips and then Aja has her cool shit file blog. That was just out recently. And thank you very much. I appreciate it. Thanks.