Today I'd like for everyone in the audience, you know, where we all deal with fixing bugs and if you're a good developer, you're looking at your app and writing bugs. So think about, think about like, I think everyone's probably at one time or another written a bug or had to fix a bug that looked like this. Not very descriptive, but you know, maybe somebody put some more information in the description. So let's take a look at that. Oh. Yeah. Well, well let's fix this one up. So first of all, I want to give this a nice clear, scannable title that if somebody looks at this they're immediately going to get a pretty good idea of what is going on. And these bugs live, these bug titles live for a long time in whatever issue tracker you're using. So it's worth putting some thought into this. So this is looking better and in fact, if you know a little bit of information about the environment, you could even stick that in there as well, it could be helpful. So now we've got our title fixed up and let's move on to the description. So as we, as was mentioned before with the scientific method talk, which was wonderful, it's very good to work through steps to reproduce. And that's for two reasons. Number one is so you are communicating a shared understanding of what you saw with a person down the line who's going to have to fix this. And number two, so you can actually go through these steps, think through what you did and write it down because sometimes you won't be able to reproduce it or, you know, something will be a little different than what you thought. So that's cool. And now the person will have a pretty clear idea of what they need to do. So the next thing I want to add is expected versus actual. And this is pretty important because sometimes maybe you've found a hole in the requirements or maybe it might not actually be like something that is a failure, but it's very confusing for the user. So it's good to separate out these two things. What did you think was supposed to happen versus what did you actually see happen? So we're doing pretty good here. This bug is coming right along. And the next thing, usually I like to add a screenshot. Screenshots aren't everything. You still need to write the steps to reproduce in a good title, but, you know, and usually like I see a lot of this when I see screenshots, which is okay. But I think we can do better. So in this screenshot, you've got a little more context on what you saw, right? Like maybe you can tell which browser it is because sometimes people might forget and leave that out inadvertently. You can see what the URL was. Maybe you've even opened the web inspector, which I'm not showing here, but you could and show the console. So that's been fixed right up. And I hope you all consider doing this the next time that you have to write a bug. Thank you. Hey. I'm Andrew. I work at a company called Mavenlink. Today, I'm going to talk to you about Huguen, which has nothing to do with Mavenlink. It's Huguen, H-U-G-I-N-N, which may have been a poorly chosen name, and I'm tectonic on Twitter. So Huguen is an open source system for building automated personal or business agents.  So Huguen's named after Huguen Immune, Ravens owned by the Norse god Odin, and they flew around the world and reported back to him on everything they saw. So Huguen flies around the world and reports back to you. It's open source. It's about two years old. I started it just to scratch my own itch, and then other people thought it was cool as well. It has almost 8,000 stars on GitHub, which is crazy, and I never thought I would be maintaining a project with as much interest, but it's also really cool. So some ways that people are using Huguen. Alerting when there's an emergency, sending you a text or an email. Monitoring sites that don't have RSS feeds. Monitoring local events. Monitoring music venues. Searching Twitter. Travel alerts. Weather alerts. It's also used in business. It was super cool. The New York Times interactive team used it to monitor some of their Olympic coverage, to keep both for some infrastructure monitoring and also to check whether their system was emitting their right alerts when metals were awarded. A DJ, I know, uses it to watch for new music and send them a digest email. And there's someone who is telling me they watched the New York Times public data releases and get an email when something comes out. Basically, there's something you want to know about, but you don't want to check it every day. Make a system tells you when something interesting happens. Finally, you could use it to tie things together, send a hip-chat message with this new base camp project, or monitor the status of expense reports in some internal system. So in Huguen, agents are Ruby. Agents are simply Ruby classes. They have a single purpose. They have memory. They have options that are configurable. And they emit and receive events that flow in a directed graph. So you can wire different agents together to make a more complicated system. It's simple Ruby. I know you can't really see this, but you just descend from agent. You declare some things. You can write a description and mark down. You can write an event description, declare what your options are. And then you have a receive method that gets called when events come into you. And you have a check method that's called on a schedule that the user gets to pick. Two very quick examples. Tell me to remind me to take an umbrella if it's going to rain tomorrow. OK. So I make a new weather agent. I tell it where I am, and I give it an API key for Wonderground. I wire it up to a trigger agent, and I say in the JSON that's coming back from the weather agent, check the conditions field looking for rain or storm with a regular expression. And if so, emit a new agent, which in this case just goes to an email agent that sends me an email at 5 a.m. So it works. If you don't check your email, it doesn't really help you. Another quick one. This is a little more complicated, but let's set up a standing alert on the world using Twitter. So Twitter is basically, I think, of the Twitter API as a universal API. So here I consume Huken, machine learning, and some other stuff like CFPs for conferences. And I watch for spikes in the data. So this emits an account every couple seconds of any tweets it sees that goes into a peak detector agent which looks for peaks of a high standard deviation. And when it sees them, it sends them out in a digest email. And then when there's a big spike in something like machine learning, when there's this well-received article, I get an email saying, hey, something you care about might have happened. Check this term. You can also do high frequency.  This is the spike in the term I was already coincidentally tracking, San Francisco Fire. It happened very quickly. Lots of integrations, SMS, et cetera. Sentiment analysis, you can track your location. I actually don't know what you want to do with this. But it's interesting. And it's the kind of data that's kind of cool for you to have, and you don't really want anyone else to have. And you should come pair with us at Mavenlink. We do extreme pairing. Thank you. Four minutes exactly. And you get the prize for precision today. Next up we have Enrique Mogallon. Hello. I have had really good experiences while getting feedback on the Ruby community. This is while programming or just in a pull request review. But before that, I had a different experience. I was working in a C-Sharp project. On my very first code review, I was on a call. I was contracting from Mexico. So I was on the phone. The manager was there. The senior engineer was there. And he started reading my code. And he tells me, oh, there is the right way to do it.  And this is not the right way.  But no, he was just talking about the code. So I just replied to him, yeah, that's just to keep you awake. And his response was, oh, yeah, I was working late last night, so I was up until 3 AM. And that made sense, right? He was just tired. But the thing is that he got me negative feedback. And like Kate said yesterday, we need positive feedback. Having positive feedback is really good for us. Why? Because we make better decisions when we feel good. And when we get positive feedback, we just feel good instantly. The other thing that he did, he was really aggressive. And of course, we have to get things done. But that doesn't mean that you have to get aggressive. The only thing that it means is that you have to express your ideas and be assertive. And for that, you have to respect the other's opinion. And the best way that I know how to be assertive is just by asking questions. So if you ask questions, you'll be more assertive. And what kind of questions you can ask is like, how do you feel about trying to do this? Or why did you do it this way? And why not on this way? And you have to be willing to learn, because you may not know the entire context, or you may not know that there is a new method or there is a new implementation, or that doesn't work in your Ruby version. But if you are in the other side, like if you have all the context and the knowledge, you have to do it the real bridgeway, which is you have to assume that the other person that you are talking with has certain knowledge but infinite intelligence. And that will guarantee that the conversation will move on. So please, be positive, be assertive, and ask questions. For example, how awesome is this conference? Thank you. Next up, we have Lane McNish. Hey, so I'm Lane. This is my first conference. I'm from Denver.  This used to be me. I was a cellist. Then I represented this guy. Now I go here. So in a box, that's me.  What is object space? The object space module contains a number of routines that interact with the garbage collection facility and allow you to traverse all living objects with an iterator. Object space also provides support for object finalizers, prox that will be called when a specific object is about to be destroyed by garbage collection. What are garbage collectors?  It's the thing that manages the memory. Essentially, it's the job of the garbage collector to figure out when a piece of memory has been allocated, is no longer needed, and to be allocated. Why do you need to keep track of this? When you're using a language with a garbage collector, there are certain things you might want to do. Run a method whenever a piece of memory is freed. Count all instances of a class that are currently taking up memory. Count all instances of all classes. Object space gives you access to do things of this nature. Essentially, it's a way to get access to anything and everything that's currently using allocated memory. One of the many advantages of dynamic languages such as Ruby is the ability to introspect, to examine aspects of the program within the program itself. Simple newbie explanation for people like me. We use introspection to examine parts of our programs that aren't normally visible from where we stand. What does this allow us to learn about our program? We might discover what objects in contains, the current class hierarchy, the contents and behaviors of objects, information on methods. And a quick little example of, it's kind of blurry, but something that you could use it for. You could see how many copies I've had today, just a few. What kind of beverage it is, what it inherits from and things you want to add to it. For example, if you sign up for last minute lightning talk, you might want to add booze. So that's it. Thank you. All right, next up, Yehuda Katz with new slides. Hey. My first set of slides was enough. So I work in a lot of areas that are not the Ruby community. I write plenty of Ruby code, but I also work in a lot of other areas. Standards, the Rust community, the JavaScript community. And one thing that I like to do because the Ruby community is so awesome and a lot of things that the Ruby community does are interesting, useful. A lot of things that the Ruby language does is interesting and useful. I like to cite things that the Ruby community and the Ruby language does in other ecosystems to try to get people to do things that I think are good ideas. And unfortunately, most likely the response I get whenever I cite Ruby as an example of something is laughter. And I think this is very unfortunate. And I think the reason why this has happened is that historically the Ruby implementation was very bad.  Sorry for any children watching at home.  We should look into doing that for JavaScript. Probably the response I will get is, well, Ruby can do it because it's such a horribly slow language. It's just a terrible implementation with such a complicated parser. Obviously, that's why Ruby can do it. It's clearly out of the picture for us. And I think the reason why this happens, there's a lot of guesswork I'm doing here, but I think the reason why this has happened is that Ruby is written largely by a bunch of people who don't speak very good English.  So you can make fun of Matt's all you want and he will never defend himself. In English at least. And I think this is very bad. I think so personally as a person who wants to use Ruby as a building block, as a way of informing other things because I think every language and every ecosystem has things to learn from, this is very destructive. And I think one really interesting thing is if you look at the Ruby implementation today, Ruby is about to get a three-generational garbage collector with incremental mark and sweep. It's about to get pretty, not necessarily JVM level garbage collector, but it's far better than Python.   Yes, there are many things about it that are still could learn some things from research in the 90s. But you know what? That's true about a lot of languages. That's true about most JavaScript implementations. That's true about Python. That's true about Perl. That's true about a lot of languages. And instead of constantly making ourselves feel terrible and making other people feel terrible at Ruby, I wish we would go out there and give Matt's and Koichi and all those guys a little bit of credit for all the work that they've done over the past few years to make the CAPI more amenable to both a better garbage collector and eventually a better JIT and basically all the work that they've done to make the implementation better. If you look at, for example, the programming language shootout, Ruby now always outperforms Python reliably and that was not true a few years ago. So it's really easy to give ourselves a hard time but please help defend some people who don't speak that good English and get attacked a lot and made fun of a lot. Just go out there if you see somebody, if you see something say something, if you see somebody making fun, if you see someone making fun of Ruby and the Ruby implementation, try to help out the people who do a ton of work to make it better all the time. Thank you. All right, next up we have Conrad Irwin. Hi, I'm Conrad. I work at Bugsnag and I also work on Pry. Today I want to share a new gem I wrote which was kind of a little bit of fun called console.log. It lets you console.log from your Ruby code. Sounds obvious, but let's have a quick demo. So I was trying to implement the change your email address in Bugsnag. You know, email address is important. We send you emails when things crash and so I created this form and you can see over here, like I've just used the Rails helpers, email address should be fine but if I see in my browser, that field's empty and I know that's wrong. I know my user has an email because I get spam from Bugsnag all the time. I just wanted to let you know because you were standing over there. So what's the problem? We should use the scientific method, I guess, and try and find some details about why this is happening. So I open up the user's controller, find the edit method and I'm just gonna add an output statement here.  I mean, obviously the email address is still empty because I haven't fixed it and then somewhere, there's my thing, somewhere there's a user object in here. Right, found it. Oh, well, yeah, obviously. Anyone had problems with Rails logs before? So, console.log. It's like put, but instead of putting it to your Rails log, it puts it to the browser console. See if I can remember how to use Vim and then this will work. So, I use console.log. If you use CoffeeScript, it's exactly the same as CoffeeScript and if you use JavaScript, you have to use parentheses. So I refresh the page here. I actually save. I refresh the page over here and suddenly here is my user object. So there's no scanning through Rails logs, it just appears immediately and that's all console.log does. Thank you very much. All right, next we have Artie Parikh with Exorcism. Hello, yeah, my name is Artie Parikh and today I'm gonna talk about Exorcism. So as a developer, I usually code in two to three languages and my daily languages are JavaScript, Ruby, Lua and I'm, you know, because I do web apps and also iOS apps using Unity, 3D and Corona SDK. So as Sarah Allen said earlier, you know, you pick a framework because it's a tool that provides some functionality to you. You don't necessarily pick a language. So what I found was that as a developer, I wanted to learn more in depth about these languages separate from the framework. Sort of like, you know, when you wanna learn JavaScript separate from jQuery or you wanna learn Ruby separate from Rails or you wanna learn Lua separate from Unity, 3D. So what I really found discovered last year was Exorcism is like a great tool. It was, it's created by Katrina Owen. So she has created this great, you know, place where you can come and do exercises in these languages, various languages.  And also, you can get feedback on your code from other people who are using Exorcism. So, and one of the mantras of, I guess, Exorcism is that, you know, the reason she created it was like, you know, you've got to practice writing expressive code, practice accepting feedback graciously and practice providing feedback respectfully. So, and a lot of times in my projects, I work as a solo developer and it's really nice to be able to get feedback, you know, and find out what I'm doing wrong or how I can improve. So, this is like some of the feedback that somebody left for me on a piece of JavaScript program that I wrote and it was like really lengthy but really helpful. And so, you can do that to others too. So, that's one piece.  One thing I found was that it also helps me, you know, separate, you know, separate out of my own code. Like I'm looking at my own code for a long time but I wanna like try something separate from my own code. So, this is nice because the problems are set up for you and the unit tests are actually written for you. So, you're just basically writing the actual code. So, if you look at, sorry, you know, if you look at the codes, this is how it's set up.  So, you don't have to think about the question that much which is kind of a problem I find myself as a developer to actually identify good questions to practice on. So, and that's, and then you can run everything on the command line, you can submit, you can access system fetch to get new problems after you solve them and you can submit right from the command line and that's all, thank you for listening and I hope you enjoy it. Next up we have Brian Leonard with Geohashing. Which are rad, I just found out. Just wanted to share something I learned in the last couple of weeks called Geohashes. Anybody heard of that before? I'm good, never mind. I was the last one at the party evidently and I think they're really cool. So, I'm still gonna teach it, that's how you learn. So, I work for TaskRabbit, we're a company that helps you get your fence painted or IKEA stuff assembled or a variety of other things. And in that, all these jobs have locations, things that need to be done in specific places and we have all these taskers, you know, thousands of people that happen to be certain places and live certain places and are tend to do jobs in certain places. We ask each of them to say where they wanna work and they draw a map like this. Leaflet, by the way, another really great library. And this is actually a pretty good standard true map. I was looking in the five minutes before this presentation for the crazy maps and there's a guy that drew one mile wide all the way down the California coastline for some reason. There's a guy that went all the way around the United States but left out Arizona. I just don't know it. He just doesn't like how they deal with time zones maybe. But the reality is that this is user input and if anything I've learned is to be skeptical of all user input. And so we actually see where these people are picking up tasks. And this is this guy's heat map. And so his map's actually pretty good. You can see that it's more or less works. But this isn't, heat maps are really good visualization but I found that that's not actionable when we wanna recommend somebody for this task. And so I started looking into where he's most probability-wise he's most likely to pick them up there. He's medium-level, likely to pick it up there. Low but still possible. And almost even more interestingly he's actively, negatively said things in all of these areas. So if we had a job in Hayward there like we shouldn't really talk to this guy about it. But how can we take all those latitudes and longitudes and draw these boxes and encode them stuff? And that's where I learned about geo-hashes which is a way to encode latitude and longitude into a Shah looking thing to be able to group them and compare them to each other. So we would take this spot in London which isn't like inherently that helpful and we would turn it into this little code Shah looking thing. And you do that by dividing the world up into keep doing it, cutting it in half. So you take the first half and you either get a zero or one in Greenland and then you take that and you divide it and you get a zero one. You take that and you divide and you get a zero one. And all of those zeros and ones can be ASCII encoded I assume into this hash. The really interesting property of this is that the ones that are kind of like each other specifically the substring starting from the beginning are actually near each other and quantifiably near each other. So if they only match the first position they're within that many meters all the way down to like very, very close area. So that last one was about 610 meters from the other one which is about a third of a mile because they differed in the last, only in the starting at the sixth digit. One of the ways I stumbled upon this is that we use elastic search fairly heavily and this is how it does all of its fairly impressive geo comparison things and that's because it's really good at substrings and because that's everything that it ends up being. If you're really astute you notice the big problem here which is if these two spots are off at the very beginning then you're kind of hosed all throughout and there are various ways to deal with that. That's it, thank you. All right, our last sighting talk speaker is a very special guest. Ladies and gentlemen, Josh Susser. So I've never given a talk at GroGorooko before but Sarah insisted and I apologize for having a Paul Graham moment here and reading my talk but I wanna get it right. So, two years ago Sarah May told us a story about a Ruby creation myth. Today I want to tell you a GroGorooko creation myth and like any epic tale it begins with an injustice. There was once another Ruby conference in the Bay Area. It got off to a good start but after the first year it seemed to me it had become mostly a fundraising tool for the hosting organization and did little to contribute to the community. Now, that made me mad and when I get mad I channel my anger into doing something constructive about the situation but I was angry. So I did something a little rash. I decided to end their conference by replacing it with one that better served our community. So I guess the folks on Twitter who called me a conference killer were a little right after all. But I don't think I did anything wrong. I mean quite the opposite. It's just competition and poorly run businesses get replaced by better ones all the time. That's what we're all up to. I was confident I could put together a good technical program and I'm pretty good with event logistics but I didn't know squat about running the business side of things and I spent over a year unable to get anything going. I eventually mentioned this to Yehuda and he said I should meet Leia. So soon after, Leia and I were sitting in my dining room talking about how we both wanted to put on the conference of our dreams with everything we wanted in a conference and nothing we disliked. Leia was much more of a conference nut than I was and ended up being the perfect partner to work with. She had been wanting to do something similar to and really ended up being the one who ran the show and made things happen. As we grew, we saw we needed a bigger team. Jim caught our attention. He ran a startup crawl event for RubyConf SFO that was amazing. So we asked him if he wanted to share that awesome with GoGoruko. Jim brought a ton of experience and enthusiasm and seems to have never seen a problem he wasn't thrilled to deal with. We weren't very ambitious. We just wanted to raise the bar for Ruby Conferences and set an example that other conferences would try to live up to. I know, pretty arrogant for a couple noobs. But in retrospect, I think we did pretty darn well. We showed that you can run a conference that is for the community, has a world-class program, is run with the highest of standards and still has a heart. I'm not saying that to brag. I'm saying that because we aren't really the ones who did that, you are. Well, those of us in the special T-shirts are up here in the spotlight. This was never about us. It was about you. Sure, we're the ones doing the work, just like bees do the work pollinating flowers, but it's the trees that bear the fruit. We could not have run this same conference in another city or built what we built here in another community. And that's why it makes sense for us to conclude GoGoruko. Jim and Leia and I love running this show, but this team has done all we can do to move things forward. We could continue to give you the same experience every year for who knows how many years. But that would actually be pretty selfish of us. Or we can hang up our hat and return our loan of this opportunity space back to the community. We had our turn, now someone else can take up the banner and move things forward in new ways. This has been some of the hardest work I've ever done, but it's also paid the best. None of us made a paycheck on the conference, but we had the rare privilege of serving our community on a scale most people never get to experience. So thank you for that. We are so grateful that you all came out to play with us.