 So, Soul Cutter on the Internet, on Twitter, GitHub, everything else, pretty much. I work for a company called TableXI. We're a small, medium-sized consultancy out of Chicago, Illinois. We solve problems. So, if you have any problems, come talk to me or email me, Bradley, at tablexi.com. I also am a contributor on the RSpec core team. I'm not actually one of the more active contributors right now, but I do really like RSpec. And as part of my initiation as a contributor to RSpec, I was led in on a lot of RSpec secrets. So this talk is about things that we don't tell users of RSpec that we use in order to write awesome tests. So you're about to be led in on the secret. The first one is a lot of people ask me about how to test code that actually has yields within them. And many people don't know, but you can test this really easily using the yield matches that are included in RSpec expectations. So I put a few examples in here of different ways you can test yielding. It also works with composable matches. So if you see the example of the hash including anything that pretty much implements triple equals will work in there as far as matching the arguments to a yielded block. So that's the first secret is that you can test that stuff pretty easily and you don't have to do any fancy tricks in order to do it. This next one is actually one of my favorite secrets. And it's a feature called aggregate failures. And for a long time I think the rule of thumb that everybody follows is that there should be only one expectation per test. And I think that that can actually make your test look kind of ugly. And I mean it works pretty well. Like the test that I wrote out here, it does run and it works. And it's not too bad to read the actual code, but if you look at the documentation that gets generated from that kind of arrangement, it really doesn't make any sense. And so like user when registered should be registered is kind of a tautology, doesn't make a lot of sense. Or when you're registered, you should be registered at some ridiculous long date string. So yeah, that's not really, I don't think the best way to write that sort of test. Aggregate failures gives you a tool where it's okay to write tests that have multiple expectations and it will actually tell you of each of the failures within that example block without having it hit the first failure. And you fix that one and then it hits the next failure. That's kind of a frustrating way to work within your tests. So there's two ways actually in order to invoke this. The first way is what I'm showing here with the green arrow. If you tag your example with the word aggregate failures like that, then it will run through all of the expectations within that example. If you don't know much about the RSpec example metadata system or whatever, you can come talk to me after this and I will chat with you about it. It's a pretty cool feature. But if that's still too much magic for you within your example block, you can do aggregate underscore failures, do, and then a block within that for whatever expectations that you want to be, make sure that they're all run. And the output that you get with this, I think, makes a lot more sense and it reads a lot better. So, you know, I mean, the example that I wrote at the top makes a lot of sense and then it kind of outlines each particular line that fails the expectation. And in this case, there's actually one expectation that did pass in there, so it doesn't say anything. So that's one that I use all the time, particularly useful for if you have a test that has pretty expensive setup. For example, like running Selenium tests and things like that where you hit a page but you want to make multiple expectations, I think it's really useful there and it saves you quite a bit of time. So those two are built-in to RSpec, so you get it kind of out of the box. You don't have to do any special configuration. This next one does require some magic invocation from the spec helper usually. It's wherever you configure your RSpec stuff. So you need to basically put this into your ... Oh, no! Oh, no! Oh, no! It's my favorite part. Well. In any case, this is more of a workflow one, so anyway, come talk to me about this later. Sorry, it's too long. I hope this talk doesn't turn out to be too random because this is me running on about four hours of sleep and thinking about all the things that I've learned and experienced in Mountain West Ruby conferences, a little bit of economics, a little bit of technology and things like that. And so that kind of gelled in my mind this morning I thought, I'll do a lightning talk. This is the last Mountain West Ruby conference. I've never spoken at it. This is my last chance. So when I entitled this talk, I called it re-evaluating value. And the reason why I called it that is because I think our understanding of value is really skewed towards the classical economics. You have supply and demand. You have scarcity, you have abundance. And things that are scarce are really valuable. You think about gold, it's really hard to find, and it has some value. People want it. And because it's so scarce, people say, oh, wow, gold's really valuable. And the same thing happens with diamonds. And DeBeer says, hey, we're going to make these diamonds really scarce. And that's going to make them really valuable. But there's really a different way that you can think about value that I think is kind of unique. And I wanted to give an example of that. So pretend that it's back in the 1970s and I have the only fax machine in the world. All right? And I'm proud. I'm excited. I've got the only fax machine in the world. What is the value of that fax machine? Goose egg, right? Fax machine. So I'm like, oh, I'm friends with Mike. Here, Mike, I'm going to give you a fax machine. And I'm going to make myself another fax machine. So what's the value of Mike's fax machine? Still, but it's worth more than nothing, right? And the crazy thing is that my fax machine suddenly has value. I start creating more and more fax machines. And suddenly everyone who has a fax machine can fax something else, anyone else that has a fax machine. And that idea of scarcity creating value kind of gets flipped on its head. And instead of scarcity creating value, you have abundance creates value. In fact, you can do the same thing with phones or computers, think about the internet. And there's all these things where instead of scarcity creating value, abundance is creating value. And the key thing is that if you have something that can create connections and exchange information, the more of them that you have, the better. I think like a single brain cell has zero value, right? But you get billions of them in your mind and you can think of all kinds of things. You can do all kinds of things. And so as I was thinking about this, I was thinking about what's the value that Mountain West's Ruby conference has given to me? Because a lot of these videos you can get online. You can get on Confreaks and watch them and stuff. But to me, the interesting part is that I can come to Ruby conference and I can connect with my fellow Rubyists and we can have an exchange. And there's something valuable that's created from that. And you know, I came to a Mountain West Ruby conference and Matt was up on stage. We were cleaning up afterwards. He puts on a sombrero and I'm like, hey, I should go talk to Matt, right? And I got a picture and I was able to talk to him, talk with him about his family in Japan and being their developer there and things like that. And I was able to make a connection with him and get some value out of that. I remember the first time I used XML, the XML builder gem and I had a bunch of ideas and I emailed Jim Wyrick like, hey, you need to fix a bunch of stuff about your gem, right? I had no idea who he was. I just got an email address and he emailed me back and he kind of set me straight and said actually my gem does all those things and here's how you're using it wrong. And I was simultaneously humbled and encouraged by the fact that he would take some time to kind of help me out and that there was like a connection there and that created something valuable for me. So anyway, I just wanted to get up and say thanks to Mike for this, for creating value and creating a conference for me. Let me make sure my notes show up right. There they are. Okay. Okay. So I'm giving this talk because I attribute my professional success to my affinity for tabletop role-playing games. This is because RPGs, I got five minutes, have taught me to reason it through seemingly impossible situations, work with a team in like bizarre and artificially constrained scenarios, articulate my reasoning and decisions carefully and most importantly appreciate the unique contributions that each person brings to a team. Does that sound familiar to you? It should. So here's how it works. I'm going to teach you how to play. The Dungeon Master runs the game. Everybody else is a player. The Dungeon Master is the arbiter of the rules, the settler of disagreements and the teller of the story. The players are the actors in the story but they're actors with self-determination and motivations that extend beyond the setting described by the DM. The DM starts the story and describes how the players' decisions and interactions affect the world around them. The real joy of D&D is in these tables' interactions. It's essentially multiplayer chess with a theater troupe. So there are many RPGs where it's talking explicitly about Dungeons and Dragons, a rule center on funneling broad concepts into narrow definitions until they can be classified and measured by rolling some dice and comparing the sum of that dice to a difficulty number. That number is decided by the DM and every DM runs their own ship. All the books are polite suggestions at best. The best DMs live in the moment, fueled and inspired by the power of the story. So here's the details. You have six attributes, strength, dexterity, endurance, intelligence, charisma, wisdom, and wisdom. That serves as a foundation for a larger number of skills. Everything you want to do in the game, should it require a measurement to determine success, can be classified into a combination of skill and relevant attribute. Want to kick down a door? That's a strength check. Roll a D20 with the dice with 20 sides and add your strength. It's a creaky old wooden door, half-rooted and moldy. Get an eight and it breaks. Solid steel, nothing but a 20, and then you're just going to rattle it in its frame. You can't kick in the door. Did you try the doorknob? Oh, it's locked. Cool, that's a slide-of-hand check. Let's pick it. Slide-of-hand is associated with dexterity, so roll a D20. Add your slide-of-hand score and your dexterity check. Strong door, weak lock. Get an 11, it pops right open. Every other rule in the game is an extension of this premise. Decide on a course of action, describe it to the DM, negotiate the relevant attribute and skill combination, roll the die, compare the difficulty number and see what happens. Whether you succeed or fail, the world has changed. The story has changed. Did your failed attempt at kicking open at that door awaken your neighbors? Are they frantically calling 911 or cursing under the breath as they roll over? So the stories are what matters. If you want to be good at D&D, learn to tell stories. Know what details to include and which are best left to the imagination and practice by doing. I do this by taking lots of pictures and then making up stories about them. This is a really good storytelling picture. If you can imagine that little dog on an enormous adventure, D&D might be the game for you. That's my dog. Here's another story. In our current campaign, I assume the role of Swift the Falcon, a bright-for-barbarian half-dragon who's more bohemian than Conan. His brother, Majita the Lion, always sends Swift with trading caravans because Swift can speak three languages, handy when you're trading hide for ale and silk. And as Swift as Swift is, he cannot read or write because barbarians don't keep tax records. Dracella, played by my girlfriend Brenna, is a mute ex-monk turned wanderer. After an unknown arsonist left her lifetime monastery, a ruin she took to the road, seeking not revenge, but renewal. Brenna personifies this role well. She won't speak to players during the game, often going hours without a word. Instead, she writes notes to the other players or pantomimes her reactions. So what happens when the mute monk and the illiterate barbarian team up to solve a kidnapping? Wacky hijinks and adorable pictograph communications. So these are pictures that have all inspired stories for my tabletop games. In conclusion, I care more about storytelling and spending time with the people I like than I do about partial cover rules or the varying carry capacity of pack mules or the armor class of chain mail. D&D scratches the itch I have for problem solving, provides a social context to spend time with my friends, and helps me hone the skills that make me good on a team. It gives me a place to tell my stories and experience the stories of others. Thank you. How to be a great developer. Don't use DeXit in front of a group of 200 people. So I'm Ben Agat. This is also not a talk about scratch scrapers. Totally blew it, but Ajah inspired me to stick that one in there, thank you. Remus, I've had a good opportunity in my life to give a lot of people some advice about starting a career or improving their career or, you know, really a lot of people come to me and said, how can I be better at what I do? And I wanna share some of that with you today. First question I'm gonna ask, why do we write software? There's a lot of answer to that. Think about that on your own. And who do we build software for? Okay, we build software for people. We build software to enrich people's lives. Now, when you're starting a career, you often feel like this. There's a lot of hesitation. There's a lot of apprehension. There's a lot of unknowns out there. And there's a lack of confidence generally when you're entering a room with a lot of experienced people around you. So, how do you become a great developer? First thing I wanna point out, it's my opinion, take it at face value, is tech skills are overrated. They're only part of the equation. When interviewing for a job, this isn't the most important thing. Personality trumps tech skills at almost every time in my book. Experience is very important, but your personality, and not just your personality like, hey, are you funny? Do we get along well? But your capacity, your desire, your passion to learn and improve upon yourself, those are key elements of your personality. When you approach a problem, how do you face it? Do you back down, or do you keep yourself calm and collected and overcome it? So, you wanna be a great developer? It's five things I wanna talk about. First is, that should say practice empathy. Practice empathy. So, why empathy? Empathy is your ability to understand how a person feels and why they may feel that way. It's your most important skill. When we're writing software, we're writing for people. There's two groups of people in mind, the users that use it, and the rest of our team, the people that we have to correspond and work with, on a daily basis. They're the ones affected by the decisions you make. So, one thing I wanna point out is, you need to be careful in assuming that you know why a decision was made, unless you're in the room when it was made. Assumptions are very dangerous, and we see that a lot of times. A lot of times this leads to interpersonal problems, et cetera. Practice humility. I like this. If you think you know everything, you're wrong. Think you'll learn everything, you're wrong. Be open to the likelihood that you were wrong about a great many of things. The less you fear being wrong, the more confident you can be. Understand what you do well and what you don't. Keep learning. This has been a consistent theme throughout this conference, and it's been absolutely fantastic for this. I really like this quote. I'll let you read it. So, it's up to us. If we wanna learn, it's a choice that we need to engage ourselves. Be liberal in learning about new technologies and approaches, be conservative in using them. Any technology can be the right choice depending on the needs of the project constraints of the team. It's not Ruby only, it's not Rails only, it's not JavaScript only. What's the right tools for the job? Avoid tribalism in work and in community. There's no room for boys club. Enough said, I could expand on that in a lot of ways, but please be inclusive and better your community. How can you better your community? Be active. There's events all around you. Here in town, we have the Utah Group Users Group. I organized the Drug Weekly Hack Night, Drug Weekly Month Meetup, Monthly Meetup. Tomorrow we're having a hack night at Coffee Street, Coffee Shop just down the street. And next month, Mike Reese is gonna be talking to us more about robots, so come and learn and do that with us. They're on Wednesdays every week and the monthly ones first Wednesday in the month. So come out to that. Make people's lives better with your skills, make the community around you better. You don't need to go to some magic city of tech genius to do important work, okay? Share what you learn with the people around you, ask them to share what they've learned with you. So you wanna be a great developer, practice these things. You'll notice that none of these things had any tech skills related to them. It's just how to be a good person, a good employee, a good coworker. And encourage you to just kinda think about that as you evaluate your decisions. Thank you. Okay, I'm kind of a pioneer. Going back to the talk that we're talking about. So I'm gonna tell you about a language that I'm really liking these days. It's crystal language, has nothing to do with crystal meth, hopefully. Somebody was asking in Twitter to this guy, what's this language all about? And I like how we put a definition together. Friendly syntax, static type checking, modern standard label, compiles into efficient, easy to distribute, native code, macro, self-hosted. So let's try to expand a little bit on that. Yes, it is very cool, but how? The syntax is very similar to Ruby. What you have right there, you can read it. It's Ruby, right? There's one letter difference. What is it? That question mark right next to RV, right? And we're gonna talk more about type checking and why that's important. Static type checking, what I call the checking, right? If you look at that, and if you look at it with the eyes of Ruby, it's gonna run every single time, right? In crystal, it's not gonna run. It's not gonna even compile, it's a compile language. Because what it's gonna do is gonna say, well, the value of A could be a type integer or could be a type nil. And nil doesn't know that declaration, doesn't know how to deal with plus. In crystal language, the plus is not defined for nil. And if you cannot call a method that is not defined for all types. So it's not gonna compile, it's not gonna run even the first time. Like you can see also, I didn't say which type it is. So we tried to figure out, as much as it came, what type it is. It has a modern standard library. It has all the kind of cool and new stuff already baked into the language. Things like spec that is very similar to RSpec, CSV, JSON, XML, YAML, Markdown, HTTP clients and servers, even including web sockets built-in, OAuth, OAuth2, second round, 11 same HTML builders, all kinds of things already built-in to the language. Like I said, it compiles into fast native code as in micro second fast. The code that you see on top is a very basic HTTP server. And what you see below is a copy of how it will run. The first time you run it, it took 725 microseconds. So it did take some time on the first time to run. But every single time after that, it was 8257, well below 100 microseconds. It is kind of refreshing to see how fast programs boot and how fast program runs every single time. It doesn't do metaprogramming like we know in Ruby because that's just running at runtime. And like we said, it's a compile language so everything that you need to do in kind of a fancy smart way, you need to do it in advance. But there are things that you can do with macros to create your own method, method definitions, method builders. It all ends up being valid. It has to be valid, crystal code in the end at compile time and not at runtime. But this lets you do some nice things with your code. It is self hosted and what that means, it is written in crystal, most of it. If you can look at that, it's 98.2 in crystal, 0.7 in JavaScript and 0.4 in HTML and 0.3 in shell. My guess is you can easily speak most of the languages or you already speak those languages. It also can cross compile in different platforms. So if you are an OS 10, you can cross compile into Linux just in that same machine. I have some links for you here about the language. The API is very nice and clear with a nice documentation. I mean, the documentation can go a very long way, still, more examples and more things but there are a lot of cool things you can do there. There are a lot of libraries coming in that are still a lot that need to be written and again, it's an opportunity for you to be the one to write the first library, for example, that's things like Hamo, if you're into that kind of thing. In any case, my biggest objective is to pick your interest and have you go and try it out, check it out, I think you're gonna love it. For me, it gives me a different set of challenges and a different set of constraints. And it gives me a lot of things that I always like which is speed, but I need to think about the types that I'm using and I need to think and think more about in advance how this is gonna be built. And just because I'm a little nostalgic, I had to bring it back. There were not enough sombreros in this talk. And it gives me a lot of... Mike, thanks again, great conference. I've had the opportunity to come to a number of these different conferences. I don't, obviously don't have my laptop or any slides or anything, I'm very unprepared. Yesterday, or actually about a month or so ago, I had a number of tests that I was developing a project and I do the best I can to try to practice good test coverage and I had a sporadic test failure and it really bothered me. I could run the model itself, it would test fine, but when I ran the whole suite of tests, I get this random failure and I could not figure out how to do it. And I sent an email to U-Rug, didn't get a whole lot of feedback back about it. So yesterday I came here and I watched Ryan do his presentation on building a test suite. And I gotta say something about the Ruby community. When I first, my first, I think it was Mountain West, was up at Snowbird, Ruby Web, okay. So that was the first event that I ever came to related to Ruby. I had never written Ruby, I'd never seen Ruby, I'd heard people talk about it. I went to this event and I remember seeing these people, everybody in the room was like way up here as far as, I mean, I was just blown away and humbled by, I've been programming for 15 years plus at the time and was just blown away by the community. And the welcoming, we talked about this already here a couple of times. The welcome, the way that this community responds to new people and mentoring. I've just gotta acknowledge you guys for that. I wouldn't be here if that weren't the case. I love, I've gotten to really enjoy Ruby. Anyways, I came in and I had this problem and Ryan was sitting here, I sat down next to him and he was like, oh sure, yeah, I'll look at it. Took me out in the cafeteria and we sat down and he showed me this new, this not new gem but this gem that he had called Minitest Bisect. Has anyone used it? A couple of people? I had never heard of it before but I had 500 tests and 1,300 assertions in my tests. I know it's not good. And he sat down, we had to hack through it a little bit because there was a problem with an exception that was being thrown. But in 10 minutes this thing found the combination of files that resulted in my random error and we were able to duplicate it and it turns out I just had a name collision with I named it test class the same as something else. They would take me forever to find this or I would have never found it. I would have just said, ask for it. It's expected to fail. Just run the model and you're okay. But I was just, if you haven't looked at Minitest Bisect, he's cheating, he's helping me cheat so I don't get buzzed. I recommend doing it because within 10 minutes this thing just went through all of my tests and did every combination it could is my understanding of how it works and gave me the three files that in combination made this test fail. And then I could take a look at those three files and it was no brainer once I did that. Other than acknowledging you guys and saying thank you and I hope that we can carry on this legacy that Mike started with the Ruby Conferences in Salt Lake. Thanks for the opportunity to be here. Hey, I'm Joey. I'm actually a pretty new programmer. I go by FergMath to flex on everything. So look me up. I wanna talk about, I went through a bootcamp and I made a pretty massive transition. I was actually a journalist for the Desert News. Also for Silicon Slopes, if you even know what that is, we're pretty awesome, but this was my old career and I just trashed it. I went through a bootcamp called Def Point Labs as part of the first class. A lot of my colleagues are here. My instructor was Ben Eggett and I'm gonna actually echo a lot of things that Ben said earlier. I now work at MX. It was a long bumpy road to get to MX but it's definitely my dream job. So at least so far. So I wanna talk about, a lot of people ask me like how did you get, how did you jumpstart your career? I do a lot of mentoring at Def Point. I did this cohort, I've slacked off quite a bit, but do a lot of mentoring there. And towards the end of the cohort, a lot of people start getting nervous and start almost panic asking me, what do I do? All I have is advice for them and the first thing is, don't assume you're entitled to a job. That's the first piece of advice I would give you and jumpstarting a career, whether you're self-taught or through a boot camp. You're not entitled to a job just like any other line of work. To echo Frank Underwood, one of the worst fictional characters of all time, you are not entitled to anything. You're entitled to nothing. So just keep that in mind. It's not a downer, it's just you gotta work at it. Knowing Ruby and or Rails doesn't really make you stand out. And you just gotta keep in mind that money is not important. You're not entitled to an amazing paying job because you still have to kind of pay your dues just like anywhere else. Don't get discouraged when a job doesn't come. Just take the time to get better and become a better programmer. Are you qualified? The answer is not, not right out. A lot of companies will have a hard time considering you qualified. And here's what actually will make you qualified and I'm gonna echo a lot of what Ben said earlier and I have three H's for that. Triple H, if you will, I need pro wrestling fans out there. Hunger, you've gotta be hungry. You've gotta go out there and get it. You've gotta constantly be learning and be excited to learn. That's a huge characteristic for wanting to hire someone. Don't you clap, stop it. Humility. What's so funny? I don't understand. Humility, it's important to understand that you are new. You don't know everything and there are tons of people out there that know way more than you and you need to use that. And helpfulness, the Ruby community is a helpful community, end of discussion. We are helpful people. People will help you. You need to help back, okay? Don't walk around like this, like the cocky cockatoo here. Don't do that. You are not the stuff. I almost swore. You're not the stuff. You are not as awesome as you think you are and it's okay. Also, nerdify. This is what I say to everybody. I quoted myself. I gotta work on the humility thing. You're a nerd now, so act like it, okay? Act like a nerd. It doesn't mean, well yeah, you should play D&D. It's pretty dope. But that's not what I'm talking about. What I'm talking about here is you need to go out there and you need to build robots and you need to make cool things and geek out about new languages and that's what you are now, okay? Just take Garrett Thornburg as an example. You gotta be this guy. You probably got two pins. One minute, thank you. Finally, you need mentors. You cannot do this alone. End of discussion. You wanna see how many mentors I have? These are all my people I consider to be mentors. People who have helped me get to where I am today. If you're on this list, thank you by the way, very much. I would say also basically anyone at MX. Amazing company. They have really helped me get to where I'm at. Finally, menace one, okay? Someone will tell you ultimately that you are not capable of it, that you will never be a programmer. You tell them to shut up, okay? With your actions. Don't actually say that. Because the point I'm getting at here is those people to me aren't really following this. That's not what Ruby community is all about. We all wanna be good at this. We all wanna share this joy. And so there might be some haters, just ignore them. So anyway, that's all I got. Thanks. Woo! You know, Ruby has bytecode and that's pretty awesome. So what does IR mean? Is it infrared, you know, like remotes? Well, no. Is it skyscrapers, you know, like in the sky? Really high? No. It's compilery lingo. That was much easier when I wrote it. Intermediate representation is what it means. And by that, you could talk about assembly, or Java bytecode, or Ruby's IR, which I wanna show a little bit of, or JRuby's IR, and there are a number of different types of IR, so you can talk about the syntax tree itself. And that's a fairly common IR, but that's not the one that people who are working in compilers always find interesting, and usually they don't think of that as an IR. So there are different kinds of machines that IR can represent. Stack machines, which is a machine that has a list of instructions and a stack, so like you push stuff on the stack, and then you perform operations on the things on the stack, and then there are register machines, which is where you have a list of instructions and then a list of registers. And in that case, you know, it's like, well, what do registers mean? Well, if you look at assembly, you see things like EAX, and all these kind of weird acronyms, and those are actually just variables. They're just kind of funny variables. So I have some code that I wanna show a little bit. So I wrote a Fibonacci algorithm, because you know, that's the common demo thing, because it's got calls, it's got recursion, everything. And this is Ruby, this is Java, and the reason why I have a Java example, I'll get to in a moment. But I don't particularly like Java, so I also wrote it in Mira, which is kind of like Crystal, but for the JVM. And if you notice, the main difference between this and the Ruby is that there's a type annotation, and for some reason the main part is kind of funky. So you can run this and compile it, or this, and you end up with this interesting class file that contains byte code in it. And if you run a special tool called JavaP, then you can look at that byte code, and it's pretty nifty. So Java will give you all this cool stuff, like it'll tell you all the constants that are used by your file, as well as what the lists of local variables are, and then it shows you this stuff, which looks kind of like assembly. And so what this is doing is essentially showing you the entire implementation of your algorithm, but in a very step-by-step way where it's pushing things onto a stack and then performing operations on that stack. So what this actually is doing is it's loading the current instance, then it's pushing a two onto the stack, then it's doing a comparison. And if you wanna look at that, what that actually corresponds to, it's this part, because it's, one of the things that it's pushing onto the stack is zero, which is the first local. And then it has a go-to, depending on which branch we're going on. So we have this branch, so if a is less than two, then we go here. And if it's more than two, then we do this complicated thing. And the complicated thing is actually just like loading the first thing, loading one, then doing a subtraction, and then invoking a method, using that as an argument. And then it does the same thing again, but does a subtract two and invokes fib, and then you add the two things that are on the stack together and you return them. And so Ruby has a very similar IR. Ruby's IR is also, so let me take a step back. So Java uses a stack-based IR. So it uses a stack machine, so it's got instructions and a stack. And so we push things onto the stack, and then we pull things off the stack, and then we do things with them. And so does Ruby. So if we were to do the same thing essentially with the Ruby program I showed you, we'd end up with this big file, which is a little complicated to read, so I cut out some of the pieces. So in this case, the comparison gets turned into this code, which basically gets the local, well actually this is the two, this is the local, and then this is the comparison. And it is basically the same logic, but the difference is it's a little bit more complicated because Ruby's mechanics about those things are more complicated. The interesting one was JRuby, which uses instructions. So you can get access to all of this stuff. It's under the covers. It's really easy to play with, and you can look at it, and you can see how everything works underneath everything, and it's pretty accessible when you find them resources for it. Thanks. Wow, I'm honored to be up here on stage. It was after so many awesome people. It's been a great RubyConf so far. So yeah, I just want to second what a lot of people said. Ruby community is amazing, and I mean the language itself is beautiful, but I mean I think the main reason all of us are here is it's an awesome community. So let's hope I have wifi. Okay, so I just want to talk really fast about a gem that I've made and used in production for a few years and continued to improve over time. It's called the Petergate gem. You can install it like any gem by just saying, putting it in your bundle, putting it in your gem file, or gem install Petergate. It is sort of built around a lot of methods that are included in devise, so if you're using devise and awesome, if not, make sure that your authentication method actually uses at least these methods, and I might have forgotten to mention exactly what Petergate is. It is basically a gatekeeping gem or authorization, similar in some ways to pundit or can-can or can-can like X100. I feel that it's a lot simpler to use and approaches in a slightly different way, whereas it's not trying to do everything can-can does, it's just trying to be simple in a lot of ways like rails in a lot of ways can be with like before actions and what used to be before filters and strong params. The main things it does is in your model, you would define Petergate in the same way you would define devise, list the number of roles that you wanted, such as admin, you could say whether or not you want to use multiple roles on the same user or just a single role, and then in the controller, you would just post a single line, access, everybody can see show index, users can see everything except destroy, company admins can see all, et cetera. It also has a kind of weird thing that I built in a while ago that allows you to actually say this array of roles can actually see this array of indexes or this array of actions. And it also, as far as like displaying content versus not displaying content for specific roles, allows you to use the logged in method, which you could pass just an array of roles to, and if any of those happen to be logged in at the same time, it will return true. Otherwise it will return false. There's a few other things that might be useful such as being able to see all of the available roles from some other object. So there are a few ways you can get those and I show them here. Let me just pull up a little bit of code first and try to demo that really fast. So terminal, this is just a simple, let's just say news app, yes. So first in the user model, you'll see yes, thank you. Can everyone hear that? See that? Whatever you do with your eyes. Okay, so in the same way you define device and say what it's loading, you would just define Petergate and then list these are the roles it's going to use. In this case, I'm using multiple true. If you don't use multiple true, you can use multiple false. All of this like device is also added by the generator so you don't actually have to add this yourself although you would customize it yourself. And then in the post controller, you'll see I'm saying access. Everybody can see the index. Users can see index and show and editors can see all of the actions. So that's basically set up in such a way that you could see news posts but you couldn't actually read them unless you were a user and you couldn't change them unless you were an editor. So let me just actually go to that page. And so this is actually logged in as an admin. As an admin, I can actually add new users and see which roles they have. See admin has company admin and user. Editor has editor and user. User just has user. So let me just actually, I do me login as an editor. So logging out. Cool, my internet work. And you're very cool. Howdy everybody. My name's Andrew Butterfield. And this is my second Mountain West Ruby conference. I've really enjoyed it. It's had it's the last and I'm super grateful to squeeze in at the end here. And today I want to talk about searching for the unattainable. And I wanted to remind you of three legends that you're probably familiar with that you learned in grade school. The first ones are Sir Walter Raleigh and his search for El Dorado, the mythical city or empire of gold. Juan Ponce de León and his search for the fountain of youth. And lastly, King Arthur in the Knights of the Round Table and their search for the holy grail or quest. Should use the proper term quest. So I guess I want to talk about commonalities between these three different explorers. They all have lots of money. They all had a good group of people with them to help them in their quest or search. They had all the equipment that at least at the time was thought they would be needed to search for these things. But they all failed in trying to find these unattainable things. And the reason that they failed was because these things don't actually exist. Spoiler alert, sorry if you think that they do. But they don't. And so I wanted to talk about like, what's your holy grail or my holy grail or what are the things that are getting in the way of you being able to achieve what you perceive to be unattainable, at least right now. And so I want to talk about three different reasons that I've thought about. Under the premise that, let's assume you have the money and the resources that you need. You have a good group of people around you and you have the equipment that you need. But still, there's something that isn't quite in your grasp at least that you feel like. And so why would that be? So the first reason that I want to talk about is what I'm calling the agile gambit. And you could substitute any word in there for agile but it's a good specific example. And for those of you who aren't chess players out there, a gambit is a strategy or a move in chess where you sacrifice a piece that's worth less in the hopes that it will give you a strategic advantage in the future. And so I feel like in the processes that we're engaged in as developers and in our industry, there's been a huge shift over to agile development. And the shift has been away from something called waterfall. How many people have done waterfall development out there? Cool. I've never done it before because the shift happened before I got into the industry. But it definitely feels like a pariah, right? Like a taboo term like, let's not do waterfall, right? And so we play this gambit, this agile gambit in a lot of our planning. But I think that in agile, sometimes we do it wrong. And we don't do enough of the things that are part of waterfall that are beneficial. And I'm not saying that we should go back and do waterfall in our engineering process. But I think that a lot of times we discount things because other people say that we should or an industry says that we should when there is still value there that can be incorporated into our current process. And maybe that's inhibiting us from reaching what's unattainable. The next thing I wanna talk about is the streetlight effect. So I was a Boy Scout and I participated in this get several times on campouts that was about a streetlight. And the story goes something like this. There's a drunk who's under a street lamp at night time, it's in London. And he is looking for something. And a police officer is walking down the street and sees him and asks him, hey, what are you looking for? Did you lose something? And the drunk says, well, I lost a quarter. Can you help me find it? Okay, dang. And the police officer says, sure. So they look for a little bit and they don't find it. And the officer's like, are you sure you lost it here? And the drunk says, no, I lost it over there in the park. And the officer's like, why are you looking for it here? And so really like the meaning, or I guess of this story is that sometimes we use tools in the wrong way. And the last thing that I wanna talk about probably won't have very much time as the founder's dilemma. But if you remember Iron Man one, Tony Stark says just before he fires Jericho missile, this is how dad did it. This is how America does it. And it's worked out pretty good so far. It's easy to kind of slip into complacency once we've kind of achieved something and not progress. So I challenge you to overcome the founder's dilemma. And maybe by recognizing these three things, it'll help you to attain the unachievable things.