A week ago, I was on a code overload in Singapore. What was I doing on the other side of the world? Why, giving (and attending!) my very first talk at a Ruby conference, of course!
I was lucky enough to join some serious Ruby powerhouses at the Red Dot Ruby Conference earlier this month. And it was such a cool first conference experience. But, because I had to give a talk, I was pretty preoccupied with writing my speech and creating some fun slides to accompany it. What I forgot in the process was that I would be an audience member at the conference, too! (Pretty silly, I know).
My lightning talk was just a few minutes, which meant that for the majority of the two-day conference, I had the unique opportunity to listen to some really fantastic talks. And I learned so much. I also got to meet some interesting, talented, and creative people who have made some very significant and core contributions to the Ruby and Rails communities and codebases. Summing up everything that happened in those two days is a bit difficult since every talk was informative in many ways. But I’ll recap at least some of the dopest things I learned about while I was there. But if you want the full effect, you should probably eat a durian while reading this post – just sayin’.
Your Code Is Not Just Yours
One of the first talks of the conference focused on something I pretty much knew nothing about: security. AndrĂ© Arko’s talk, Security Is Hard, But We Can’t Go Shopping was an eye-opening look at why Ruby developers don’t think (or talk) about security vulnerabilities in their codebases – and why we all should be having that conversation.
AndrĂ©’s talk definitely caught my attention when he gave an example of a company that went out of business in a day because they lost all of their data because their severs were hacked. Yes, you read that right: lost all their data, shut down in a day. Pretty terrifying, right?
There were three big takeaways for me from this talk:
1. Updating is insurance
We’ve all looked at our code and seen deprecation warnings, or things that are out of date and need to be updated to the latest version. And, we’ve all, at some point, ignored those warnings. It’s really easy to think about shipping your code quickly and iterating fast, particularly because updating things is not fun. And no one wants to do it.
But, you know what’s worse? Your entire app blowing up because you had a vulnerability exposed in your code because you didn’t update! If we all started thinking about updating as insurance, we’d be more willing to sit down and put in the time to make sure all aspects of our applications were updated and thus, at the lowest possible level of security risk. This shift in perspective also seems like the best way to pitch “updating” as a task to project managers who might not see the time value in something like upgrading an already-functioning application.
2. Responsible disclosure
If you find a security vulnerability, be nice about it. Don’t be a jerk, man. Sometimes, you can even get a reward for disclosing! Figure out what the process is for disclosing a security issue to a company, and be empathetic to the developers who wrote that code which you’re using – who knows, maybe one day there’ll be a vulnerability in your code, and you’ll wish you had been nicer to those developers.
3. There are users, there are abusers
As a young developer, you can think about who is using your code. Many junior developers write code to get it to work or to make it fast, but it’s also important to think about who is or could potentially be using your code. It’s helpful to start thinking about those things, even as a new programmer. Consider things like strong params and csrf
tokens to start, and then work your way up to more complex security measures in your Rails applications. At the end of the day, you probably have some gaping holes in your codebase that is allowing someone to be malicious to your code base, which means that your code isn’t actually yours anymore.
All About That Efficiency
My favorite talk of the entire conference came from Sam Saffron, the co-founder of Discourse and one of the first employees at StackExchange. To be honest, this talk was less an exercise is learning new things and more a revelation in all the things that I didn’t know. And all the things that I knew nothing about centered around one thing: efficiency.
Sam’s talk piqued my interested in particular because I’ve been trying to think about the efficiency of my own applications for a few weeks now. I’ve been trying to use more efficient methods in my own code – like pluck
in last week’s post, for example, or my post on the ActiveRecord includes
method a few months ago.
Yet there’s a lot more to efficiency than that, it turns out! And that’s exactly what Sam’s talk aimed to explore. One of the things I learned pretty early on was that ActiveRecord is inefficient – yes, really! For those of us writing smaller applications, it may not be all that obvious. But for something much larger, such as Discourse, which has tons and tons of assets that have to compile on page load…well, it’s pretty obvious how even just one n+1 query could throw the whole thing to hell in a handbasket!
What I loved the most about Sam’s talk was the live demo. He actually ran his server in showed us the different technologies he used to track things like server calls, method invocations, and raw SQL queries. He didn’t just tell us what he used – he showed us what they looked like in development! And here’s the icing on the cake: everything is open source. Which means that we can all use the same technologies and fork them and add/modify them for our own projects!
Here are a few of the gems that Sam uses and recommends, which I’ve looked into. Lookout for some upcoming #TechnicalTuesdays posts on these soon:
1. lru_redux
This gem allows for efficient caching by using ordered arrays. It provides you with some pretty fantastic methods to write, read, and clear your cache. The most important thing here is that arrays are quick and efficient when it comes to looking up an item by index, which makes it ideal for something like storing a cache. Check out more on the lru_redux
Github page.
2. dapper
The dapper
gem is a lightweight Object Relational Mapper that was created by developers at StackExchange who wanted to solve an n+1 problem. What’s pretty cool about this gem is that it allows you to execute raw SQL queries and map your results. A major benefit of this is that you no longer have to rely on the Object-Relational Mapper that comes for free with Rails: ActiveRecord. We’ve all encountered ActiveRecord’s flaws – particularly when it comes to calls to the server and queries to the database – and thanks to this gem, you don’t have to deal with those things again. Instead, you can just write your own queries to execute! Find out more over on their ReadMe.
3. fast_pluck
I’m really curious about how this “freedom patch” actually works, and I need to take the time to sit down and read through it with a good cup of coffee. But, I really like the idea of speeding up ActiveRecord’s pluck
method, which I am already pretty comfortable with. Check it out over on this Gist.
4. memory_profiler
The memory_profiler
gem measures how many objects you’re allocating to memory on boot of your application, and how many are being retained (how much memory they’re taking up) in your app. I haven’t explored this gem too much, but I hope to play with it more in the future. You can play with it over here.
Language Design Is Hard
This realization is probably neither prophetic nor profound, but it’s still worth repeating nonetheless: languages are hard. They’re hard to read, learn, and, most of all, write.
Matz’s keynote presentation on the new and upcoming features in the next Ruby release was the first time I started thinking about how difficult it must be to actually create the language that we use everyday, and love so dearly. After his presentation, I asked him how he goes about actually designing new features, long before they are implemented. His answer, in short, was incredibly empathetic: he said that he thinks about what it’s like to actually use the Ruby language with the feature he has in mind, and he considers the user experience before handing off a feature for someone to actually implement and include in the next release.
I thought about the difficult problem of language design yet again during Paolo Perrotta’s awesome talk about refinements. If you’re not familiar with the concept (I wasn’t before this talk!), the short version is that refinements showed up in Ruby 2, and were used to make “local” monkeypatches, which are a much safer and preferable alternative to global monkeypatching. An interesting issue with refinements is that they rely on dynamic scoping, which means that you can close and reopen the scope of a class and redefine things in different ways.
In a way, it was great that Paolo’s talk was towards the end of the conference, because it tied up things together nicely. I learned that a simple thing like Ruby refinements – which boils down to two keywords, refine
and using
– were a perfect example of the first two things I learned during the conference: security and efficiency!
The issue with refinements is that you can’t always tell what’s going in your code, or what exactly your code will execute. And that’s pretty scary! You know what else it is? A security threat and a huge vulnerability. Refinements also slow your code down, because the Ruby interpreter has to go through all of your code and check if a refinement is being used or not. Not exactly the most optimized way of doing things, amirite?
All of this got me thinking about the people who write the languages that we use. They have to have a deep understanding of the language architecture and syntax, and think about how a developer might use (or abuse) a language feature. All of this is to say: language design is hard. And maybe we should all be a bit more grateful for the people who think about these complex problems on a daily basis.
Compared to things like security, optimization, and language design, a smelly durian doesn’t seem nearly as bad. In fact, I’d say that as far as developers go, we as a Ruby community have got it pretty good. But probably not as good as this dog right here:
tl;dr?
- Think about the two types of people who use your code: the users, who should have a seamless experience, which will make you optimize your code, and the abusers (or a better term that I can’t think of), or those people who will be looking for security vulnerabilities in your code.
- Language design is hard. Refinements are a pretty good example of how a programming language can blow your mind with a single feature
- I also met Matz! It was incredibly awesome. And he really is as nice as they say.