This year again, I attended Ruby Nation. This year was great because I actually understood what was going on!! Admittedly, I took better notes on the second day than on the first because I was speaking on the first day but most of the session I went to were really great. Also, I apologize in advance because this is just one giant post, as opposed to breaking it up by session which I usually do after conferences.
The first session was talking about ruby and government with Sarah Allen. She was recently a presidential innovation fellow and spoke a bit about the interesting things she was doing and the really interesting digital data issues that the Smithsonian system has. Sarah brought up some really interesting thoughts about rails in general. One of the most interesting (controversial?) things she talked about was making Rails more accessible. She talked about other platforms like Drupal or Wordpress and the ease of adding certain functionality or widgets there. These are things that Rails doesn’t have. It isn’t super accessible because you don't have the same sort of ability to add widgets or different features. Her point was that potentially being able to make it easier to add widgets would make us more effective programmers and that by doing this, we wouldn’t have to re-work things or add simple, commonly-requested functionality on a regular basis.
Her talk closed with three interesting points to think about. First, framework leads to language. Second, what if we could add UI features at runtime, and what would that look like? And third, non-developers are co-creators so how to we give them a more active role in rails.
The second talk was by Eileen Uchitelle and was about CRUD and ActiveRecord. I thought this talk was fantastic, although admittedly got a little lost in the middle. The premise of this talk was that when we assume activerecord is magic and does all these magical things, we end up not paying enough attention to our code and to the actual SQL queries and how they’re functioning. Eileen then went through an example using each of the CRUD methods (create, read, update, delete) and went through ways that the queries could be better, faster, and more effective. For example, in create, she spoke about batch insert and in read she talked about using pluck. Her slides are super clear and definitely worth a read.
The third session was Terence Lee speaking about working with Ruby. He spoke a lot about how to commit and encouraged everyone to get involved with fixing ruby, committing, and getting involved with the core team. I learned that .to_f is to float. Floating objects “represent inexact real numbers.” He talked about the future of ruby being focused on trust, transparency, and onboarding.
The fourth talk was given by Davy Stevenson on Ruby as science, art and craft. I thought this talk was really great and looked at code from different perspectives and points of view. She started with science, looking at algorithms and talking about what complexity looks like. Davy went through a variety of big O notation types like linear, quadratic, exponential, and factorial. She described an algorithm as a set of instructions that will solve a particular problem… a great definition for someone who isn’t a math person. She then looked at the convex hull problem and demonstrated different approaches through different algorithms that connect the points and show this convex hull in different ways. I won’t go into them here, but if you want to google them a bit further, she discussed brute force, gift wrapping, and monotone chain algorithms.
Then Davy talked about art. The art part was lots of imaged of different interpretations of art and thinking about them. The best part of that segment for me was a quote she mentioned from @sferik where he said that programming is about building powerful things in simple pieces.
Finally, Davy discussed craft taking the idea of apprenticeship and artisan abilities and connecting it to code. She said we write code to enrich our own lives and the lives of the people around us and then showed us examples of beautiful code. Definitely take a look at the slides to see what people consider as beautiful code.
After this was lightning talks!! There were a few talks… one on muscle driven development, which talked about health and treadmill desks. One on debugging, another on language and thinking about how the language we’re using shapes how we look at solutions. A fourth on Ruby For Good which is going to be awesome and everyone shold check out. The fifth was on the Angelo gem and the last talk was about how you shouldn’t do ops as a dev.
From here, we went into the tracks. Again, the talks today, I won’t do justice because I wasn’t focusing as much as I could/should have been but at hopefully I can provide some notes. The first session I went to was JohnPaul Ashenfelter’s Machine Learning talk. He did this at RailsConf as well (a longer version). It was really interesting. Basically, he spoke about different gems and things developers could use to learn more about the users. First, he talked about the sex machine gem which isn’t perfect but can help determine the gender assignment of your user base. Second, he discussed free geoip to show location awareness. After that, he got into clustering a bit and looking at clusters in order to help determine patterns. He walked through the ai4r gem which puts people into clusters and then calculates the centroid (centroid being the center of the random clusters) and finally, it loops through to see if users are closer to the center or their cluster or another cluster. This enables you to see what cluster people are in which is super helpful is your clusters show, for example, what tier users are paying for in your system. Alternatives to this can be hierarchical clusterers or divisive hierarchical clusterers. Finally, he talked about a gem called linalg and how you can use it for collaboration purposes (I think… my notes get a little sketchy here).
After that, I went to an ActiveRecord workshop with Dave Bock. This workshop is fantastic, but very hands on so not many notes. Basically, Dave has a handful of scenarios that each table has to discuss and talk about how they’d architect them. Really helpful for continuing to learn about ActiveRecord, associations, and modeling.
The next talks I went to was about tests and having a messy test suite. Presented by Chris Sexton and Aaron Kromer, this talk was great. They went through testing best practices and showed examples of clean, clear test structures. Some highlights were that you shouldn’t deeply nest state in your tests and you can fix this by creating contexts, this way the state is top level and you can test everything. Tests should help organize and expose state. Class declarations should tell what behaviors to test. Finally, the two most important pieces of advice were to prioritize what’s most important to test and then iterate towards that goal and make your tests better as you work towards your goal.
The last talk of the day was about sidekiq. I don’t have a ton of notes from this talk as well but presented by Mike Subelsky, it was a great walkthrough of sidekiq and what you can tell from the dashboard when running it.
I was able to pay more attention on day 2.
Day 2 started with Jim Gay talking about east-oriented code. This is a pretty cool concept that operates under the principle of tell, don’t ask. The core of it is that queries travel west and commands travel east. The talked touched on the law of Demeter and talked about east oriented code being different than that. There are four things to keep in mind with east oriented code. First, always return self. In this way the method is prevented from querying, can only tell. It leads to polymorphism, duck typing, and encapsulation. Second, factories are exempt form this. Third, always follow rule 1. And finally, sometimes break rule 3. After rule four, he showed a really interesting rails erb template that described this and walked through it. I left this talk sortof understanding everything but definitely would love to take a look at the code examples and slides in order to comprehend it all a little further.
The second talk I went to was on two programmers in one. I loved this talk by Jano Gonzalez. He talked about how each of us as developers are a little hacker and a little thinker. The hacker wants to get things done, and quickly which can sometimes lead to a maintenance nightmare. The thinker thinks about maintainability, abstractions and all the different layers but sometimes can get away from the problem that they’re trying to solve and can have analysis paralysis. He then told his story about going from hacker to thinker and coming to a good balance with both sides when using ruby. Jano spoke about how the hacker is useful for exploring new territory but the thinker is good from defining components and acceptance criteria. Developers need to deliver value but also diminish technical debt and it’s all about the balance between the two. My favorite part of the talk was when he spoke about the 3 stages of learning from Martial Arts. There is Shu, Ha, and Ri. Shu is when you’re new and you follow all the rules. Ha is when you move on and start adding your own knowledge and breaking some of the rules, and Ri is when there are no rules to follow and no rules to break, you just do it.
After that was a talk on google glass by Lance. This was a fun talk and one I just sat back and enjoyed since I’m not really developing with google glass but was just curious. Lance talked about apps as service layers. He then went on to discuss some of the glass specs, things that are great about glass and things that still need to be fixed. He then talked about the Mirror API, which I still have to check out, and how you don’t need to know android in order to program for glass. There’s a concept of static cards which add functionality and a new(?) tool called WearScript which is a bit like phonegap for glass.
Interesting talk and really fun to just see some of the programming side of glass.
Sam spoke about the anatomy of a mocked call which basically involved doing a deep dive into what a mocked call means technically with rspec, using their internal mocking library. He started by talking about testing and why you test/TDD. His main points were that TDD’ing helps programmers create a mental model. It helps them think through what the code does and then because things change as you program, it helps keep that mental model intact and keeps you on track with the problem you’re trying to solve. In short, tests force behavior.
The first part of this deep dive was discussing stubbing. Stubbing is basically faking a response to a method. Moching enables you to verify the collaborations between objects by testing the methods that get called. It creates a mocked expectation. so in the example
it “does something” do
expect(foo.bar).to eq (nil)
The allow is actually allow= allowanceTarget.new
allowanceTarget is a subclass of the TargetBase and calls delegate_to on TargetBase and, with a setup_allowance, TargetBase defines TO as an allowancetarget enabling .to to exist as a matcher.
Then there is receive which is also often used as a matcher. Once receive is set up as a matcher, similar to how to is set up as a matcher above, then receive#setup_allowance creates a mock proxy. A mock proxy is an object that manages the metadata of mocks and stubs on the object in the lifecyce of a test. Calling add_stub on this proxy sets up a emthod double which saves the original implementation. Then calling foo.bar (the stubbed implementation) sends a message to the method double which sends a message to the proxy which invokes the stub which returns a value (gosh, I hope I got that right!).
When you run a test, rspec also runs setup and teardown before and after the test and at the end of the test, the teardown resets everything. This reminds me a little bit of how testing work in ember with quint.
Okay, now onto mocks. For explaining mocking, sam worked through the same example but using expect(foo) instead or allow(foo). In this case, expect = ExpectationTarget.new and goes through a similar process as the stub did, except this time with a mock. Here, once you have the proxy, the proxy callbacks checks to make sure the arguments are valid and the proxy raises if a mock wasn’t called.
Finally, I can’t remember at what point sam mentioned this, but during his talk (or when someone asked a question about using spies instead of mocks), he mentioned spies so now I know what spies are! Spies are whenever you do a a stub, it will record the information so you can set an expectation at the end of your test instead of at the beginning. Basically, you can set a spy to collect all sorts of information from you and when the object returns you can ask it questions about it’s experience. The way I envision this is similar to what the Dorothy’s were trying to do in Twister. In Twister, the tornado chasers weren’t able to learn more about tornadoes because they weren’t able to see or understand what was happening inside the tornado. They came up with a way to release thousands of little sensors into the tornado to collect all the information and have them transmit the information back so it could be recorded and studying. From my understanding so far, this is similar to what spies do.
Evan is great. He’s got so much experience and his talk was on remote pair programming. Now, I work remotely, so I’m familiar with a lot of the tools, but his talk was less focused on tools like madeye, nitrous, and screen hero and more focused on command line tools. He spoke a lot about vim and emacs (which made me really want to learn vim again… one day I’ll get around to that). He also spoke about tmux, ssh’ing into machines, and a lot of really interesting concepts. He spoke about how his remote pairing stack has changed over the years and different combinations of things he’s tried which allows people to pick any of these tools and configure it to their remote pairing liking. Overall, an interesting talk and some exposure to remote tools I hadn’t thought about in the past.
Mark spoke about wyriki which is a project that Jim Weirich was working on when he passed away. I’m gonna be honest and say that Mark lost me pretty early in his explanation but this is what I got. Wyriki is a different way to architect rails applications. It creates new structures of runners in between controllers and models which allow someone to isolate the business logic from everything else. The rest of my notes on this are sparse and it’s pretty obvious I got lost in there, but I think the core takeaway was thinking about different ways to structure apps, so not fat model, skinny controller and not everything in moderation but how to really separates different types of business logic in your apps.
Next up was Justin’s talk on breaking up with your test suite. I took frantic notes on this one and listened intently, but eve so I’m sure I missed stuff. Also, these slides were great and super understandable so check them out. So first was talking about why we should test. there were 8 or 9 ultimate reasons why code should be tested which fall into two essential categories. First, you can gain confidence from the test and you can gain understanding of the code through the tests. BUT he started by discussing that we should question before we test. When thinking about tests, we should think about the purpose, rules, and structure and we should expect that within our test suite these three items should be immediately clear to anyone looking at it. If we cram lots of different goals and motivations into each test, the test becomes unclear. The rules become debatable, the purpose becomes hazy, and the structure ends up being ad hoc instead of uniform. Every test suite should promote one type of confidence and 1 type of understanding. So, here are some different suites and for each suite Justin went through the user, what the understanding and confidence were, tips, and warning signs.
First up was the safety suite. The safety suite is for the browser It checks does the app work and is our product simple. If the tests do not fit inside 30 minute or if you can’t write a new test within 30 minutes then your product probably isn’t simple. These tests shouldn’t see the internal apis. They should bind to what is visible by the user and they should enforce a fixed time-budget. The warnings here are that failure from refactors are often false negatives here and that human intuition overvalues realistic tests. On this type of test suite, numerous releases and branches can get expensive and there is the idea of the superlinear slowdown meaning that the bigger the system, the slower the tests.
Next comes consumption tests You should verify behavior and demonstrate usage with these types of tests. The user is the repo’s customer and they are used to verify what you, as the programmer, is directly responsible for. It says, is this code usable? If it’s hard to test, it’s probably hard to use. For these the module boundaries should be meaningful beyond testing (ie- these things talk to each other so they should be tested together). It should fake all the dependencies. It should exercise the public, not private apis. And finally, it should be organized by the consumer’s goals and outcomes. Warnings-wise, these tests need to be fast and this is the only part of the suite that tells you “you just broke something”.
The next tests suite are contract tests. Contract tests are used by us. They represent our interests that live in someone else’s repo. It leads to faster feedback making sure that something in the system that someone else is working on, doesn’t break something you’re working on. For these, they should be written for first party dependencies and follow the same rules as consumption tests. These are NOT a replacement for actually going and talking to your fellow dev about what they’re working on.
Next is TDD. So, so far, in all these tests suites, none have talked at all about the design of the code. The main value in TDD-ing is to discover tiny, consistent bit that help with big projects. The user is someone concerned with implementation details and the inputs and outcomes. These tests are a sounding board and enable you to have confidence in building small things and learning about what roles our code is playing. Here, he showed a cool chart that had interesting structural points related to putting queries on the left, logic in the middle and commands on the right… reminded me a bit of east-oriented code structures. He also stated that commands and queries should have very little logic. The warning here is that discovery tests yield small disposable units so be okay with throwing stuff away.
Next are adapter tests (whoever knew there could be so many different kinds of tests suites!) These tests exercise the adapter API under just realistic enough circumstances. It warns us of outages or API changes. These tests also reduce the cost of swapping dependencies later. For these, don’t test them first and trust the framework. These are similar to contrat tests but contract tests improve communication between colleagues whereas these tests improve the feedback between your code and the 3rd party code. Last warnings are that these tests can be slow and outside of your control and that they can be tricky if you’re using some sort of CI.
Phew! that was that talk.
One note is that my confusion still lies a bit in integrating all of these different types of tests. Should an apps test suite have all of these things? What does it look like structurally? Are they in the same files or different files? But I think the idea of thinking about all of these different suites and the goals of tests and testing is pretty cool.
Production code analysis by Dan was a great talk. Dan talked about code cleanup and how to look at a monorail (single large application) and refactor/delete effectively. You want to look at what code is being run to allow for good code cleanup and that lots of these monorails have dead code. Some overarching tips are to celebrate clean up commits as a team and to start by finding large unused code sections by finding unused actions. There are a handful of tools he talked about to help find this dead code. First you can use new relic which can show you for any given endpoint, how often is it being hit and then you can do a route check to see what routes are completely unused. You can also use tools like graphte, statsD and redis to find unused actions. For example, statsD is pretty easy to implement, has lots of info from Etsy’s blog, and can be used to see both timing and emdpoint information. You can look at background jobs in redis to see which jobs aren’t being triggered at all and what events are related to those jobs.
For mailer, you can see which is the most popular and least popular mailers by hooking statsD into active mailer. Finally, if you find the actions not being triggered, you can often delete the related views that aren’t being rendered any more.
Another good place to look is at translations. Which translations are in memory but aren’t being used anymore? Use the gem humperdink to track these translations. Finally, you may have two methods that are doing the same thing in your code. For this, learn which is best by wrapping the methods in a split. Wrapping them in a split and tracking them with statsD will tell you which method is faster or more effective and allow you to make data-driven decisions.
Lastly, Dan talked about logs. Logs are great for cleaning up code. Logs should be searchable and in one place. You should try to standardize the log format and multiple apps that communicate should be in the same system. Once you’ve got good logs, you can do log queries or check out endpoints to see what’s arriving to them. For this, check out the gem imprint.
Russ Olsen spoke about going to the moon! Wait for this talk to come out on video. I had to leave about 15 minutes early which was a bummer but he’s such a good storyteller, I was on the edge of my seat the whole time.