Show Notes
02:30 - Noah Gibbs Introduction
- GitHub
- Blog
- Ruby Rogues Episode #199: Deployments with Noah Gibbs
- Rebuilding Rails by Noah Gibbs
- Rails Deploy In An Hour Class
03:03 - Structure
03:44 - Guiding People Through the Magic
- Special-Purpose Tools: The Good and the Bad
06:55 - The Origins of Rebuilding Rails by Noah Gibbs
07:55 - The Practice of Code Reading
09:19 - Getting Started Rebuilding Rails
- Frameworks
- The Core Functionality of Rack
15:09 - Use Case for Rebuilding Rails
19:49 - View Model Objects (Presenter Objects?)
24:25 - What Do Rails Devs Take For Granted?
- Rack
- Security
27:59 - Rails = âWeirdâ ??
32:48 - Rails Expectations
- When Itâs Time for Separation
- Rails Programmers
37:56 - Constraints: Making Framework Decisions
44:19 - Big Data
- Designing Data-Intensive Applications The Big Ideas Behind Reliable, Scalable, and Maintainable Systems By Martin Kleppmann
- Aphyr (Jepsen)
Picks
simplehuman Garbage Cans (Avdi)
Etsy CTO On Its Conservatively Crafty Tech Philosophy (Saron)
Death Of A Programmer. Life Of A Farmer. (Saron)
Mary Poppendieck's Keynote (Jessica)
Ruby Remote Conf (Chuck)
Rails Camp USA West Coast (Chuck)
Traction: Get a Grip on Your Business by Gino Wickman (Chuck)
Rails Camps (Coraline)
The Codeless Code (Noah)
Ruby Under a Microscope: An Illustrated Guide to Ruby Internals by Pat Shaughnessy (Noah)
The Rails 4 Way by Obie Fernandez (Noah)
Etsy CTO On Its Conservatively Crafty Tech Philosophy (Saron)
Death Of A Programmer. Life Of A Farmer. (Saron)
Mary Poppendieck's Keynote (Jessica)
Ruby Remote Conf (Chuck)
Rails Camp USA West Coast (Chuck)
Traction: Get a Grip on Your Business by Gino Wickman (Chuck)
Rails Camps (Coraline)
The Codeless Code (Noah)
Ruby Under a Microscope: An Illustrated Guide to Ruby Internals by Pat Shaughnessy (Noah)
The Rails 4 Way by Obie Fernandez (Noah)
Special Guest: Noah Gibbs.
Transcript
CORALINE:
Thereâs nothing like rum drinks in a rainbow painted playhouse.
NOAH:
Absolutely true. It has the advantage that I can head up there and scandalize the neighbors by drinking 10 feet in the air.
[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on Ruby developers, providing them with salary and equity upfront. The average Ruby developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. Itâs totally free for users. And when youâre hired, they also give you a $2,000 signing bonus as a thank you for using them. But if you use the Ruby Rogues link, youâll get a $4,000 bonus instead. Finally, if youâre not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/RubyRogues.]
[This episode is sponsored by Codeship.com. Donât you wish you could simply deploy your code every time your tests pass? Wouldnât it be nice if it were tied into a nice continuous integration system? Thatâs Codeship. They run your code. If all your tests pass, they deploy your code automatically. For fuss-free continuous delivery, check them out at Codeship.com, continuous delivery made simple.]
[Snap is a hosted CI and continuous delivery that is simple and intuitive. Snapâs deployment pipelines deliver fast feedback and can push healthy builds to multiple environments automatically or on demand. Snap integrates deeply with GitHub and has great support for different languages, data stores, and testing frameworks. Snap deploys your application to cloud services like Heroku, Digital Ocean, AWS, and many more. Try Snap for free. Sign up at SnapCI.com/RubyRogues.]
[This episode is sponsored by DigitalOcean. DigitalOcean is the provider I use to host all of my creations. All the shows are hosted there along with any other projects I come up with. Their user interface is simple and easy to use. Their support is excellent, and their VPSâs are backed on Solid State Drives and are fast and responsive. Check them out at DigitalOcean.com. If you use the code RubyRogues youâll get a $10 credit.]
CHUCK:
Hey everybody and welcome to episode 207 of the Ruby Rogues Podcast. This week on our panel, we have Jessica Kerr.
JESSICA:
Good morning.
CHUCK:
Coraline Ada Ehmke.
CORALINE:
Hello.
CHUCK:
Avdi Grimm.
AVDI:
Hello from Tennessee.
CHUCK:
Iâm Charles Max Wood from DevChat.tv. And this week we have a special guest, Noah Gibbs.
NOAH:
Hey. Good to be here.
CHUCK:
Yeah, we had you on a few weeks ago. But do you want to introduce yourself anyway?
NOAH:
Sure. So, I wrote a book called âRebuilding Railsâ about understanding some of the tradeoffs in Ruby on Rails by building your own framework structured the same way. So, itâs sort of the âunderstand the internals but necessarily all the APIsâ. And you had me on a few weeks ago to talk about deployment because Iâm also teaching a class called âRails Deploy in an Hourâ, which is basically a quick setup with all the tools you normally want to use for deployment. Chef, Capistrano, stuff like that. But I just give you all the code and initial setup instead of making you work through all the systems.
CHUCK:
Got it. Iâm kind of curious to get this started. Did you build things the same way that theyâre built in Rails or did you explore different ways of doing the same things that we have in Rails?
NOAH:
Mostly I tried to keep the structure the same because a lot of what Iâm doing is trying to show why Rails does it the way that it does.
CHUCK:
Okay. And so, it comes out as a guided tour through Ruby metaprogramming. Because a lot of Rails is structured around the way Ruby lets you do it. I talk a little about other ways to do things. But primarily, itâs once you understand how the metaprogramming thatâs available works, itâs obvious what the tradeoffs are with Rails. Not everythingâs like that. There are a few things that I structure a bit like Sinatra, especially say, my early routing.
CORALINE:
So, is part of your goal to dispel the idea that Rails is too magical?
NOAH:
Part of it is to guide people through the magic. I think dispel the idea is a little bit strong. My experience is that if you teach people deeply about metaprogramming they either decide, âOh, this isnât magical at all,â and they love it and they dive in, or they look at this and they go, âWow, this is horrible now that I understand how it actually works.â
CHUCK:
[Chuckles]
NOAH:
And they pull farther back out. Iâm a big fan of special purpose tools. A given tool is usually really useful in some cases and not others. And I find that just by showing people all the details of how this metaprogramming stuff works, yeah most people tend to either really dive into the tool or really pull back from it. So, dispel the idea is a bit strong. Itâs totally possible to come through my book hating all the stuff Rails does instead of loving it. But at least youâll hate it in an educated way. [Chuckles]
CHUCK:
I like that.
NOAH:
I love it, of course. I wrote a book on it. But yeah, itâs not for everybody. One of the joys of this explosion of server tools weâve got and all the users donât have to have all your stuff installed is we can just use tools that are not appropriate for every situation as long as we pick the right ones. So, thatâs always been my focus, is Iâm going to show you this special purpose tool that is really good in these cases and then tell you what cases I think itâs good for.
JESSICA:
And which cases you think itâs bad for?
NOAH:
Yeah. Sometimes explicitly, sometimes by implication. But if you mean what tools do I think Rails is bad for? Just off the top of my head, itâs not the best thing in the world for building an API, and Iâm still looking at the Rails 5 modifications. But the fact that theyâre adding a whole bunch of stuff to make it good for APIs means theyâve noticed that itâs not perfect for that. The magic and the amount of structure that itâs got means that itâs not amazing for high performance. It also means that if youâre doing something simple enough that Rails doesnât help you much it complicates debugging, having those extra layers. So, mostly Rails is not as good for really simple cases, API sort of cases, high-performance cases.
CORALINE:
That doesnât leave very much.
CHUCK:
[Laughs]
NOAH:
It leaves a lot. It leaves a lot. So, one thing that itâs really good for is a small team throwing up a website that will be used by human beings using HTML in a hurry. And it turns out, thatâs nearly every startup. And the reason itâs good for that is because your framework can do a certain amount for you security-wise. And Rails does about as much as any framework can do. Even in say Rails 4 they were still adding new things that gave you much better security by default. And then theyâve got the Rails Security Guide which does a really good job of explaining what they canât do for you.
One thing that I think is underrated is that if youâve got a small team that is putting stuff together in a hurry and theyâre going to be kind of sloppy, a somewhat sloppy, built in a hurry Rails site is going to be more secure than almost any other sloppy, built in a hurry site you can do. And then you can further secure it when youâve got the time. But itâs going to come out less horrible security-wise when theyâve done that.
And nothing stops you from putting an API server beside it. Nothing stops you from building you API in Sinatra quickly, building your app in Rails quickly, and given the Rails routing system you can do that in a massive hurry. One of the things I explore in the book and talk about is how Rack is used all the way up and down the Rails stack. And so, if youâve got a Rack app, like say a Sinatra app, itâs really easy to shove that directly in your routing table. Itâs really easy to just route certain requests to it. And soâŠ
AVDI:
Iâm curious about the origins of this book of yours. I hear from a lot of people a lot of, particularly first time authors, that they wrote something because they wanted to understand it better. Is that part of your motivation here?
NOAH:
Thatâs a little of my motivation. What I really did here was I wrote the book I wish I had had. So, Iâve had a 10 to 15-year career in C and C++ and systems programming, deep down in the bit stuff, and hadnât done a lot of web programming when I came to Ruby on Rails. And so, what I thought was missing when I got there was a book that assumed somebody understood programming pretty well but didnât necessarily know the stuff that was specific to Ruby and really didnât know the stuff that was specific to Rails. And so, taking that apart layer by layer was exactly what I wish I could have done right when I started. I did all that on my own before I wrote the book. But the book was my way of handing that knowledge to somebody else the same way I had to do it for myself.
AVDI:
Something weâve talked about on this show before is the practice of code reading. Iâm curious. How did you go about learning everything you needed to know to understand how Rails works?
NOAH:
Sure. So, I was as I said a C and C++ guy for a long time. Iâve always been a pretty fast code reader. And when it takes hundreds or thousands of lines to do anything interesting, you get pretty good at seeing the overall structures but stopping when somethingâs complicated or interesting or looks bad to really drill into it. So, this will sound worse than I mean it, but in some ways reading Ruby code feels like preschool posters to me. Thereâs just so little there. And itâs so easy to read it all that I can analyze it pretty deeply while barely having to pause. C code is just harder to read [chuckles] for a given amount of functionality, because thereâs so much more of it to do the same thing.
And so, I was used to if Iâm going to read code, sit down for hours, plan to go deep into these weird special cases. And mostly Ruby code just works better and reads easier. And of course, the Rails codebase is very clean. Itâs extensively peer reviewed. Itâs really well put together. They rewrite little chunks of it all the time. Thereâs the whole bug database. If thereâs something youâre curious about, you can go back through the GitHub history and you can get the annotations and you can search through their Pivotal Tracker. Compared to any C codebase I have ever read, the Rails codebase is like literature.
CHUCK:
So, if somebody wants to jump in and rebuild Rails or build their own web framework, where do they get started?
NOAH:
So, there are a couple of places you can get started. I began with just making a second library so that you have an app, just making a miniature framework. Itâs not big. You can do that in 20 or 30 lines or less. But controllers are probably the next thing. You can render the text in the controller instead of having a view if you want to. So, you can cut off the views that way. Itâs really easy to just not call the models and so you can cut off the models there. Iâm not saying thatâs best practices and you should always do that. But if what you want is the smallest little lib framework that you can get, controllers are a good place to start.
And then the next thing is probably views. You can implement a controller framework in 15 or less lines, depending on what you want. You can implement a view framework in a similarly small number of lines. ERB is built right into Ruby these days and Erubis is really easy to use. Most of what surprised me as I was building this was how small the smallest version of each of these things can be, how small your simple view framework can be. Iâve got a talk I give called something like âThe Five-Minute Ruby Web Frameworkâ. And itâs literally a 13-line mini Sinatra. It only supports GET. But you can write the Sinatra style routing language in under 15 lines easily.
AVDI:
I think a lot of people see something like that and they think, âSo, what is the rest of this cruft?â
NOAH:
Yeah. And sometimes thatâs a fair question. I will say that Sinatra itself is kind of dirty in internal structure. I had the good fortune to work with the folks at OnLive until recently. The company sank. But I built a custom Ruby framework on top of Sinatra. We did some really interesting things there and we did at least manage to open source that. But one of the problems we persistently had is that Sinatra is structured a little bit weird. And so, if you want to replace parts of it or hook into it, itâs hard to do. Thatâs not always a criticism. Sometimes a framework is just very self-contained. Itâs not designed for hooks. But Sinatra is structured a little weirdly in several ways.
If you want to build on top of a framework Iâm told the Cuba framework is a much better place to start, just because itâs smaller, not structured in quite the same way, and itâs basically designed to be hooked into in the way that Sinatra is not.
CORALINE:
Have you looked at the Lotus framework at all?
NOAH:
No. I have never looked at the Lotus framework.
CORALINE:
Itâs supposed to be a lot more modular.
NOAH:
That makes a lot of sense. Yeah, Sinatra is not at all modular. Sinatra is definitely not built to be taken apart. So, what I would say with Sinatra is that if youâre looking for a framework at that level, you can build a very simple framework on top of Rack. I think some of the cruft in Sinatra, some of the additional line count, is because Rack was not as good when they started. Rack has grown upward as the frameworks have grown downward, to take over more and more of the functionality. One of the things Iâve found in Rails repeatedly was it was surprising how much interesting deep Rails functionality was entirely handed over to Rack, as it couldnât have been in much earlier versions. So, things like cookies and sessions and how they track that stuff, Rack does the vast majority of that at this point. And it didnât originally.
CORALINE:
Can you talk about what the core functionality [is]?
NOAH:
The core functionality of Rack?
CORALINE:
Yeah.
NOAH:
Okay, sure. So, I usually start by saying Rack is the Ruby equivalent of CGI with as you would hope for from the Ruby equivalent of CGI. It is a compatibility library over all of the different application servers for serving requests, for returning responses, and for the things that most web interfaces are going to want to do. So, sessions and cookies and parsing the things from the environment, the same things that would be passed in CGI environment variables like what domain youâre serving, and whetherâŠ
JESSICA:
Can you define CGI?
NOAH:
Oh, Iâm sorry. CGI [chuckles] Iâm an old C programmer. I take too many things for granted there. CGI which stands for Common Gateway Interface, is the interface that a web server provides to whatever program itâs running to serve the request. Itâs a way to write a little program that is not itself a web server that serves web requests. If you are running PHP or youâre running a C compiled program or something like that, the web server is going to call that program and itâs going to set a bunch of environment variables to send in the information about that request. And then it will receive output from the program. And so, CGI is an API for web requests to run an external program. There are much more complex interfaces than CGI these days. But CGI is sort of the granddaddy of them. But that is the API that your web server is using and passing to your program to serve that web request.
And so, Rack is like that. Rack is the API that your Ruby program uses. And because all of the different Ruby application servers have all implemented the same standard, Rack, it turns out that you can, no matter which app server youâre using, be sure that you can write the lowest level Ruby program that can talk to any of them. So, Unicorn and Thin and Puma and Passenger all implement the same API for web requests.
Obviously you could just write a free standing web server. It is entirely possible to write a little Ruby program that talks directly to Apache or that just opens a TCP socket and serves web requests directly. But you wouldnât ordinarily do that because youâve got this, the application server is already written directly or already written. Itâs a lot easier to just write a program that knows how to serve a web request but doesnât know how to do all the very lowest level web stuff. You donât want to necessarily rewrite that code yourself as much for correctness as anything else.
SARON:
So, Iâm jumping in a little late. So, forgive me if youâve already answered this question.
NOAH:
Please.
SARON:
But Iâm wondering. What is the use case for âRebuilding Railsâ? If Iâm picking between different frameworks that to me is a decision weâve definitely talked about many times on Ruby Rogues. But rebuilding a framework seems like a much bigger mountain to climb potentially, especially if you havenât done that before.
NOAH:
Yeah.
SARON:
What is the right situation when you would do that?
NOAH:
So, the primary reason I wrote the book is that I was coming from being a programmer but not a web programmer, in a different language. And a lot of the tradeoffs in frameworks seem weird when youâre coming from that level. For instance, I donât know if youâve looked into how Rails does automatic requires for instance. But thatâs a great example of a subtle functionality where when it breaks, itâs not clear why it breaks, to a programmer who hasnât looked into the internals of it. Once you understand what the Ruby metaprogramming underneath it looks like, itâs completely clear why it breaks and itâs completely clear most of what theyâre doing. But until youâve seen how itâs built it never really fully makes sense.
A lot of what âRebuilding Railsâ for is to understand those tradeoffs and to be able to debug them. A lot of Rails seems extremely magical until youâve seen how itâs built. And in some ways itâll still seem magical after you know how itâs built. But youâll know a lot more about how the magic works.
CHUCK:
I just want to point out that you said that coming from outside of web development into web development, that yeah itâs hard to understand these tradeoffs. And then you went to a tradeoff that I donât think most people talk about when theyâre talking about the tradeoffs between the frameworks. Generally what weâre talking about is the APIs that we have to use, not the internals of the framework itself. And so, the automatic require is something that I donât think most web developers even think about when theyâre doing Rails. And so, I just thought it was interesting that you went there instead of say, well the routing or the asset pipeline or the way that you handle certain types of requests.
NOAH:
Absolutely. So, I would say that like most large frameworks, Rails is a combination of those two things. And itâs hard to tease apart. You canât say I want Rails but I donât want to do the automatic require thing for instance. Itâs getting better about some of the pieces being separable. But at the top level itâs everything all the way down. If you want to separate it the first thing you do is scrape the top level off, like you can just use Active Support or you can just use Active Record. So yeah, to me those are the same kind of tradeoff. But I agree, a lot of it is not exactly web related. Rails is both a programming model and happens to also be used for a web server, if that makes sense.
The programming model is interesting. Avdi for instance has written a book on why thatâs not perfect for large projects. And I think heâs right on that. Iâve always been a fan of the idea that Rails is a wonderful frontend framework but is clearly structured around fielding individual requests. Once you get to the point of having a longstanding service that wants to keep doing things Rails is a terrible pattern for that. And you should separate that out of your Rails codebase and into a second codebase sitting next to it. But yeah, so Rails is both of those.
The web patterns are interesting. But I would say that most of the web patterns rather than the programming model patterns are not quite as weird. Theyâre a little weird if you look at how controllers pass variables to views for instance. Thatâs something that feels really natural to a novice when they use it. But the implementation isnât necessarily obvious unless youâve seen how Ruby does metaprogramming and then itâs obvious again. So, thatâs nice because that actually feels a lot less magical when youâre done. Oh look, I can get a list of instance variables. Oh, I can turn that into a hash table. Oh, I can pass that hash table through and set it as variables. Until you realize that thatâs a pretty standard Ruby thing to do, it looks like magic. And as soon as you realize Ruby does that, itâs not magic anymore. Thatâs less of a tradeoff. Thatâs actually one where I wish I had explored the tradeoff more in âRebuilding Railsâ.
Have you seen the gem called decent_exposure?
CHUCK:
I think Iâve heard of it.
NOAH:
Okay. I found out about it because Obie Fernandez mentions it in âThe Rails Wayâ. Itâs interesting because instead of⊠it tries to replace the model of passing instance variables through as much as possible. And what you do is you declare a sort of view method where you say, hereâs the method name, hereâs how you generate it if it gets called. Then go ahead and do this. But the idea is that the controller defines pieces of data that the view will have access to. And instead of setting them into a variable it makes a method thatâs callable on demand usually by a bunch of different view methods. And so, the controller actions mostly go away. As much as you can you make the controller actions go away. And itâs not a response to the request as much as itâs a set of pieces of information the view can have and things the request sets as parameters are how that gets looked up. Itâs a very functional programming way to look at it. Iâm not doing an amazing job describing it.
It actually looks very natural when itâs done right.
AVDI:
Iâm curious how you feel that approach compares to an approach that Iâve seen advocated more recently, which is to try to just instantiate a single view model type object. So basically, a controller besides for the built-in variables, a controller is going to just be setting one instance variable and passing that down to the view. And that instance variable refers to a view model object which has everything else that the view might possibly need.
NOAH:
Is this pretty much the same thing as a presenter object? This sounds like a presenter object. But I might be misunderstanding.
AVDI:
It could be. I think they could be considered related. In my experience presenters know a bit more about formatting.
NOAH:
Mm, okay.
AVDI:
About translating data into HTML. A view model is really more about, here is the collection of information that the views might possibly need. But there are also form objects that are similar to this.
NOAH:
So, Iâm a little lukewarm on the view model object stuff that Iâve seen. Iâm probably out of date. I remember, itâs always been the goal that your controller will set a single instance variable thatâs passed to the view. Thatâs been part of style guides for Rails for certainly three or four years, and probably longer. I find that very often the views that I produce need to know several things about objects that are not necessarily related to each other.
So, to admit bias here Iâm mostly an analytics guy. And so, a lot of what I build in Rails are analytics dashboards. And an analytics dashboard is very often, hereâs a bunch of different graphs, show a bunch of things about those graphs. And I can make them single object really easily by breaking it into a bunch of independent Ajax requests. But then Iâm making decisions that have latency implications in order to keep my code clean. And to me that always feels, I donât know, weird. If clean code is making my overall performance substantially slower, I usually treat that as a smell in my methodology.
So, the idea of just combining these multiple otherwise unrelated things into one object so that I can package it and pass it to the view, I donât know, to me thatâs not a win. Putting it in a single⊠itâs like if you had a single app data object and you just shoved everything into the app data object, pushed it through, and then pulled it out of the app data object instead of using instance variables. You could do it. Thereâs nothing especially wrong with it. But itâs taking something that Rails does really well and getting rid of it.
CHUCK:
Yeah, usually what Iâve seen is you essentially have this view model which you can think of as a presenter thatâs mostly about the entire view.
NOAH:
Yeah.
CHUCK:
Iâve seen presenters where itâs a presenter for a particular piece of the view.
NOAH:
True.
CHUCK:
And so, this is generalized across the entire view. So, itâs not just a container that has all the information in there. And yes, you could do all of this with the instance variables or at variables, or whatever you want to call them. But basically itâs then intelligent enough to say, okay I want the userâs name so instead of doing presenter.user.name, you just presenter.users_name and have it work out that way. And so, you can put a little bit more logic and tune it a little bit more toward what data needs to show up there.
NOAH:
Yeah.
CHUCK:
And I think we talked about a similar pattern last week when we talked about Trailblazer, as part of what it does. But yeah, thereâs a lot of, I think you really when you were talking about frameworks I think the same thing applies with a lot of these approaches. There are tradeoffs. And it may work out better for you or it may not.
NOAH:
One of the things I like about presenter objects is that very often itâs not clear if particular logic is business logic or visual logic, view type logic. And sometimes the distinction between, this is business logic that belongs in a model versus this is formatting logic that belongs in a view, is really blurry, is very, very blurry. And so, a presenter gives a unified place to put both of those. A presenter is allowed to have business logic as long as itâs about how you lay out something the UI is showing. And so, I see a lot of value in unifying the model logic with the helper logic in that way. I
see a lot less value in making sure that there is one object that has everything the view is going to use passed through. I may be missing it. Itâs totally possible that itâs a tradeoff or just that itâs a solution to a problem I donât usually have that absolutely happens. But I will say I havenât found a problem the shape of that solution.
CHUCK:
I want to go back into the framework design and Rails, how Rails is set up. Iâm curious. What are things in Rails that we take for granted, or most Rails developers take for granted that they donât even realize the framework is doing for or to them?
NOAH:
Sure. So, Rack is the big thing I wind up talking to people about here. Rack is interesting because itâs not only the lowest level interface, itâs also an intermediate interface. You can have what are called Rack middlewares. I like to think of them as like pancakes because you can build an app out of a stack of them. But the request can be processed on the way it. It can be fielded by the middleware. It can have parameters changed. It can just be passed straight through with no modifications. And then once the app has handled it, it can also filter it on the way out.
So, youâve got simple middlewares like say, add a content type to the headers, or youâve got middleware for things like do basic HTTP authentication and if the password doesnât match then just donât let it through to the app. Rails already builds a giant middleware stack. I think itâs on the order of 20 pieces of middleware for most configurations at this point. And thatâs just getting down to the Rails layers. Thatâs not counting the stuff that is effectively Rack middleware but isnât necessarily registered with Rack in the same way.
And so, routing is the same thing as Rack. What I mean by that is what the frameworkâs doing for you is itâs routing all the Rack middleware stuff for you down to the routing layer. And then in the routing layer everything is made of Rack apps. And so, the big thing Rails is doing for you that is really powerful if you know how to use it and you donât necessarily know it, is building the whole stack out of the same pieces with the same API all the way up and down. If you want to insert your own Rack middleware into the middle, it turns out thereâs a really easy way to do that.
If you want to bypass large chunks of Rails, things like on this particular request at this particular path I donât want to use the whole routing layer. I just want to skip all of the Rails overhead for that request and skip all the Rails processing for that request, and hereâs my little Rack app that will process that. By the way it always returns this string. You can just do that. The Rails controllers and every controller action is a full on Rack app. You can use them anywhere you could use a Rack app. But the controllers also have their own built-in Rack app stacks as well. So, theyâve basically got their own layer just like your app server provides for you. And so, I think Rack is probably the biggest thing of that kind that you donât realize the framework provides you.
There are several other good ones. We talked about security a little. And Iâm not going to be able to go over all of it. Itâs a broad topic with a lot of interesting deep implications. But in the same way, thatâs one that the framework provides you. And if everything goes right, youâll never see it. [Chuckles] Rack is the same way. Until you need the power you should never need to worry about it. But once you do need the power, you wind up asking a question, look on Stack Overflow, and one of the first things people say is, âOh, well you can fix that by putting a piece of Rack middleware and hereâs how you insert Rack middleware at that layer.â
CORALINE:
So, youâre describing a Rails app as a stack instead of a typical [MVC].
SARON:
It sounds like sheâs trying to say MVC framework.
NOAH:
Ah, okay.
CORALINE:
Yes.
NOAH:
Thank you. Yes. So, a Rails app is both of those things. But the MVC framework is buried under a number of layers in the stack and has additional layers in the stack through the whole controller layer. And so, the controller layer especially but also sort of wrapped around that MVC stack, you have this stack of Rack middleware. So, I would say that it is still an MVC stack. But itâs kind of an MVC stack buried in these layers. And with the whole C part of that, composed of these layers. So yeah, both.
SARON:
Youâve described a lot of what youâve seen about Rails to be weird. And Iâm wondering. What is the weirdest and strangest most surprising thing that youâve discovered?
NOAH:
Wow. Well, when I realized every controller implemented its own Rack stack, that was up there. That was definitely part of it. Whatâs the weirdest thing Iâve discovered in Rails? There are also some fairly strange things in Active Record. But theyâre not⊠I donât know, itâs not like Ripleyâs Believe it or Not weird. Itâs just, âWow, why did they decide to do that that way?â weird. Active Record keeps reminding me that SQL is not a standard and really never has been. [Chuckles]
SARON:
What do you mean by weird? Is it just the background and expectations? Or how do you define weird in this context?
NOAH:
Sure. I usually say that what makes a tool a good match for you or not in a lot of cases is your taste, which in turn is your previous expectations. One of the things I loved about Rails is that it just feels right to me. Ruby and Rails were both like this. When I reach for a tool or an API, itâs usually there. I canât always immediately find it. But if I look for something that should be there, usually it is there. Whatâs interesting is that Rails has a layer like that, that feels utterly natural. And Ruby has a layer like that, that feels utterly natural. When I look for a particular API itâs usually there. And itâs implemented with a bizarre series of hacks that clearly were, âWe know what we want it to look like on top. And weâll do anything necessary to make it happen on the bottom.â
This is how I feel about, say the automatic constant loading. Because the way they make that work is, âOh, well weâll use directory names. And the directory names will all just work, even though some of them are lowercase with underscores and some of them are uppercase with mixed caps.â And there are a lot of things like that where the effect is utterly natural. You reach for the thing and itâs there. But once you think about the implementation, your first response is âEw. Ah. They did itâŠwell, I guess youâd have to do it that way. But really?â
Thatâs part of the reason that I say Rails is also a programming model. They need an enormous standard library to do some of these tricks. Like the fact that you have to tell Rails how you make certain words plural or not so that it can successfully turn your singular words into plural words for a database entry. And so, you have to decide how you want to make the word octopus plural, things like that, which is necessary for what itâs doing. If you have a model called octopus then you have to decide if itâs octopi or octopodes or octopuses or something else, because youâre going to be reaching for that database table. And Rails is going to pluralize it however you say to. [Chuckles] Octopods, says Avdi. Yes. [Chuckles]
SARON:
I wonder how often that happens. Is that a problem thatâs unique to Rails? Or is that just a side effect of trying to make something feel so natural and so obvious that the internals almost have to be a mess. Is that usually how it works?
NOAH:
So, Iâll again show my bias here. I was a C programmer and a systems programmer for a very long time. And the way that that usually works out in that world is that the codebase is so huge and itâs so hard to get an overview of it that they try to keep it internally consistent at the lowest level, because the lowest level is most of what you can see. Many of these kinds of cleverness are considered are serious code smell in that world, because the projects are so big you know one person canât keep the whole thing in their head.
Ruby is very different from that, because very often one person has a serious overview of it. Thereâs just a lot less code in the same amount of functionality, which is wonderful. But it means that a lot of these kinds of being friendly and making sense and being structured like you expect and being structured sort of like English are possible. It didnât use to be possible. And so, the way that they handle this in Java or in C or any other sort of performance-oriented giant line count languages is usually just to avoid almost all the cleverness. Does a Java framework do this? No, not at all. You will have to manually describe how each of these things happen in most Java frameworks. Does a C framework do this? C programmers would laugh at you based on this.
The idea that any part of it would be friendly to human beings is considered⊠I hate to call it a macho culture because that means something specific, but itâs got very much its own sort of, this is the hard core way we do it. This is how itâs done. And a lot of it is that cleverness is considered really bad. And I get it. That comes straight from electrical engineering culture. And it works really well for the kind of projects they do. And a web app done in that culture would be misery and horribleness. And so, thatâs one of many reasons that you donât wind up writing your web apps in C, because the culture would generate things that were hideous as web apps. Even aside from the fact that the language isnât terribly well-suited for it either.
JESSICA:
Noah, you mentioned that in Rails thereâs an expectation that one person can hold the whole program in their head.
NOAH:
Itâs a possibility.
JESSICA:
Is that like⊠I see that as this fail point, at which point one Rails app isnât working anymore.
NOAH:
Yeah, I would agree with that. So, the Rails basic pattern, the basic idea of how it structures controllers, how it structures views, itâs designed to be fairly friendly. You can pick up any controller or a view if itâs well-written pretty easily. But I agree in general that when a Rails app gets big enough that one person clearly canât see the interactions, itâs time to start taking chunks out of that Rails app. Separate it into other apps, separate it into services. I would agree with that. Rails is designed to be small enough one human being can comprehend it.
And a lot of the tradeoffs it makes, like having these additional services, additional libraries that are just magically available, are very much designed around the idea that one person can keep the [non-local] effects in their head. Whereas a lot of the scaling decision that it makes like say the routing layer being able to be a whole bunch of separate apps, are designed to make it really easy to cut that up into multiple pieces so that you can limit the non-local effects so that the pieces are small enough one person can keep them in their head.
JESSICA:
Exactly. Itâs not really just Rails. Itâs any application needs to be broken up at the point where one person can keep it in their head, eh?
NOAH:
Absolutely. Having pieces that small is really, really valuable. Not everything can do that. What I say about say Java is that if you were going to have 100 programmers all working at once on a
giant monolith, no question that monolith should be in Java. Whereas the Rails approach is what if youâŠ
JESSICA:
[Laughs]
NOAH:
Well, itâs a language that is designed to limit the amount of damage you can do to other programmers. It intentionally limits non-local effects as much as it possibly can. Now, my take on that is that you should not have 100 developers all working on the same giant monolith. Just avoid that situation as much as possible. But for the same reason, I canât remember where I saw this great discussion on IDEs, but talking about how every Java IDE has to be able to scale to multiple million-line codebases. Wait, didnât you just tell me that the big problem is that the codebases are too big? And now youâre making sure the IDEs make it easier to handle the big codebases? Isnât that bad? At which point, if youâre talking to an IDE developer theyâll laugh and then go right back to what they were doing. And the answer is yes, that situation is bad and we are making it worse. And then we laugh and go right back to making it worse.
JESSICA:
Iâm a big fan of the IDEs for reading those million-line codebases. And then I go switch over to vim when I want to write something intelligible.
NOAH:
Yup.
CHUCK:
[Laughs]
SARON:
[Chuckles]
NOAH:
Yeah. Well, if you write tools that make you keep it in your head, then youâre going to produce code that is small enough to keep in your head. And youâll get laughed at more by people who consider themselves real programmers based on line count. But youâll also produce much better code.
JESSICA:
Exactly.
NOAH:
I donât know.
CORALINE:
In that vein, do you think that Rails [inaudible] be better programmers?
NOAH:
I think that Rails programmers have a combination of pressures from the framework which make them much better programmers in some way and much worse programmers in others. So, where I see Railsâs sweet spot being, the thing that itâs much, much better than anything else and nothing else can come close to it, is a small team putting together a new project on a tight deadline to try out an idea where thereâs a really good chance that that idea wonât work out. Which again, is almost every startup these days. And the reason that I think that that is absolutely Railsâs sweet spot is that it makes sloppy programming forgivable, again like the security thing we talked about. It makes it really easy to take out a giant loan of technical debt by using other peopleâs third-party, not necessarily well tested libraries. It makes it easy to put something up that works, not necessarily perfectly, really not heavily bulletproofed. But it works. Youâve got a proof of concept and you can test it.
And the reason I say thereâs a pretty good chance the idea wonât work out is that if you put this together really fast and really sloppy, youâre going to have to put all the effort that you would take to rebuild it well in order to get it working well. But if thereâs a 75% chance the idea doesnât work out, well great. Three out of every four things you build, youâre just going to let it sink. Youâre probably going to get rid of it. At best youâre going to modify it to try another idea. And so, whether you rebuild it in Ruby afterwards or whether you rebuild it in ta different language, which is mainly a performance thing rather than anything else, whichever or those you rebuild it in itâs going to take you as much effort to build that full version as it would always take you.
Itâs just, you save the effort on those other three versions by building it in a language where you can do it fast, you can do it sloppy, and not put in the extra effort. Which again, is wonderful as long as what youâre trying to do is to solve problems that youâre not really smart enough for. And more and more, all the interesting problems are problems that one person is not smart enough for. And so, theyâve got to do it with a trial and error approach. Theyâve got to do it with an iterative approach. The interesting problems are all things where one human being canât just work through it and get the right answer by brain power ahead of time.
CHUCK:
If we donât have the constraints that put us into that sweet spot for Rails, then how do you decide which framework to work in, or what language?
NOAH:
I look at what my big constraints are. On any project thatâs at all interesting, thereâs going to be some set of interesting constraints. Like if you tell me that absolutely every request to my server is going to have to come back in a 20th of a second or less, then youâve told me what my 99.999th percent worst latency is. Great. That constraintâs my tool choice. Thatâs a big deal. If you tell me that Iâm going to have to put it together with three guys in two weeks, well then Iâm going to look at something like Rails where I can put something very quickly together but itâll still work well. If you tell me that itâs going to have to link to a giant big data backend, Iâm going to do it in something on the JVM. Maybe thatâs JRuby, maybe thatâs, I donât know, Clojure. But that gives me a constraint that I can work with.
If there are no interesting constraints on the problem, well then why are we doing it? Thereâs got to be some use for it, right? If youâre doing it in a startup sort of situation where youâre trying to make money off it, your constraint is almost always time. Because itâs money and those interchange. But an interesting problem has almost always got either a hard constraint or a goal. And the goal makes a constraint. The goal tells you whatâs important. So yeah, I find what the interesting constraint is and then I pick a tool thatâs designed for that constraint. And these days there are so many languages, so many tools, so many frameworks. I can find something thatâs aimed at that constraint.
AVDI:
So, hereâs a question for you. Given that you see Railsâ sweet spot as being the ability to throw something up really quickly and see if it sticksâŠ
NOAH:
Yup.
AVDI:
Arguably Rails is sort of intentionally that way but also sort of accidentally that way.
NOAH:
Yeah.
AVDI:
The application it was extracted out of wasnât exactly an application where⊠it wasnât exactly just throwing something together to see if it sticks.
NOAH:
No. I meanâŠ
AVDI:
Iâm curious if you thinkâŠ
NOAH:
Sort of, butâŠ
AVDI:
Sort of, yeah. But I meanâŠ
NOAH:
Sorry, go ahead.
AVDI:
Iâm curious if you think that there are other frameworks that maybe are now addressing that need more directly. I guess one that springs to mind is Volt where itâs putting an assumption in place that youâre going to be using probably something like Mongo and youâve got this whole stack set up.
And in return, you get to basically type stuff into the server and see stuff appear live on the page.
NOAH:
Yeah.
AVDI:
And so, you have even more live-ness, ability to play around, than in something like Rails.
NOAH:
Yeah. Thatâs potentially a really interesting thing. I have not looked enough at frameworks like Volt and Meteor to know if they also have the other handrails that something like Rails does. Again, I emphasize the security thing and I emphasize that the reason youâd use Rails is if youâve got human beings talking in HTML. Because if youâre going to put up a site that serves HTML to real browsers on the open internet, security is a huge, huge constraint. Itâs one of those things where building that backwards into something that doesnât already have it is not just phenomenally expensive, not just phenomenally time consuming, but it requires a genuine expert. You have to understand a lot of interesting attacks in great detail. And itâs a genuinely adversarial setup. So to me, thatâs part of why I say in a quick situation use Rails.
And thatâs what Iâve⊠I havenât looked into Volt. But Iâll say that JavaScript frameworks for doing things like that, like Node.js for instance, thatâs where they tend to fall down. Thatâs where they tend to say, âOh, well a skilled programmer can do that.â Yes, but you shouldnât make a skilled programmer do that. A skilled programmer can do almost anything with incredibly bad tools. That doesnât mean you should hand them bad tools. But I may not be giving Volt its due. Itâs possible that Volt does a good job of fixing that. But thatâs one of the things thatâs hard with a really dynamic language. Rails has had some of this, too, is that constraints like that, it needs to be reasonably secure, are hard to build into something thatâs very flexible.
AVDI:
Thatâs true, yeah.
NOAH:
But I think thereâs definitely a place for that. One place that I think Rails falls down hard is highly server-interactive applications. Youâve probably seen how bad it is setting up a chat server properly on Rails. Anything where you exchange a lot of information with the server after the page is served. And while that is in some ways an HTML limit, HTMLâs not designed for that either, a good framework can get around that to a large extent and Rails doesnât really try. It sounds like they may be trying to do it with Action Cable. Active Cable? I forget what itâs called. But I will say that the Rails 4 Live events were not enough or anything close to enough to really make that usable. Itâs possible that Rails 5 is going to do better on that. And itâs clear theyâre trying, which is nice.
But yeah, thereâs definitely some room for that. For starters, if I was going to do something with server push I wouldnât start with Rails. Because while itâs good for prototypes in general, itâs not great for prototypes of that. And so, thereâs definitely⊠thereâs plenty of room, even in that space. Thereâs plenty of room for something to be a really good tool for something small. If you told me there was another tool that was really good for, like you say doing live stuff and pushing directly to the server and back to the page, you can do better than Rails does that way trivially. Iâve seen very simple little Node.js frameworks that do exactly that and do a great job of it. And itâs because even where Rails is basically competent it definitely has its flaws.
CHUCK:
Anything else we want to go after with this before we go to the picks?
NOAH:
A couple of things Iâll hit quick just because I wrote them on a piece of paper, maybe important, maybe not. You talk about choosing a framework. One of the big things I do when choosing a framework is to read through the code. And reading through the code is a lot easier after youâve written code like it. And so, Iâm all in favor of people choosing a framework. And I think that building some parts of your own framework makes that, I wonât say easier. It still takes time to read. But it means you can make a much more informed decision because you know better what youâre looking at. Enough code reading will do the same thing. But Iâll say that good code reading, one of the things you should be doing is experimenting with that code. You should be tweaking it and seeing whatâs different.
And in the same way, very often knowing the framework down to the Rack level makes it a lot easier to get around the framework limits. Rails is nice as far as you can patch into the Rack middleware stack. But just knowing what you can do is usually something you accomplish by looking down underneath the framework. If you want to get at cookies before Rails touches it or you want to do an interesting kind of authentication before it gets into there, anything like that.
Cool, so thatâs what Iâve got.
AVDI:
I have one more question for you.
NOAH:
Please.
AVDI:
At the top of the show you said that âRebuilding Railsâ was the book that you wish youâd had.
NOAH:
Yes.
AVDI:
Iâm curious if there are any technologies, frameworks, languages, where youâre feeling that again now.
NOAH:
So, Iâm doing a lot of analytics and big data these days. And I would say Iâm not smart enough in that domain to know exactly what that book would look like. I think every so often about writing a big data book like this, because Iâve done a lot of poking into say Cassandra, which is really interesting under the hood, down in the data structures, stuff like that. But what I really want is some kind of a down deep understanding of the distributed systems stuff. And once Iâm smart enough to write that book, I probably will. But Iâm pretty sure that book doesnât exist yet. I really wish it did.
JESSICA:
Oh no, I have a recommendation for that.
NOAH:
Oh, okay.
JESSICA:
Martin Kleppmann is currently working on a book about big data and distributed systems and the tradeoffs that the different technologies make. Iâll find a link and post it in the show notes.
NOAH:
Sounds great. Yeah. I found a lot of tradeoff stuff. What Iâd really like is, do you guys know Aphyr? He does the Jepsen Call Me Maybe stuff.
JESSICA:
Yes.
NOAH:
Yes, so thatâs a lot of what I feel like thereâs a big gap on. And I canât be the only one. Thereâs a reason his stuff is so popular. I understand a lot of the differences in the tradeoffs that the different technologies think they make. But what I donât usually know is enough to see the holes in what theyâre doing. I can see some of them. I can find the big obvious holes in what theyâre doing. But thatâs what âRebuilding Railsâ taught me enough to go do with other frameworks. And what I just donât have the ability to do in distributed systems yet, with the understanding that distributed systems, itâs a lot harder to do that than with Ruby web frameworks.
AVDI:
Cool.
CHUCK:
Alright.
JESSICA:
Yeah, that makes sense.
CHUCK:
Letâs go ahead and do the picks. Avdi, do you have some picks for us?
AVDI:
I have a pick. And this is going to be another of my silly office supplies picks. But Iâm going to pick a brand of garbage can. Iâm going to pick simplehuman garbage cans. We got one for our kitchen sometime last year I think. And it has been the first step, I donât even know what theyâre called. The kind where you step on a pedal and the lid comes up. Been the first garbage can of that kind where the pedal hasnât broken within three months. Theyâre just, theyâre really sturdy. Theyâre most expensive than most of the stuff that you would go out and find and youâre thinking, âHey, letâs go buy a new garbage can.â But it seems like theyâre worth it. Theyâre pretty well-designed. So yeah, simplehuman garbage cans. Thatâs all I got.
CHUCK:
Alright. Saron, what are your picks?
SARON:
Sure. I have two. Theyâre both articles. So, the first one is called âEtsy CTO on Its Conservatively Crafty Tech Philosophyâ. And it basically interviews CTO Kellan Elliott-McCrea. I donât know if Iâm saying that right. And he talks about how they pick tools and what they used to do and what they do now. And he talks about their tech philosophy and I thought it was interesting in the context of picking different frameworks and picking what you use. He goes in depth about that at Etsy. So, I thought that was cool.
The second article is called âDeath of a Programmer. Life of a Farmerâ. And itâs a story about someone who was basically just tired of being a programmer and decided to raise, I think itâs lamb or goats or farm animals and farming. And talks about their trials and tribulations and what it was like. And I thought it was an interesting read.
CHUCK:
Alright, Jessica. What are your picks?
JESSICA:
I have one pick. Itâs a great pick. So, the other day a couple of weeks ago I was at Craft conference in Budapest. And it was a great conference. It was really amazing. It had some great themes about things like why micro services are not going away that really came out in the opening keynote of the second day by Mary Poppendieck. And itâs amazing. So, Iâm going to pick her keynote. The video is available. And itâs called âThe New New Software Developmentâ I think. But she starts from 40 years ago when she started programming and gives a lot of context about why the industry is moving in the directions that weâre moving. And what that means for the teams of the future and the software of the future. Thatâs my pick
CHUCK:
Cool. Iâve got a couple of picks. The first one, I just want to let everybody know we are doing Ruby Remote Conf. Several of the Rogues are actually going to speak at that. And Iâm really excited about the lineup we have. We also have a few other people you may have heard of like Dave Thomas. Steve Klabnikâs going to be speaking. Just a whole bunch of people. And yeah, itâs just going to be terrific. Itâs at the end of June. You can get tickets now. Go to RubyRemoteConf.com and sign up. The tickets are $200 apiece.
And another one that I want to mention is an event thatâs happening here in the US. Itâs called Rails Camp. Rails Camp West I think is what itâs called. Itâs going to be in northern California. It looks really great Iâll put a link to it in the show notes. And you can go check that out as well. Bobbilee Hartman reached out to me and let me know about it. And it looks really fun. I wish I could go. I just donât think itâs going to happen this year. Anyway, thatâs another thing worth checking out.
And finally Iâve been reading this book called âTractionâ. Now if you go look on Amazon there are two books called âTractionâ. One has a yellow cover and the other one doesnât. This is the one that doesnât, though the other one is really good, too. This one is basically about how you run your business and how you organize your business. And itâs making me think about the way that I arrange things and think about accountability in the business and things like that. So, if you are running a small business or youâre an entrepreneur then I highly recommend that book. I recommend the other âTractionâ book, too. But this oneâs really good.
CHUCK:
Noah, what are your picks?
NOAH:
First off, I recommend âThe Codeless Codeâ. Itâs a website of Zen programming parables in the style of âThe Gateless Gateâ. And itâs amazing. It is good Zen. Itâs good programming. Good Zen to the extent I know anything about it. But it does a beautiful job of keeping the enlightened style. And Iâm an increasingly old programmer. And so, programming parables are always interesting to me. These are done really well.
Iâd also recommend âRuby under a Microscopeâ by Pat Shaughnessy. I expect somebodyâs recommended it before. But itâs worth more than one recommendation. It goes down deep into a lot of the Ruby data structures like the hash table and extensively how hash tables work and how they perform and how theyâre set up. It goes down deep into the Ruby parse tree stuff, which I think more people should look into. Rubyâs a complicated language for parsing. Anyway, âRuby under a Microscopeâ by Pat Shaughnessy is fabulous.
And then as a last pick, so my book does a really good job of hitting the overall structure of Rails. But it doesnât do a good job of hitting the individual Rails APIs and talking about that. Many of my things have different names for the methods. I certainly donât have a giant extensive Active Record.
Iâm mostly doing just enough of the Ruby methods to show you the structure of Rails and tradeoffs of Rails. So, the opposite approach is âThe Rails Wayâ by Obie Fernandez. I think theyâre up to âThe Rails 4 Wayâ. And so, if you want a companion book that does the things I do well badly and the things I do badly well, just to get the balanced view, âThe Rails 4 Wayâ by Obie Fernandez is a great choice for that. And thatâs me.
CHUCK:
Alright. Well, thank you for coming and having this discussion with us. If people want to find out more about you, about âRebuilding Railsâ or get the book, what are the best ways to do that?
NOAH:
Well, âRebuilding Railsâ is at Rebuilding-Rails.com. My blog on lately more deployment topics but Ruby topics is at Codefol.io. And you can also find my class at Rails-Deploy-In-An-Hour.com with dashes between the words. So, those are all great ways to find me. Iâm easy to google. Itâs not hard to find my email address. So, Iâm very happy to field questions from anybody whoâd like to email me. You shouldnât have any trouble finding me. But you can comment. Leave a comment on the blog if you have any trouble finding my email address. Iâm pretty friendly.
CHUCK:
Alright. Well, thank you everyone for listening and weâll catch you all next week.
[This episode is sponsored by MadGlory. Youâve been building software for a long time and sometimes itâs get a little overwhelming. Work piles up, hiring sucks, and itâs hard to get projects out the door. Check out MadGlory. Theyâre a small shop with experience shipping big products. Theyâre smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter at MadGlory.]
[Hosting and bandwidth provided by the Blue Box Group. Check them out at Blubox.net.]
[Bandwidth for this segment is provided by CacheFly, the worldâs fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]
[Would you like to join a conversation with the Rogues and their guests? Want to support the show? We have a forum that allows you to join the conversation and support the show at the same time. You can sign up at RubyRogues.com/Parley.]
207 RR Rebuilding Rails with Noah Gibbs
0:00
Playback Speed: