This is a series of reflections on the harshest falls I took learning Ruby and Rails over the course of the last few years. This first two issues tackle my stumbling with two very commonly spoken anecdotes, one about Ruby, the other about Rails.
The first common saying I will address is about Ruby and it is the notion that Ruby is easy to understand and pleasant to read. I saw this in many places, on the official site, on many a forum, and on conference talk videos. I even agreed with this notion initially from my first impressions of looking at programs written in Ruby. The problem for me lied in the fact that reading something and understanding something are two very different things.
Let's build some context. I graduated from university in 2022. This was also the time I decided to stick to a framework and language to reach more substance rather than project and framework hop from new thing to new thing. I had worked on projects in multiple languages before Java, Python, small assembly stuff, and of course Node.js. By far my favorite language was Python, but by far my favorite thing that I built was a web application in Node.js. The usability and ergonomics of writing python plus the ability to build web apps naturally brought me to Ruby and Rails. Then honestly I became a little obsessed. In the confusing ever changing world of web development where new frameworks released every few months, the tried and tested opinionated world of Rails felt like a nice cozy cradle. Not for too long though. There is more to speak on this subject, but for now I'll just say that a lot of the online infrastructure at the time I was learning Ruby and Rails was in decay (thankfully this is being addressed by the community and it's starting to really show!). This is some rough context on where this journey began.
Okay, so where did it all go awry? Well this is a problem familiar to newer developers in general that picked up the trade when I did. There are so many abstractions! Really, a ton of abstractions. A modern web application looks nothing like how it looked 20 years ago. Testing suites, back and front end split, CI/CD, cloud hosting, tons of DB options, server options, deployment strategies, and the endless stream of new frameworks, backend, frontend, all encompassing. Reading Ruby code that deals with all of this is particularly illusive because you don't really understand all that is going on from simple beautiful lines like:
User.includes(:posts).where(posts: { published: true }).order(created_at: :desc).limit(10)
# or
after_commit :reindex_user, on: :update
# or
expect { subject }.to change(User, :count).by(1)
Which all read greatly but have so much going on underneath.
Ruby is wonderful because it allows us to create our own vocabularies through metaprogramming and Domain specific languages. However if you combine this ability to expand vocabulary and you multiply it by a huge community and then by two decades of success. Well, by the end of it you might as well be speaking a different language. That is how it felt honestly. I would read Ruby code and understand it at a very basic level, but then it seemed like other people were reading the same code but getting much more out of it. This was because they were, and not just because they had more experience, but because Ruby itself is easy to read on a whole other level when you've been through the journey with Ruby. When people refer to Ruby being easy to read, I think it's something that has held true for those who have seen a significant part of the journey. There is familiarity and foundation there, so there is much experience to pick up on. For me at the start of my journey at that point in time however, there was just so much magic that while everyone insisted it was easy to read, it didn't feel that way. Certainly people refer to the cleanliness of the syntax when the speak about readability as well, but with all the changes ruby had gone through in the last decades, syntactic complexity was also introduced. So while Java is ugly, you look at the layers of it and can from the onset have a rough idea of what you are looking at. Ruby on the other hand sometimes proved to be pretty on the outside, but hiding away very valuable information. As mentioned before, there is syntactic sugar that has been added that I have come to appreciate, but at the time it only further confused me. I would look for guidance on a forum and had two solutions to the same problem (hashes!). This is something I have grown to love about Ruby and I am now aware it is the feature of Principle of Least Surprise. At the time there were many surprises however. Also some of the syntax I saw was solving problems I had never encountered before. For someone starting out, it's added complexity, more to memorize. The outcome of all this is easy to read, hard to understand problem was that I built a really cool project with Rails really fast, and thought I understood what was going on. I was really happy until I wanted to change something. Then I realized there was a lot more going on than I understood and could even perceive. I added cool gems for a calendar, users, pagination, a frontend CSS framework. But it took forever to change anything, and especially long to change anything in a meaningful way. Worse, when I changed things I didn't even fully understand why things worked when they did. Yes I did run into multiple working answers. The available answers diminished faster and faster as my app grew in complexity and I was inheriting architecture I didn't understand, but could read. Bugs, the bugs! Ruby is great, but not even now do I think it's fun to debug. I could read my application, but I could hardly change it. I could read the errors, but I didn't understand why they occurred.
So how did I get out of such a mess? It took a multi pronged approach. First I just dedicated more and consistent energy to Ruby alone. All the abstractions in a Rails app are in themselves important, but all made up of the same building blocks of Ruby (pun intended). This is a habit that started then and has yet to stop, it continues to pay off to know the Ruby Object Model, Ruby idioms, and how certain Design Patterns look in Ruby. This slowly helps over time. This is advice that everyone gives you, but that I felt pressured to and chose to ignore due to market demands. A web app you don't understand is more impressive to recruiters than a nicely written pure Ruby script you meticulously crafted. Second, I decided I needed to learn Ruby and Rail's histories. I have found it really helpful to know what period in time a piece of syntax was introduced, as it points to the frustrations of the time. With this in mind I better know when to utilize the context. Similarly, when building rails apps from then on forward I decided to generally check when a module was added. Asset compilation, API architecture, caching, CI/CD, testing. There are solutions present for all listed in Rails, but when they were introduced and why, matters greatly. Gems also have to fit into a specific context and be maintained. To know where these abstractions fit into the whole, helped greatly with deciding when to dig deeper and knowing where to go next for more information. Thirdly, learning to navigate the Ruby ecosystem. How gems work, where projects are hosted, where to find solutions, how to find if they've been maintained, learning resources, blogs, organizations. All of the above strategies and resources proved valuable in building knowledge and context that added new dimensions to the simple to read lines of Ruby. It was like the difference between hearing Shakespeare for the first time, where his work sounds pleasant and is undeniably stylish and coherent, and then hearing Shakespeare with the context of the time period. With the knowledge of his other works, his contemporaries, and those who he has come to inspire. With knowledge of the beauty in works you enjoy now that can be traced back to him. With knowledge of the before and after. It's the sound of Shakespeare after you realize all that he is actually doing. It's not just rhymes, the work has a specific structure, while being funny and telling a story, while being new. Ruby is easy to read in that it looks nice sure, but Ruby is easy to read in that it allows you to communicate intent at a precise moment. It allows you to setup a table with specific tools for a fellow developer to execute the task at hand with ergonomic ease. All that intent is not literally in the code, but it is evident when you place the code within the ecosystem of Ruby. That intent, those extra layers, they are not easy to read unless you've been a part of the journey. So I got acquainted with the journey, and I suggest that we recommend to every new developer that they do too. I also think we should consider it as essential as I found it in learning Ruby and Rails.
I already hinted a bit at what I feel may be a solution. Here's two though. The first and simplest is adding the following nearby when saying that Ruby is easy to read.
Ruby is simple in appearance, but is very complex inside, just like our human body
That's from Matz himself. It is much harder to find, but boy is it true and extremely relevant. Let's not shy away from this fact. No, it won't push away newcomers, not more than being hit with tons of Ruby magic. I would have had a more pleasant time had I known that the process was indeed meant to feel complex because it was. Imposter syndrome in the beginning is also at an all time high and it doesn't help to keep hearing that Ruby is meant to be easy to read all the time, without also hearing that it is hard to be understood. That phrase deserves more prominence. Second solution is some sort of external material on the the history of Ruby and also something for Rails at this point. It can simply be a timeline kind of deal with hyperlinks and information, but Ruby feels too big to just be a collection of resources. The lived timeline of developers is important for them navigating the ecosystem and having that externalized could be of great value to newcomers. Additionally I personally believe there is a market for a book about Ruby's history so far. Believe it or not, simply having lived through what a lot of seasoned Ruby devs lived through is valuable information. You get a hint of this with mini documentaries from YouTube channels like Cultrepo. Even if there's not a sole monetary incentive, there is incentive from a community building standpoint. It's something I would consider doing if I felt just a bit more qualified to do it, although I know I would never feel completely ready.
I hope you have enjoyed reading this blog post. There is more to come on this series. Up next I'll handle the Rails statement of "Rails is productive". I'm sure you have an inkling of where I am going with this having read this article, but I hope you still join me for the next one.
Feel free to share some of your struggles when picking up Ruby and or Rails.
Top comments (0)