Funny, everything in this post is exactly why i prefer Python(+Django/Flask) over Ruby(+Rails). Too much magic happening everywhere, a gazillion of built-in methods, weird shit happening all over the place, all that combined with all the syntactic sugar Ruby offers.
Granted, it might look "beautiful" in the eyes of a experienced RoR developer, but personally i find it just makes code very hard to read. Just my 2 cents.
This is I think the biggest reason Rails has remained a pro development tool and has failed to usurp PHP in the beginner realm.
Rails took me about a year of full time work before I could reliably fix bugs in a 1-day timeframe. Before that there were frequent unpredictable week-long goose chases through the Rails stack... usually just to learn I was Doing It Wrong and there was some convention you just really can't break without everything falling apart.
I had the same experience with Ember.js, another convention-over-configuration framework. A year of full time development before I could bang stuff out without being afraid I'd get totally lost and have a feature balloon up from two days to a month. And this is with a computer science degree and 10 years of web development experience.
Once you get past that first year, it's great. Or, if you're on a team of people, you just get help.
I taught RailsBridge a few times, and it's kind of crazy how many concepts you have to teach someone just to get to the point of a simple web form on Rails. It's probably at least 100 totally disconnected ideas, from routers to HTML to templating engines to MVC.
We're just not doing a good job paving a path from PHP's functional, minimalist, "copy/paste this snippet of code into your template" architecture to things like Rails/Ember which provide ergonomic toolkits for modern apps.
You are so right and it breaks my heart every time I think about it.
I just don't know what could really bridge that gap. So many terrible php and <insert language you like to make fun of> codebases come from exactly
> "copy/paste this snippet of code into your template"
programming.
Which is how most beginners learn (myself included. cobbling together myspace and wordpress templates) and it takes a while before you've done enough of it to see how deep the holes you dig with it can be but in the mean time your stuff "works" but is a nightmare to maintain and understand long term.
I had a lot of hope for the node community (because at least then newbies only have to learn the quirks of one scripting language) solving this with express/ sails or something else but they've stalled.
I guess its just a hard problem. No idea how to solve it
>>Which is how most beginners learn (myself included. cobbling together myspace and wordpress templates)
That right there is the problem: too many people are after quick wins and instant gratification and aren't willing to make an effort to learn something the proper way and appreciate its complexity, even if they are not exposed to it directly.
I learned Rails via the Rails Tutorial[1], and finished it in three weeks of evening and weekend sessions. When I started, I knew a little JavaScript, but not much else. By the end of the tutorial, I had a fully functioning app (parts of it I had customized, even!) and was ready to start building my own stuff. It was very empowering and I was blown away by how incredibly smooth and easy the Rails framework was.
That said, if I had taken the approach that lazy PHP beginners take and tried to learn by copy/pasting stuff (or relied on Rails scaffolds from the get-go), I would have stumbled over and over and probably given up.
>> Which is how most beginners learn (myself included. cobbling together myspace and wordpress templates)
> That right there is the problem: too many people are after quick wins and instant gratification and aren't willing to make an effort to learn something the proper way and appreciate its complexity, even if they are not exposed to it directly.
While I kinda agree with you to a certain degree, I think instant gratification is crucially important, at least in the first "play" phase. A lot of people don't want to know something before they even attempt to play with it. That's what playing is there for, it gives you a small insight of what to expect.
You don't really have a play phase with Rails... or Ruby for that matter, a lot of my front-end or PHP developer friends can't even install Ruby on Windows because it requires you to know certain things about the OS, the language and some very basic things from how linking, compiling and C works (most developers don't).
To even get started with Rails you either need to be a experienced Ruby developer, or dedicate time to learning Rails before you even begin to use it (and even then, I am not sure you could grasp some concepts without knowing Ruby's rich syntax).
Not to mention, you need to know how to use bundler, setup a database, a web server, etc. Compared to most PHP frameworks, where it's just download X, visit /, "voila," edit file something.php, visit `/something` and "voila," again.
Also, as someone who works for a hosting company, most of our PHP developer clients don't RTFM, they prefer blog posts, or YouTube tutorials (this isn't even a joke) because they don't have time for getting started guides. :|
I'm sure you just meant to highlight that reading tutorials is often a better experience than just messing around and hoping to get somewhere (which is why I didn't downvote you), but on first reading it comes across as "if you can't commit to devoting nights and weekends to systematically learn how to code, you're doing it wrong and you're probably a bit of an idiot – like all of those PHP script kiddies."
I think something like Flask is super easy to learn. Go one step further and use Bottle, its a single Python file and its API is one page long.
Its basic, but that should be the point. You can fluidly graduate from Bottle to Flask + extensions or to Django depending on which you prefer. Or just start in Flask - the base API is pretty much the same, its just it has a ton of extensions to implement all the server functionality you could want.
It's an act of balance. You shouldn't have to spend days hunting down simple bugs or figure a convention out. It's not that Rails is bad, but all conventions should be well documented, and if all conventions and general usecases for them cannot fit in a single volume book, it needs to be trimmed down.
You are comparing high-level frameworks like Rails or Ember with PHP, which is a language. Learning ruby is not that harder than learning php (actually it was easier IMHO). And if you compare Symfony or Laravel, and Rails, then again the difference in learning curve is not that big, it takes (quite a few) months to really learn your way around in any of them.
All those vague concepts kept me away from learning rails because it always felt it was hacked together.
There are also a lot of PHP frameworks that have this pro status because they are hard to learn. But using comments as programming features doesn't sound pro to me.
Some time ago I jumpt fresh into C# and .NET MVC. Now that is what I call a pro framework. It was very easy to learn but so powerfull.
Ofcourse I'm biased now because I fell a little in love with C#
It wasn't until after spending non-trivial amounts of time
building a non-trivial app in rails that I realized I hated
the magic.
And it wasn't until after spending a non-trivial amount of time building many non-trivial apps in rails that I realized I sincerely appreciate the legwork that Rails saves me from doing. And having worked with rails for a non-trivial amount of time, nearly all of the 'magic' has been dispelled and replaced by an understanding of what Rails does and why. Giving me metaprogrammed finder methods or metaprogrammed getters and setters is wonderful. Maybe you don't like it, but I do, and this is a matter of opinions so the fact that it metaprograms is not a point of critique against the framework.
Telling us you hate metaprogramming does nothing beyond riling up more of a bickerwar.
Yet isn't the time saved by using Rails, the same thing that every other framework offers---without using large amounts of meta-programming?
I mean I like Django. I think its saves me a lot of time. I love the ecosystem, that lets me pick up someone else's apps and use it directly or use it as template to write my own.
Django makes different choices when it comes to what level of metaprogramming to afford, and how to display that to the user.
Now when I first started with MVC on the web (I'd known about it via Smalltalk, but it has a whole different feel there), I used Symfony PHP with its scaffolding and at then point active-record style generators. I liked it, and it helped me understand the core of MVC.
After that, I became opinionated and as my opinions didn't align with that of Symfony or Rails, I chose Python and Django. It was a breath of fresh air because when everything is explicitly defined, it becomes imminently simple to swap out and rewrite things for your given use case.
In fact, the only thing that's pretty difficult to change in Django is the request/response cycle since that's too deeply backed into all the middleware and top level binding to the server.
I've developed non-trivial applications with both Rails and Django and while I agree that Django is more explicit, its overuse of class inheritance made it difficult to figure out what was going on, and made reference tools like this necessary: https://ccbv.co.uk/
I know you don't have to use class-based views and can just use functions with mixins instead, and that's the approach I prefer when working with Django. But if everyone else uses CBVs I still need to understand them.
Rails controllers use inheritance too, but they mostly just inherit directly from ActionController::Base or from ApplicationController. It's not a deeply nested hierarchy.
When it come to their database model I didn't find their use of class-based inheritance to be too crazy. There's some meta-data hacking going on in there; but it wasn't too difficult to figure it out if you wanted to extend the Django ORM to interface with other databases.
In my case, I made an interface to read from ElasticSearch and return Django objects, and store back to ElasticSearch using regular Django objects as well. Since I wasn't creating/restoring everything to ES, my library had to create a partial model that'd look up the rest of the information in Postgres if you touched a field that hadn't been stored in ElasticSearch.
On the view side though, its not too complex when it comes to request objects, response objects, templates and middleware. Injecting new template engines is fairly straight forward, and the request/response objects are just data objects.
However, CBVs are horrible. I never used them. I begun using Django before them, and when they were introduced I tried using it for a month then dropped it entirely. I can see how they can be useful for a CRUD app, or some kind of application where there's a lot of code-reuse going on between the functions related to a particular object, but that's never been the case for me.
I just use functions with decorators for permission & object instantiation from the URL.
Django actually hides all of its ugly internals in their form classes.
Hardly anyone talks about that because for 90% of the use cases it just works, but the moment you want your form widgets to do something complex, you have to write the forms yourself---in their entirety.
I hear that Django 1.9/1.10 is going to give us templates for forms and refactor that code into something sensible. Hopefully it'll be good; but if its a debacle like CBV, I'll just continue doing form templating by hand and using Form only for validation and sanitization.
I agree with all of the above. Django's Model system is great, and function-based views work well too, but the class-based views and forms are misguided attempts to apply OOP principles where they aren't really needed. Inheritance is just not the right tool for the job, it creates more problems than it solves.
I would have been satisfied if the forms use the django templating system, instead of trying to use string manipulation to create HTML somewhere in the bowls of a python file.
How great would this be?
name = BooleanField(template='switch_not_radio_boxes.html')
Your template file spits out HTML for flip switches instead of radio boxes (e.g. Https://proto.io/freebies/onoff/), and the template can add javascript/css to be bundled into a singular location with the rest of the Form fields static assets.
It'd be simple.
But nope, instead BooleanFields use a widget that creates HTML & sprinkles error messages upon it through some byzantine means.
>Maybe you don't like it, but I do, and this is a matter of opinions so the fact that it metaprograms is not a point of critique against the framework.
Almost every 'critique' of a language is because people don't like the features used/not-used.
It's like saying that the syntax is not a valid critique of brainfuck because you like it.
From someone who loves RSpec along with its metaprogramming and DSLs, I agree that much of "magic" in Rails and its ecosystem is annoying. RSpec gets it right in that it implements an elegant, readable DSL for a specific use case: testing. Rails does a good job at enabling rapid application development but it does a poor job at maintainability and testability. It's a trade-off, but one that I'm less willing to make for complex, long-term applications.
Please don't let Ruby's leaky dynamic action-at-a-distance shoddy excuse for metaprogramming and DSLs scare you away from real metaprogramming and DSLs.
Real metaprogramming doesn't involve action-at-a-distance and flaky dynamic interpretation. Real DSLs don't let you "peek behind the curtain" and therefore don't leak. True metaprogramming systems and DSLs don't let you flout "convention" and get into trouble as RoR does.
Introspection and a dynamic unstratified language do not make a metaprogramming system. High-level well-founded language manipulation constructs do.
Conventions and overloaded operators do not make a DSL. A well-defined grammar and interpreter do.
See OCaml's module system for an example of metaprogramming done right. It is simple to use and gives strong static guarantees. If it compiles, it will run without crashing; else the compiler will give clear error messages if it's unhappy.
See YACC, SQL, and XPath for examples of DSLs done right (albeit arguably abtrusely). They do not leak by design, since they do not let you "peek behind the curtain" which is the #1 way to get yourself (or others) in trouble with DSLs.
> Every bit of that "magic" is either meta programming or a dsl.
No it's not. The boot process hooks up a lot of things without your knowledge. It's an unbounded mass of side-effects that are caused by your code that you have zero path to understand or debug, other than pouring over docs and StackOverflow questions until you understand Rails architecture deeply enough to form a hypothesis about what part of your code might be implicated in the behavior of your app.
DSLs and meta-programming are not what people are talking about when they talk about "magic". They're talking about side effects.
Because "metaprogramming" might as well be a synonym for "magic" to most programmers.
Ruby almost gives you real macros. It gives you enough to do interesting things with, at any rate. Sitting that close to Lisp makes something magical to people who are accustomed to languages that sit closer to C/FORTRAN.
> Too much magic happening everywhere, a gazillion of built-in methods, weird shit happening all over the place
Couldn't agree more on this. Magic is good if you understand the underlying stuff but if you don't and you are once offtrack you are lost. Maybe it's also a matter of taste. However the hype and traction DHH could build when RoR started was quite impressive.
I think this is wrong. Nearly all of us build on top of things we don't understand. I don't understand the physics of a harddisk, or the pipelining of a CPU, or some of the low level OS functionality.
The issue is when do each of us, as individuals and/or teams, really need to understand more. And perhaps more importantly, when does it make business sense to leverage magic to get to market faster, build cheaper, or find market fit before worrying about building the most robust thing possible.
I think this concern gets lost in translation sometimes. It's not that you need to understand everything but you do need to know that there is a layer underneath. And it needs to be possible to follow a trail to and through that layer to debug things. Most of the time I don't need to understand the physics of a harddisk. But I know a hard disk operates under certain pysical laws. When I encounter something happening wrong it has on occasion been useful to be able to follow the trail all the way down to that disk and debug at that level.
Ruby's freewheeling philosophy however means that even when you are the author of the code some other code might have reached in and changed something out from under you. Not only do you not know there is another layer somewhere doing stuff that impacts you you can't even reliably follow a path to find that layer and debug it. As long as everyone does everything perfectly this is a wonderful world to live in. But the first time someone breaks the rules and impacts you and you lose a week or more unnecessarily you'll understand the distaste that ruby fosters in some people.
It's more about being able to discover what you need to know that it is possessing full knowledge of everything you need to know.
> Most of the time I don't need to understand the physics of a harddisk. But I know a hard disk operates under certain physical laws. When I encounter something happening wrong it has on occasion been useful to be able to follow the trail all the way down to that disk and debug at that level.
I'm not entirely sure how a filesystem works under the hood (let alone the physical media it's on), despite interacting heavily with one every day. A bug involving a hard disk would be incredibly opaque to debug, from my perspective. I suspect that you find it easy, because you've spent the time developing an understanding of the system.
> Not only do you not know there is another layer somewhere doing stuff that impacts you you can't even reliably follow a path to find that layer and debug it.
And this is where our roles are reversed! I would have little trouble following that path, all the way down into C if needed- because I've spent plenty of time understanding the system.
The problems you describe are problems anyone would have with an unfamiliar system, and it's not Ruby's fault.
>The problems you describe are problems anyone would have with an unfamiliar system, and it's not Ruby's fault.
Way to reduce what he's saying into the classic, "He can't be depressed! There's starving kids in Africa dying!". You've taken his /observations/, misplaced the usefulness of those observations, and then reduced them into some absurd argument that he's not actually making.
Accessibility to the unfamiliar access goes wonders and reduces the "magic" feel. If ruby doesn't have that sort of accessibility, then it IS Ruby's fault. If that's what Ruby actually wants, that's fine - but holy crap, it's this sort of mentality that completely fucks over usability.
I actually like Ruby, but hate RoR, because of a very lacking sense of control, unless you are very deep into it. You have absolutely zero feeling for what it OK and what's not OK to do with so much implicit magic behind the scenes. And that's debilitating.
My interaction with RoR can be boiled down to this exaggerated dialog:
- Here, write your code in this pattern and it will work.
- And if I change it like this?
- No it won't work.
- But why?
- It's an opinionated framework. It's the opinion of some Very Smart People(tm).
- But this is my work. Why can't I do it the way I want?
- Because you are dumb. And your dog is dumb. You haven't grokked it. You aren't a hacker. Neither is your dog. Where are your hoodie and Nike Airs?
> I don't understand the physics of a harddisk, or the pipelining of a CPU, or some of the low level OS functionality.
I think the key difference is that you don't need to know how that works. I think there's a question of how leaky the abstraction is and how often you need to look behind the curtain.
Tons of people and use cases never need to delve into the implementation to get a lot of mileage out of Rails. I get a lot of work as a Rails consultant and most of the real pain I see is caused by people doing stuff like implementing their own ORM with an ActiveRecord-ish interface, or writing their own caching logic implemented as a mixin for ActiveRecord.
> I think this is wrong. Nearly all of us build on top of things we don't understand. I don't understand the physics of a harddisk, or the pipelining of a CPU, or some of the low level OS functionality.
There's probably a SE paper somewhere stating this formally, but I figure well done implementations on top of abstractions only need to reference one layer down. It might be okay to inspect the state the layer below for performance reasons, but no further.
That means that a well done Rails app might want to inquire about the state of HTTP, but shouldn't inquire about IP addresses. And it might want to know about indexes on its databases, but not disk caching policies or i/o schedulers.
So the case of "too much magic" is not to become used to the discomfort of not understanding how underlying abstractions work, nor is it to stop using them. Instead you want to choose dependencies with well documented abstractions, implemented such that you can inspect if you need to.
This has nothing to do with Rails specifically. I see plenty of coworkers who dislike Django's large set of features, as too much bloat, or too much magic they don't understand. Instead of reading documentation, and becoming expert in Django's abstractions, they spin up Flask apps, slowly reinventing the wheels, but maybe not quite as round.
No. For example, on rails if I make a typo creating a table, I delete my whole project and start over from scratch. I have not been able to figure out how to edit the name of field. That's an impediment.
A very quick Google search for "rails rename column" will show that there's a method called "rename_column"
You can even search for "rails typo in migration" and the first result is a stack overflow post suggesting and explaining how to roll back the migration so you can edit it
And this sort of thing is exactly why there was a satire site article titled "Computer Programming to be Officially Renamed 'Googling Stackoverflow'" the other day.
I understand having gripes with rails but this is a bit ridiculous. Deleting an entire project because you made an error creating a table and weren't able to sort out how to fix it?
That's a little extreme, surely this must be hyperbole.
Sort of, but I'd rephrase it. I don't need to understand how a harddrive or SSD actually works, I just need a consistent and well documented abstraction.
But Rails (and Ruby) do offer that. I agree that there's a lot of it, but it is there. Its abstractions are consistent, and Rails is generally well documented.
I don't know Rails enough to really comment on that, but if it takes 1 years to learn it all, I'd say it fails my definition of concise and comprehensible. It should fit in a single volume book that I can read in the evening over the course of a week.
That said, I don't have a problem with frameworks that are larger. Hell, I'm a .Net dev by day myself and that certainly doesn't meet that requirement. I just don't find it elegant.
That's a pretty crazy claim. So, do you build your own interrupt gates, and take those into account when you're writing PHP?
How about electrons? Can you draw me a graph of the electrons currently residing in your computer case/laptop? Can you explain to me exactly how your PHP code will look in binary?
Sorry to be snippy, but you're making a pretty audacious claim there. I don't think any reasonable software engineer/developer can claim to fully understand every underlying principle.
I mean, you can have an abstract, high-level idea of how things work, but do you really think you know the intimate details of every single piece of hardware/software involved in writing your code?
Making a specific claim about this is nonsense but making a claim about this in principle is perfectly valid.
it's the difference between being able to wire up a logic gate from transistors with a basic understanding of how they work and to be able to wire up a cpu, ram and some io from logic gates, being able to wire up a computer from cpu chips, ram chips and IO chips.
Even if you don't know the exact details of the latter in principle you understand that whole device that you just built.
So the claim is not so crazy as it might sound initially.
> What is the claim exactly? Ruby/Rails is bad because ... too much magic.
No, that wasn't the claim.
> 1. Rails is easier to learn than most of the things mentioned above, so not magic
Ignoring the strawman component: that's a matter of opinion, for some those electronic bits and pieces are actually simpler to understand than software.
> 2. It's perfectly reasonable, and good, to build on top of and leverage things that you haven't taken the time to learn intimately.
Yes, absolutely. Just like we don't require everybody that uses the highways to be car mechanics or road construction workers. Society would grind to a very rapid halt if we had to have an intimate understanding of everything we use everyday.
I'm with you on this; I can't reply to the sibling comment, but I'll elaborate on what this means in my own professional practice.
I did a dual-major in CS and EE, and then an MSc in CS. While I'm a little fuzzy on the specific details of the current transistor geometries (14nm?! that's wild!), I do pretty much understand the entire stack upwards from there. I could design a fully-functional computer from the logic gate level, although it likely would be slow as hell and be exceptionally boring. It's not my strong point, but I understand enough about what's going on.
Honestly, most of my electronic design work these days is analog circuits slung onto the side of a microcontroller, with code written in C. I'll do schematic design and capture, and board layout without too much difficulty.
Going up from there, I've written my own (toy) operating system from scratch. I've written Linux kernel drivers for both off-the-shelf devices and for custom devices implemented in FPGAs. High-bandwidth/low-latency TCP servers written in C. My own (toy) programming language. I've written C extensions for PHP and Python, and have done pretty intense profiling work on them; this requires a pretty deep understanding of how the internals of the interpreter work (part of my MSc coursework). And I've done web apps in PHP, Python, Ruby, and Elixir.
The whole point of this is that I'm totally comfortable going as deep into the stack of abstractions as necessary to solve whatever problem I'm facing. When I started learning Rails, I was mystified by all of the "magic". I'd never even really used Ruby, let alone all the extra stuff Rails does. But I set up the emacs-bundler library (https://github.com/tobiassvn/bundler.el) and started diving in. I'd work through a tutorial, and every time I encountered something I didn't understand, I'd dive into the guts of Rails (bundle-open activerecord) and read the code until I understood it.
As an example of going a layer deeper, I once encountered a bug in a Python script that used PySerial. There were multiple threads, and the script would hang sometimes. I read through my code and couldn't find any problems, so I dug deeper into the PySerial code. Nothing obvious in the .py file for PySerial, so I dug deeper into the C extension. In the C code, I discovered that there was one case where the GIL wasn't being properly released before doing a (sometimes) blocking call! Tada! The script worked great if the call didn't block, but hung if it did.
I think there's a subtle difference between what your parent said and what you're saying: they suggested that they know what's going on at every level, and you merely claim that you can figure out what's going on, if need be. (A charitable reading would be that they meant the same thing though.)
I think we should all aspire to this level of having enough of a mental model for all the layers underneath us that we can go dig into them when needed. But it takes a lot of effort to get to the point you're at, so it's a pretty big ask. (Also, most of us probably can't go back to a university to learn the EE side, and it's not easy to self-learn it.)
Having said all that, for Rails specifically, it's pretty easy to do exactly what you did and just open up Rails and other library code. It's almost entirely simple method definitions, and the parts that aren't can be understood if you go read about how `define_method`, `method_missing`, and `const_get` work. The "Rails is magic" meme seems to either scare people off from reading the code, or give people permission to be lazy about it.
Especially with pry existing now, the "Rails is magic" meme is tired and incorrect.
Install pry, pry-rails. Something weird occurs? binding.pry, `show-method` or `show-source` and it dumps you to the exact line and filepath of the method, be it the original or a monkeypatched method (use -a to show them). Keep digging like that and you'll eventually hit the C implementation code.
[18] pry(String):1> show-method length
From: string.c (C Method):
Owner: String
Visibility: public
Number of lines: 5
VALUE
rb_str_length(VALUE str)
{
return LONG2NUM(str_strlen(str, NULL));
}
Your last point really stood out to me. Reading through the commentary, it's difficult to see what is so magical about Rails after spending a lot of time using and especially abusing vanilla Ruby.
Sure, I can concede that code that tries to do too much for you to the point where you didn't actually want it is annoying. It's just that, in the context of what Ruby CAN look like, Rails isn't that arcane.
For example, entirely for fun (it was a lot like a game - I couldn't stop seeing how far I could push it), I gradually built up a small library (less than 100 lines of code) that eventually yet radically transformed Ruby into what looked like a badly designed yet different (functional) language. Functions could be conveniently composed, partially applied, juxtaposed, etc by monkey-patching the symbol class with overloaded operators. I also had fun getting all this working for instance method calls so they could be treated the same way (few caveats with that though).
Not to say that this is a production-worthy effort, it's simply not. It's just the experience that has ultimately taught me the extent of Ruby's (perhaps dangerous) power and that Rails doesn't actually call upon that much of it in the grand scheme of things.
Truly knowing Ruby for Ruby and what it's features can really do, you only need to look at the so-called magic that Rails demos to understand intuitively how it does what it does.
Another subtle thing with it is that, while I'm writing code in whatever scripting language I do think about what's going to be happening under the hood non-stop. For example, every time I write a line of activerecord, I'm thinking of what kind of SQL is likely to be emitted, and whether or not it'd even be possible for the database to have an index for the query. Sometimes a table scan is the best you can do without denormalizing and its awesome to notice that right away instead of down the road when it's slow.
But this all is both a blessing and a curse. Often it ends up meaning that I spend more time thinking about a problem than I need to.
Another fun example from some recent work: a client calls me up and has a machine that they can't access. More probing reveals that the machine is buried under a frozen highway! (I'd love to go into way more detail but... NDA) Anyway, we do still have an RS485 link to it, with getty running. The goal was to determine whether it was a software problem (fixable without needing a backhoe in 4 months when the earth thaws), a hardware problem, or a cabling problem. How do you know for sure? Jump into the bootloader and configure the ethernet phy to tell you what it sees by directly writing registers over MDIO! Turns out the PHY is alive and well, but can't seem to see the 100MBit sync pulses. Plus it is still successfully doing PoE negotiation. The cable is still connected but either the switch, the cable or the magnetics are bad. Field guy is going to try a new switch before we abandon all hope, but at least we know that no amount of software fixes will solve the problem
You understand the underlying stuff after working with rails -- the complaint of Magic comes from (I believe) the fact that Rails is very easy to approach compared to other languages, so many people are able to create a lot with comparatively less understanding of the framework, so when things work or break, they are less likely to know the root cause/reason and blame it on 'magic'.
Complexity/perceived burdenwise, I think java is to rails as rails is to sinatra (or a similiarly small framework).
There may be a point where you want your functionality bundled and presented as a framework (if you, like me, think of frameworks as bundled and groomed libraries/functionality), but if you're not sure you're at that point (or don't know what that point is), try to start smaller (like sinatra) and go bigger, rather than the other way around (starting with the biggest tool you could find, trying to find the smallest).
I strive not to become a good developer on X platform (for Y language) but rather just a good developer who's proficient with Y language (and happens to be able to use X lib).
I used Sinatra on a project the year before last, and liked it so much I used it on two more the year after.
At this point I think I'd only choose rails where I knew from the start that it was going to be a big, complex, semi-monolithic service. I can definitely see value in rails for doing that kind of thing.. But for everything else Sinatra is a pretty good default position.
Sinatra is all well and good until you have an application complex enough that you want to start applying some interesting methods of code reuse across several routes, and want to share several facets of, say, object loading and authorization, or something around page rendering. At that point you run into the fact that all your tools for manipulating the request and response are built into a singleton object (your instance of Sinatra::Base) which begins to inhibit several very useful forms of code reuse (such as most OO inheritance schemes, for a start).
If I had a dollar for every minute I wasted rewriting things that I could have for nearly-free with (for example) Rails and CanCan and a quick call to load_and_authorize_resource in my ApplicationController, or a lame hacked substitute Rake task for ActiveMigration... that'd be a distressingly accurate description of way too much of my career.
Of course if you really are just building just the one microservice and don't have any complexity to manage, then yes, Sinatra all the way, 100%.
Would you mind giving a semi-specific example? It sounds like general use of ruby-based Dependency Injection is the solution to your problem, not necessarily rails.
Also, OO inheritance has some well-documented flaws as a code-reuse mechanism. I couldn't point exactly to what favoring composition over inheritance would look like in ruby (I've seen some approaches, but have an unhealthy dislike for the word "Factory" so they didn't seem great), but maybe there's a better way to share that code you're trying to share? Also, I don't think the solution is mixins because once you have too many of them how they interact becomes very hairy -- but regardless, I think a ruby solution exists to that problem as well. There is also the "has a" vs "is a" distinction but I digress.
Of course, there is a point where you shouldn't rebuild the wheel, but I don't think "shared functionality", or "access to persistent objects across requests" is that point.
To expand on what I mean, if these are the things you want to do:
- Respond to requests like an API server
- Serve static files
- Serve templated files
- Shared information across request
- Share application-relevant objects across requests (ex. marshallers, keystores)
- MORE STUFF
- ...
I think the point where rails makes sense is at/after "MORE STUFF", and possibly in "..." range.
Semi-specific example: I worked at a place that operated on a marketplace model. It was desirable for all marketplace submissions to be reviewed by a set of humans who were paid for that effort by the review. The existing system for doing this was in a bad state. By "bad state" I mean coded in a legacy system with no tests or even separation of concerns (think of a system that iterates over the results of a query, making additional queries and rendering JavaScript snippets to the page in this loop) and hitting scalability limits as it made exciting joins across the company's master database.
The company's architectural model dictated that the new version should take the form of a (non-micro) RESTful service layer handling the data in its own database (also facilitating the application of the problem to new lines of business for different varieties of marketplace item under different brands, improving visibility to the review process to sellers, and leaving open an avenue to outsource or automate certain parts of the problem.) We would migrate the legacy code over to use this layer instead, then we would write new frontend code with better workflows, then we'd coordinate with other teams to review new classes of marketplace item with different review criteria, then some year we'd have room for the pie-in-the-sky machine-learning-assisted review (assuming that something more important didn't come up instead.)
The result of this was a modestly complex set of abstract business-data objects, including marketplace items, all the metadata associated with them (editable by reviewers in this system), owners of items, reviewers, reviews, internally visible comments associated with the reviews, feedback associated with the reviews, review escalation, reviewer-supervisors, and a variety of other things which I forget right now.
I say RESTful: while not as pure as it could be, it actually did a half-decent job of being hypermedia-y and not merely "throw some JSON around over HTTP". Things had URLs instead of just IDs. Lists of objects were paginated with consistent ways to get links to the next/previous page.
Sinatra left us with uncomfortable choices between having excessive code duplication and the quality/maintainability issues it would bring, or writing our own logic to ferry Sinatra's various handles to the request / response / templating engine. We chose the latter, and I don't regret it - I regret that we sunk as much time as we did into that piece of code instead of building it on top of something with richer abstractions. It was the wrong choice for this particular application.
If you like Sinatra and want to use something that's both fast and as simple as Sinatra you can try Kemal.(http://kemalcr.com/) A side note that it's written in Crystal(http://crystal-lang.org/) which is like Ruby.
I really don't like the way Sinatra has its own new DSL. I don't understand why Rubyists want a DSL for everything. I really prefer the class based approach of Camping.
I'm a Rails developer and I'm coming to feel this way as well. I agree with most of what's in the Rails Manifesto except the convention-over-configuration thing. Too much "magic" happening. Magic's cool, but I need to know why a certain thing works or why it doesn't work.
Rails is the only environment in which I've routinely found myself utterly stumped. Not because it's hard, because it isn't. But the thick layer of "magic" makes it awfully hard to debug sometimes.
We are in the same boat. I find myself relying way more on pure ruby classes.
It's also dangerous because Rails fits a specific niche, like he mentions--building (potentially) many web systems quickly. We chose to migrate large legacy systems to rails, which meant lots of the nice convention just. doesn't. work. Day 1, you're already digging in to figure out how to get around the magic!
For me, magic isn't the problem. I like the magic of conventions, but not when it is painful to pull back the curtain. For Rails, I think pain comes when magic stands on poor internals, which gets amplified when gems layer on their own painful workarounds...and I have to sort through all of it.
That's why I'm excited about Sean Griffin's work on the [Attributes API](http://edgeapi.rubyonrails.org/classes/ActiveRecord/Attribut...). To do it, he's had to refactor out a lot of internal monkey patching so that (in Rails 5) there is only one source of type information for an AR model. This means gems can extend AR, I can extend AR, new requirements can walk into my door that I can deliver on without monkey patching or opening Pandora's box of a patch of crappy Rails internals. The magic is still there, but it's done it a way so the magic doesn't fall apart in unexpected, unmanageable ways. That's what matters to me.
As I've entered the more intermediate stage as a Rails developer, I've noticed that the "magicalness" that allowed me to do so much so quickly as a beginner, is often actually getting in my way. Perhaps when I reach the "advanced" stages, I'll learn to love the magic again, but I'm in this awkward stage of knowing what I want to do but not knowing how to tell Rails to do it (or stop doing it, as the case may be).
Why throw out some catch phrase without providing specifics?
We all adopt certain amount of implicit choices in our lives because if we had to be explicit about everything, we'd be bogged down in choice-making and not really get anything done.
Why care about choosing the right ORM, Logger, templating engine when there's real business problems to solve? If there's a true business advantage to choosing an alternative, then substitute, but eventually you have to get on with the show and make something meaningful.
Strong defaults and conventions are a feature and Rails nails it better than any other framework out there.
Funny you should mention Django, because its the magic framework in python land that does all those things you label Rails doing and it does it way way worse than Rails.
That might plausibly have been true in the past, at least if you hadn't heard of Zope/Plone, but Django has been moving away from that for close to a decade:
The only real magic left in Django is the metaclasses that ORM models use to turn class based fields into instance level descriptors.
class Model(models.Model):
field = models.SomeField()
rather than..
class Model(models.Model):
def __init__(self, *args, **kwargs):
field = models.SomeField()
super(*args, **kwargs)
Django is most certainly the framework that bundles a whole lot of choices together (similar to Rails), but the magic it performs on behalf of the user is extremely minimal.
I think your response shows why this is a great document. It's something any programmer can read and quickly determine whether or not Rails is right for them.
What do you use for Python debugging? I'm working on a large Python project coming from rails work and my biggest frustration is no equivalent to pry. I find Python debugging incredibly painful by comparison.
In terms of web debugging instead of general code debugging tools mentioned by others, the common Python frameworks have toolbars based on Armin's Werkzeug one:
PyCharm's debug tools are top notch. It's based on PyDev, which is an alternative that can be used independently in other IDE, but it's really the integration with the IDE that makes it a much better alternative than using, say, PyDev in Eclipse or vim.
Here's a brief overview of PyCharm debugging functionality:
I really like the ease of use for remote debugging. It's essential in helping to maintain a Linux development environment that closely resembles production while actually coding on a work laptop that runs Windows. Beyond that, I often use the remote functionality to run one-off scripts to retrieve and process data from a production Django system (though, generally this is restricted to 'read' operations unless it's been tested in dev).
Similarly, Python turned me off immediately when I tried to exit the REPL with "exit" and it goes "The way you exit is with control-D." It fucking knew I wanted to exit, and instead lectured me. WTF, Python? Seeya, dick.
That's because there's no magic in the REPL. You're typing nothing but regular Python code.
'exit' is an object. Expressions typed at the REPL are stringified. Thus, when you type 'exit', it gets stringified, and thus you get that message.
'exit' is also a callable, so if you type 'exit()', the REPL will exit.
The same goes for 'help', 'copyright', 'credits', and 'license': they're just objects that get stringified.
Having the REPL work the way you want would mean building magic into it, and magic avoidance is part of the language's culture, so that's not going to happen. Having it print that message is a compromise between keeping things friendly and building magic into the REPL, if you consider printing the result of expressions automatically to be magic.
The Python REPL isn't being a dick, it's being parsimonious and predictable in its behaviour.
Those assumptions that "optimize for developer happiness" 95% of the time make the developer's life hell the other 5% of the time. It happens often enough that "explicit is better than implicit", within reasonable constraints like dynamic typing, is one of Python's core values, and experienced developers usually come to appreciate it.
It's best to design an API that makes what's happening clear without being overly verbose or esoteric, and without making assumptions, especially not dangerous assumptions that may cause you to lose data (exit may close the REPL and cause you to lose your session when you forget that exit is a special word in REPL mode). My personal feelings are that Python has done a better job at this than any other major language. I have major projects in both Ruby and Python and I enjoy the Python ones 100x more because of this.
This document partially explains why; DHH is normalizing shortcuts because it helps him gain new users, even though working around those same shortcuts becomes a major PITA when you need to go a little bit off the beaten path, which happens in one way or another in most real software. There is a way to make these things explicit with only marginally more typing/"effort" (for example, requiring parens to call functions with no arguments, making it explicit and obvious when someone is referencing a variable vs. when they're calling a function), thus avoiding the complexity down the road.
> and experienced developers usually come to appreciate it.
I find statements like this a bit condescending. It's like when Java developers say 'Oh, that's nice, but I work on big applications." "Obviously you don't get it because you're not experienced. Experienced developers get it."
I'm sure that wasn't your intent. But it still irks me a bit.
I've been writing software for a very long time, in many languages and paradigms over the years. I believe that qualifies me as an experienced developer. My years of experience tell me that if I only experience pain 5% of the time, then the 95% of the time I don't experience the tools I use making me do extra work more than makes up for it. :)
>I'm sure that wasn't your intent. But it still irks me a bit.
Correct. I meant it inclusively, like most of the Python community is either experienced developers who've worked in a lot of languages and have sought refuge in the sanity of Python or the apprentices of such developers. Python doesn't have a figure like DHH to give it sex appeal, so not many new people use it.
There are definitely experienced developers who have not yet had occasion to seriously enjoy and appreciate Python.
>My years of experience tell me that if I only experience pain 5% of the time, then the 95% of the time I don't experience the tools I use making me do extra work more than makes up for it. :)
I meant this as a count of the number of issues, not the amount of time it takes to resolve them. That 5% of problems caused by non-obvious implicit magical behavior usually take an inordinate amount of time to debug and solve, and then the workarounds are usually disgustingly ugly because the framework had never conceived that someone might have a valid reason to circumvent their magic. Even worse, this locked-down, "looking inside will void your warranty" attitude (which Rails often calls "convention over configuration") frequently means that the workaround must be somewhat pervasive and ugly up your code not just in one place, but in several places to really resolve the problem.
Experienced developers may not encounter this often if they don't use a lot of magical APIs that promote the systemic ambiguity of "do what I mean".
> Even worse, this locked-down, "looking inside will void your warranty" attitude (which Rails often calls "convention over configuration") frequently means that the workaround must be somewhat pervasive and ugly up your code not just in one place, but in several places to really resolve the problem.
In 2005, when nobody used Rails, as a complete beginner to Ruby, I was able to write a patch to improve the Oracle database adapter. Somehow, despite all the magic, it took me very little time to find what to change and submit a patch. As a complete newbie to the language and platform.
Rails 2 and below revolved around a lot of hacks. Rails 3 removed many of those. Rails 4 even more so. Check out the book "Crafting Rails 4 Applications" to see how easy it is to hook into places in the framework to get what you need. (Disclosure: I'm the editor of that book.)
The argument you make about "voiding the warranty" is an argument I hear from people who have touched Rails for a project and hated it for one reason or another. It's not a sensible argument.
Remember, for centuries, people used "magic" to explain away something they didn't understand. :)
>In 2005, when nobody used Rails, as a complete beginner to Ruby, I was able to write a patch to improve the Oracle database adapter. Somehow, despite all the magic, it took me very little time to find what to change and submit a patch. As a complete newbie to the language and platform.
One part of the system not being obfuscated doesn't mean that many other important parts aren't.
>Rails 2 and below revolved around a lot of hacks. Rails 3 removed many of those. Rails 4 even more so. Check out the book "Crafting Rails 4 Applications" to see how easy it is to hook into places in the framework to get what you need. (Disclosure: I'm the editor of that book.)
I currently maintain both Rail 2.3 and Rails 4 applications. I totally agree that Rails 4 is a much smoother experience. There are still hacks around the magic that I've had to implement. The one most immediately on the top of my head is one of the form generators ignoring the method argument in some circumstances because it knows better and forcing me to jury rig them into obeying the command anyway (with a bit of JavaScript that alters the method on-page IIRC).
>The argument you make about "voiding the warranty" is an argument I hear from people who have touched Rails for a project and hated it for one reason or another. It's not a sensible argument.
Of course it's a sensible argument. Frameworks shouldn't be causing those feelings in people -- the magic isn't magical if it's getting in the way. If people are coming away with the impression that the system will blow up or otherwise misbehave when they try to peel back the covers, it's ignorance to just blame them for feeling wrong. One should try to at least understand the problem; then, you can decide if it's a problem that needs correction or if you're just OK with people who want some flexibility and cooperation from the framework not using your stuff and be honest about that so that they don't have to waste their time.
>Remember, for centuries, people used "magic" to explain away something they didn't understand. :)
And, also for centuries, people used "magic" to hoodwink gullible people.
> Yet the code behind the REPL knows exactly what I was attempting to do and tells me that.
Not really – all the code knows is to stringify objects, and it saw the object called `exit`, for which the stringified version is that error message. But nowhere in that flow does the code know how call anything that could exit the REPL.
/doesn't use Python regularly and thinks the smart move would be to make the REPL understand certain things as commands instead of normal Python code.
Well, the __repr__ method on the 'exit' object is getting called. So that method could actually call sys.exit() and cause repl to exit. But it would be very rude and strange behaviour for calling a __repr__ method to exit the interpreter, or, indeed, to do anything other than return a string representation of the object.
What someone more clever than me ought to do is write up a huge investigation of an obscure bug caused by exit.__repr__() calling sys.exit(), and then only at the end comment that it's not real, but could've been if Python went down this road.
If the REPL initiates an exit via throwing an exception (eg.g new QuitException ) and having the top level of the stack catch it then handle the termination, then you could have the stringification of exit throw that exception too.
It's not really magic at that point. It's not really 'magic' at that point to me.
Granted some people might say its surprising for stringifying an object to call sys.exit() or throw an error that'll cause exiting.... But within the context of the REPL its not surprising.
Whatever method you take, whether it's a special case after reading a line, or some other weird hack, you're adding magic.
With Ruby, this isn't a big deal because if `exit` is a function, then typing `exit` will call it, and you need to use the unary `&` to bypass this and have the callable treated the same way that Python does (which is roughly equivalent to a Ruby Proc).
Ruby doesn't require the hack, but Python would, for better or worse.
But also, how is bundling that explanation into the stringified version of the "exit" object not as magicky as Ruby putting an "exit" method on Kernel which is in the root namespace of the REPL and exits the current process (with an optional exit code)?
Slight correction, `exit` in IRB is actually not the same as `Kernel.exit` (as IRB actually allow IRB sessions to be nested, using `Kernel.exit` would quit the whole program rather than just the current session). It is actually an alias of `IRB::ExtendCommandBundle#irb_exit` that throws `IRB_EXIT` to stop the eval loop of the current session and allow some pre-exit hooks to be assigned to it.
Ruby's "exit" doesn't have to be as magicky owing to how simply typing "exit" in Ruby is a valid way to call a function with no arguments. The problem, if you can even call it that, is that Python doesn't have the separation between functions/methods on the one hand and procs on the other.
That is a critical difference that needs to be kept in mind.
Edit: grammar fixes. I didn't reread by comment before posting. :-/
Python 2.7.10 (default, Sep 8 2015, 17:20:17)
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit = "I'd like to assign a value to this non-reserved word!"
>>> exit
"I'd like to assign a value to this non-reserved word!"
1) Did they fix the thing where you had to use __self__ practically everywhere? Double underscored variable names also look like crap, especially when they're everywhere. It looks like a really shitty design flaw, having to use __self__ this and __self__ that everywhere. (This situation may have been ameliorated since I last looked at the language.)
2) Not everyone likes significant whitespace. But moreover...
3) If you code for long enough, you'll eventually realize that Ruby, Python, C++, etc. etc. are all fundamentally flawed due to OO making it too easy to write spaghetti-dependency code with mutable state everywhere, which means EVERY OO CODEBASE NO MATTER WHAT eventually becomes an unmanageable bugridden long-test-runtime complexity tarpit.
They should stop calling it "technical debt" and start calling it "object-oriented debt" ;)
So you eventually convert to the Functional Programming™ religion. ;) And that is the real reason not to use Python (or Ruby or Java or C), IMHO. But don't take my word for it, here's John Carmack basically saying that everyone should use functional paradigms (even in OO languages) if at all humanly possible: http://gamasutra.com/view/news/169296/Indepth_Functional_pro...
1) __self__? I don't think I have ever seen that. Are you combining two problems? All metamethods are quoted with dunderscores, and the first parameter of each method is "self", both of which annoy some people...
2) That is a reasonable choice. I like expressing myself once, instead of repeating myself in both whitespace and brackets or whatever, but I get the argument for autoformatting after copy/paste. Of course, lua does this the best, by having neither significant whitespace nor semicolons, and just figuring out where statements end from the grammar.
3) Objects are wholly optional, and can mostly be avoided. the functools and itertools libraries go a long way to bring the functional religion to python.
You should probably be careful there -- shared mutable state is the problem, and as Rust demonstrates, attacking the "shared" part can be just as effective (if not more so) than attacking the "mutable" part.
Both come with tradeoffs, but Rust's borrow checker seems, anecdotally, to be easier for people to understand than the category-theory word salad that litters most strictly-immutable FP language discussions.
I have seen showstopper, up-all-night bugs with BOTH shared mutable state (see: the reason it is nearly impossible to reduce a certain Rails app's test suite runtime below about a half hour without significant rewriting) AND single threaded mutability bugs (in one case resulting in me taking a month to fix a login bug that nobody else at the company was able to find out in over a year... It was a hash mutation deep inside a middleware affecting auth cookies)
A simple example of a single threaded mutability bug is passing an object by reference to a method which then (either intentionally or unintentionally) mutates the object, to the complete ignorance of the caller up in the call stack. The only thing stopping that is literally, programmer skill. No language constructs. At least in all the OO langs I ever worked with.
It's self, not __self__ (it has never been __self__). Double underscore names are used for special methods, which are typed relatively rarely, the most common probably being __init__.
Most Python code does not involve the creation of classes, so I think you're wrong to associate it with true OO message-passing languages such as Ruby and Java.
I really like IPython for that reason: it does what I expect. There's a bunch of magic, but they explicitly call it out as such. It's been built to handle that frustration.
I'm a Ruby guy that has tried Python several times. My takeaway is always that Python is beautiful and wonderful, but it just has all of these tiny little annoyances that build up and make me rage quit. Exiting out of the REPL is one of these things. I guess I spend so much time working with, and get so much work done in, IRB that anything that trips me up in a REPL just gets under my skin.
I really, really want to like Python, but I just can't seem to stay with it long enough to work through all of the "weird" stuff. :/
I think they did something to fix it, but back when I was investigating Python, it was useful to pass references to yourself to everything for some reason, so every method passed like __self__ to itself, it seemed like __self__'s were everywhere. Coupled with how fucking ugly (opinion, of course) double-underscored variable names are, it just did not give me a great impression.
You're wrong and you confuse two different things.
So called "magic" methods, which are called by Python in various circumstances, are surrounded by double underscores. One of such methods is __init__, which works as an initializer for newly created objects.
The other thing is that all methods, unless otherwise specified, take a pointer to the current object as a first argument. So when defining an initializer that takes no arguments from the user you write:
def __init__(self): # etc.
I think only __init__ and __name__ are widely used in Python, all the other such methods are very special purpose and very rarely used outside of deep library code.
BTW: Being "ugly" or not is not the best characteristic you can base your opinion of a language on.
Isn't it great that people can find the tool that suits them best? Now if only we could make it so people were secure enough in their choices and preferences that they didn't have to point out that they prefer X in a thread specifically focused on Y, we might avoid a bunch of needless gnashing of teeth and flame wars.
Seems like a reasonable critique in a thread exalting the amazing success of Y. I'm sure the developers of Y care about a newbie perspective of Y, and a comparison often serves as a good tool to show why something is confusing.
Maybe its because I'm a JavaScript dev, but I seem to clearly understand the critique (vs maybe if you are a Ruby dev it just sounds like "I don't like it"): too many built-in methods, lots of magic behavior, and an over-reliance on syntactic sugar. Seems pretty straightforward.
Possible non-code-altering solutions to the problems include: 1) limiting educational material on Rails to only use a subset of the built-in methods so that newcomers aren't overwhelmed by feeling they need to learn the entire std library before being able to make progress, 2) Using more explicit versions of code vs the more terse but harder to understand versions enabled by syncretic sugar to ensure that people coming from other languages first understand what is going on, then are blown away when they discover you can write it in an even cooler way, 3) a deeper explanation of what is going on under the hood to make the magic seem "OK".
I considered it an "I don't like it" post because aspects that the top level poster described are intentional features, not problems or issues that need to be fixed (at least according to DHH & co).
And I guess the word 'critique' connotes a somewhat more detailed, analytical assessment - at least to me.
I guess the perspective difference comes from having run and worked in open source myself in the past: its a better strategy to try to understand the pain point the user is facing regardless of how "analytical" the assessment is. A lost customer is a lost customer, and in this particular case, this seems to be a common critique. Given that the critique attacks as you say intentional features, that's why my mind went directly to the problem of education of the features. Perhaps this class of use is a lost cause: or perhaps this reflects a gap in the learning curve that could be strengthened.
Python and Ruby come at problems from different directions, and you have to go with the one that suits you. Python-philosophy says "explicit is better than implicit" and Ruby-philosophy says "convention over configuration."--at some level these are irreconcilable. If you want to work one way, the other way is not going to make you happy.
Well, we might as well get rid of the comments altogether if making a statement related to the content of an article is grounds to consider it "needless gnashing of teeth and flame wars".
I find people mostly tend to get defensive when they are being attacked. I think as long as people can police their own tone effectively, that it prevents discussions from devolving into something toxic.
I submit that anyone who takes the time to really learn Rails and how it works and the problems it solves will never want to use another web framework except for toy projects. It really is that good, and just keeps getting better every year.
It does one thing, web applications, and does it really, really well for the type of coder / team it was designed for.
People that belittle it by saying it has too much magic or whatever have never seriously tried to maintain a huge web application all by themselves. Web apps are ridiculously, mind-bogglingly complex, Rails conventions have been baking for well over a decade now.
If you're Twitter, maybe you have the resources to maintain a serious web presence without Rails. Everyone else is just handicapping themselves.
Most of the software I write nowadays is for business web applications (with a few things going on in the background), and yes for this market I don't think there is really any better choice than Rails.
Although it may not have every new shiny bell and whistle, the ecosystem is mature enough to be stable and to have developed accepted best practices, which means you don't need to worry about whether the tool you use is still going to be supported in 6 months time.
But the churn on gems is very painful. To be successful with Rails long term, you must make time to constantly upgrade your framework, for for too often a gem maintainer will just stop supporting older versions of the framework.
And all of a sudden the version you need won't build, or isn't compatible with something else, etc.
So Rails is great. It saves you tons of time and gives you rock solid web apps that talk to databases. As long as you don't fall behind in your gem versions. :)
That's me speaking after maintaining several apps from Rails 1 all the way to 4.2. And probably 5.
The thing about gem churn is somewhat true, BUT that is a problem in any open source eco-system that I've seen so far. And in fact I think Rails fares much better in this area than most others. There are a lot of very high quality gems out there that are actively maintained and play well together. Contrast that to the cesspool that is Wordpress plugins.
My solution for this is to never specify gem versions in my Gemfile and once a month or so do bundle update. Much easier to fix one gem update problem at a time than to try to fix 6 all at once.
I don't here about people being bug free with TDD ( though significantly less bugful)
Obviously all about tradeoffs, but my impression is that if a third party lib needs a major version update, the time changing the version in your requirements is dwarfed by the time needed to investigate generally
Yes my experience has been the same. It's definitely better now (i.e. maintainers seem to be caring about backwards and forward compatibility), but even 5 years ago there were a lot of popular gems that have now been abandoned.
It's still better than JavaScript, where whatever popular build tool you use today will be replaced in 6 months :D
Having used Rails seriously since it was originally made available as an open source project, I find myself agreeing with you less and less. It has really failed to stand the test of time, in my opinion.
I agree that it nailed the needs of web applications in 2004. If you are still building web applications like they did then, perhaps it is still the best tool. In the circles I find myself in, there is a push for much more Javascript heavy applications and Rails starts to become a large hinderance more than a help in that environment, when compared to other tools.
We've built a log of great software together over the years, but I can honestly say that I'm not going to rush into using it in future projects.
This is a bizarre comment. Rails failed to stand the test of time because it doesn't play very nicely with monolithic JavaScript frameworks? Are you asserting that such frameworks are the future?
I think they are referring to most UI logic being on the client, not on server. That architecture does not require a monolithic JS framework, nor does Rails offer anything special in that case.
This paints with an overly broad brush. It almost sounds like you're comparing Rails with the alternative of using no framework at all, but that's not the right comparison. I would probably agree with you if you had admonished people against bothering with any framework that hasn't been influenced by Rails. But most of its best ideas have filtered out into all the other ecosystems, and there are now very credible alternatives for lots of different stacks and some of those alternatives even perform better than Rails for different common use cases.
Exactly. I know Django and Rails... The Django admin is still a huge selling point for me even today. I can get some class of application ready and running in no time with Django. With Rails, with no built in supported admin app it would take me way more time.
I know there is many gems but I have still yet to see them used in the wild. My colleagues seems to avoid using them for some reasons and discouraged me to even try them. Maybe the strength of Django is having the admin by default so most Django app (gems) comes with a admin and those admins aggregate together in a coherent admin application.
I submit that you have probably never maintained a huge web application with a team over the course of years with Rails, or you'd probably feel differently. All of those things that seem like a great idea in Rails... aren't.
I sort of agree with you, in that if I was going to start a company I would totally Just Use Rails.
But I think that's just where Rails is in its lifecycle. We all learned a lot from it, and we've started to build alternatives, but nothing has really coalesced yet.
Flash forward 5 years and there will be post-Rails frameworks that have worked their kinks out and are starting to enjoy the network effects that Rails has. At that point Rails will lose a lot of its advantage.
I agree with a lot of this. My only complaint is the business layer has been lacking. I am using the techniques presented in the Trailblazer book and I am appreciating it.
I've been a Rails developer for 10 years now and I have to say it is still my favourite tool of choice (yes even in 2016). There are other interesting tools and frameworks out there (I'd love to put my hands on Phoenix and Elixir if I had the time) but for now I have to be honest: When I start a new client project I have to consider a few things:
* Using a well-known framework is favourable over new shiny toys in a commercial system
* An ecosystem that has good 'defaults' is essential. A single web framework won't do everything for you. You need stuff around that for testing, deployments, etc.
For mainly the reasons above Rails is still my primary tool of choice. Yes, it has pinpoints but the reasons above far outweigh the new and shiny.
I found Rails during the 0.9 releases. Coming from the horrific world of Java web frameworks like Spring and Tapestry, it was a revelation to see how fun and productive web programming could be again.
When I saw things like 2.times, 1.day.ago, and ActiveRecord, I knew I was done with Java web development. This isn't a knock against Java per se, but I just spent so much time in the trenches having to do busywork and configuration that isn't necessary if authors of those frameworks put programmer productivity and enjoyment first.
If you like static typing, then sure use something with static typing.
I don't however, think that the criticism that "one day when you have millions of users you'll have to migrate to another language" is useful.
Most startups will never make it to that level, and anything that saves them time in the beginning is probably worth it.
If the average developer is only 5% more productive in rails than whatever java framework you're using, it's probably worth using Rails until you need to migrate (all else being equal). That 5% now makes it more likely you'll reach the point where you need to scale.
So apparently .day multiplies the number of seconds in a day by the receiver, then .ago subtracts that from the current date[0].
However, not all days contain the same number of seconds. This is where "friendly" APIs like this lose me - they're vague and sometimes incorrect.
In Foundation, which I consider to have a decently designed date API, "dates" are doubles of seconds all since a reference date, and "date components" are used to express the concept of days, months, and years - which also require a time zone and a calendar to even make sense.
Rails does correctly handle `1.day.ago`, taking into account the number of seconds in a day.
`1.day.ago` is a perfect example of what DHH was saying, in that it looks beautiful, but requires a bit of work under the hood. `1.day` creates a duration. This isn't just a number of seconds, but is represented by hash, more like `{:days=>1}`. When it's time to do the actual math, Rails looks at the :days number, and actually moves the day part of the date forwards and backwards.
So if it actually matters, you do a better implementation. Or hack the Rails code and share your improvement back to the community.
But the fact is, in most circumstances, good enough is good enough. And making programmer's lives easier is generally more valuable than corner-case optimization that makes things really hard to implement and understand.
That's a problem of implementation, not API. It could just as well instatiate a generic Day class that would know how to add itself to different dates.
I recently wrestled with the idea of using NodeJS for any side projects. I touched Ruby/Rails in the past for a few times (on-off between small works) and never really felt excited or see it as something "beautiful" because at the end of the day, we, developer, still have to debug our own buggy code.
After a few strings of drama in the NodeJS land, a few chat with friends who used NodeJS in production, and seeing the pattern of BigCo who use NodeJS only for glue/front-end/gateway appserver, I'm pretty close to settle with Rails.
I admire DHH for his dedication to the framework for so long (since 2004). You don't see that type of dedication in the NodeJS land. Yes, NodeJS is still new, but a few BDFL/leaders of important NodeJS projects had left the boat already. One of the premier NodeJS vendors, StrongLoop, always mired with controversy (I happened to know a few people who worked for a company that was acquired by StrongLoop).
Building long-term side-project requires a stable platform because of the time limit (outside office hour + other responsibilities). Dealing with unstable but "sexy" technology is not a good choice.
I think DHH has realized that Rails has a bit of an "image" problem when it comes to new web app development, and this is a way to lay out why Rails remains relevant and even desirable. No doubt some will take exception to some or most of his points, but that's OK. For the rest of us who thrive in continuing to build with and evolve the Rails ecosystem, it feels good to see a renewed focus on communicating just what makes Rails (and Ruby) special and vital.
For those that are interested in a more performant and scalable Rails-like experience I encourage you to check out Phoenix: http://phoenixframework.org
We have been working with Elixir (the language Phoenix is built on) for over a year. It is an incredibly satisfying language and its toolset is surprising advanced for its age. Phoenix has been a very easy mental jump for our developers who were already trained on Rails.
To add another side to this coin, having recently used Phoenix to write an api after hearing good things, I found Elixir clunky, and Phoenix poorly documented. It tries to be too much like Rails (I realise this is the point, though), and is currently failing spectacularly in my opinion. YMMV obviously.
In the spirit of making our docs better, what did you find poorly documented? We go to great lengths to have extensive, comprehensive docs. Pick any module in our source, and you'll find extensive documentation on usage, APIs, etc. All docs are extracted to hexdocs.com as well
http://hexdocs.pm/phoenix/Phoenix.html
This is in addition to our separate online guides focused more on getting up and running through the basics. Where did we lose you?
This attitude has been shown by multiple people involved with Elixir/Phoenix from what I've seen. I'm impressed and though I'm not using Phoenix, I am very interested and that general attitude of "where did we lose you" has really raised the language/framework's status in my mind. I'm a Pythonista and feel more coerced/shunned by the leaders of that community, to the point where I feel like I'm somehow "part of the problem".
I definitely see Phoenix/Elixir in a positive light and at some point will give it a fair shake for myself.
I think the Phoenix/Elixir docs in general are quite good, it's just the lack of years of blogs and stackoverflow q&a that makes it harder to jump in. Switching from Ruby's OO/functional to Elixir's purely functional/immutable/actor-based would be easier with more of other people's code to read and learn from.
I'm a complete n00b and was just trying to get a pool of TCP client workers to monitor servers and update a DB and display the results in a Phoenix app, and I kept coming across the same 4-6 blog posts and docs, maybe 60% of which were for pre-1.0 Elixir and no longer quite worked.
I see a huge amount of promise with Elixir/Phoenix as well; currently it makes some hard things easy but also many easy things hard. With a few years of library/community growth I could see it wiping the floor with Rails for a lot of projects.
Hi! It was a few things, but a while ago so can't remember all of them. An example was creating a migration. I had to rely on a blog post from about a year and a few versions of Phoenix ago to get the Cli commands just to add a column to a table. Appreciate now that it is probably in the ecto docs, but that's not really made clear anywhere and even then I didn't find them easy to navigate.
Your docs in general are pretty good and comprehensive, I just felt like a few obvious things had been overlooked.
flashm - Thanks for taking the time to provide this feedback. Sorry if we lost you then, but hopefully we won't if there's a 'next time'. We've created an issue on the Phoenix Guides repo about this (https://github.com/phoenixframework/phoenix_guides/issues/46...), and as part of our work and the Guides we'll double check and make any revisions needed to help to make certain that we conver these topics clearly/thoroughly.
Chris, i want to have docs for phoenix + dependencies on a single page, globally searchable. Well, found it after some googling: http://i.imgur.com/qGh980D.png (http://devdocs.io/)
It was the real problem - hard to find where * method is located
Any time I've gotten stuck in learning Phoenix, I've found the community to be generous in offering advice and solutions. The documentation is good, but if it fails (or you just don't know where to look), Slack/irc/Google groups are a great bet.
Now that Rails isn't the cool new thing anymore, is it still a good choice for new projects?
For the new year, I'm thinking about the programming landscape and contemplating what I want to learn next. I've tinkered with Ruby on Rails in the past and think DHH is on to something with the doctrine he has laid out. I've only scratched the surface of Rails, but it still seems pretty neat to me. A deeper dive would be fun.
On the other end of the spectrum, Dart + Angular is appealing in part because I'm a fan of some of the Google developers working on Dart. While Rails feels like it is entering a comfortable middle age (or at least adulthood), Dart feels a little like a car being assembled as it cruises down the interstate. It's new and maybe a bit dangerous.
Both projects are super-appealing to me. Unfortunately time constraints prohibit me from chasing both and I'm interested in opinions especially of Rails people. Are you still excited about it?
I didn't learn Ruby/Rails back when it was the "cool new thing" -- I resisted and tried to wrestle PHP to my liking. Eventually I gave up and threw my hat in the ring, and I'm so glad I did. My advice is to learn Rails first, and then take all the wonderful things you've learned and apply them to other languages and ecosystems if you wish (many libraries and frameworks for Javascript and other langs are inspired by Ruby or Rails). I don't think it's as valuable to attempt the reverse...
When doing projects on the side, I like to play with node.js or Elixir but when I have to develop projects for paying customers, I tend to gravitate towards Rails...
Few reasons for that:
1. I'm extremely productive and fast at developing in Rails
2. It's much easier for the client to get an app that's develop for a Framework that's been there for a while, is stable and will continue to be there
3. Ruby is a nice language and the principles behind Rails resonate with me (so it's not like Java and Spring which I was eager to get rid of when I switched to Rails a bit over 10 years ago)
That doesn't mean that I don't use node.js for certain specific use cases on client projects... But my goto framework is Rails
I'm not sure I understand why "comfortable middle age" is a negative.
Unless the argument is that Rails has either a) accumulated damaging cruft or b) missing out on important new features/paradigms, "comfortable middle age" seems like a huge selling point, right? Battle-tested, mature, a huge amount of shared knowledge, etc?
I didn't intend for that to be a negative, just that it's a different point in it's life.
I'm not trying to make any argument about Rails, but am very interested in your opinion. Has it accumulated cruft? Is it missing something that newer frameworks have embraced?
I've been programming Rails since 2010, and still feel like it's far-and-away the most productive I've ever been for turning SQL into HTML and then user actions back into SQL. If your task is SQL into HTML and then user actions back into SQL, with a few "sprinkles" of Javascript on top of it, Rails will not steer you wrong.
I have also recently been doing, for the first time in a long while, work which is not SQL into HTML and then user actions back into SQL. Rails was never seriously considered for that part of the project. This was the correct call, and the new stack (GoLang and React) are fun things to have in my toolbelt, but there have been a few points this year where I've said "I just spent two hours on something which would have been 4 lines in Rails and I'm not sure I'm done yet."
> turning SQL into HTML and then user actions back into SQL
You've really distilled it to it's essence and that has given me a lot of clarity.
The company I work for uses an issue tracker written with Ruby on Rails (Redmine). There's a few things I'd like to change and so I think I'm going to spend the first part of this year getting comfortable with Rails and making a few changes to Redmine that I'd like to see. Then, I might transition to Dart and see if I can put together an interesting browser-based client.
Rails is an awesome framework to develop in. For me, however, it is less about Rails and more about the community. Take for instance the popular Ruby job processing system, Sidekiq. It integrates very easily into Rails and makes that whole async job thing painless. I haven't seen anything as sophisticated in other languages. ActiveModel is also a very nice library to work in, and having it by default is nice.
I personally do Rails backend + Angular frontend and it is a very rewarding stack. I get the power of Angular, but the simplicity of Rails in the backend. DHH is wholly against that, but it works really well.
It's a good question and it's really what I'm asking about.
The only web-stuff I've worked on in a commercial settings was a long time ago using Java and Tomcat. At the time, it was the cool new thing. I think that some of the pain points of languages and frameworks from that era are what prompted DHH to develop Rails (I'm specifically thinking about convention-over-configuration and admit I could be totally wrong here).
So today, I probably wouldn't pick Java and Tomcat for a personal project just because I know it won't be as fun and I won't be as productive as I would be with different technology. Has Rails been eclipsed in a similar way?
I'll pick Java, SpringMVC, Maven, JUnit+DBUnit, and FlyWay (DB migration) and any appserver (jetty, tomcat, TomEE, glassfish) thrown at me except from the BigCos (WebLogic, WebSphere).
Those tools are pretty close to what Rails give you (notice the View/UI is open for anything... Rails View is slightly nicer as it has better templating capabilities but ... not a deal breaker for me).
It's not sexy, it gets the job done, and I know it'll run for at least 5-7 years with minimum hassle.
Plus it's easy to be productive on Java project...
Upvoted. I am tired of getting the "uncool old fart" looks every time I propose similar stack. You CAN do cool stuff with established tech plus have a peace of mind that you will not run into any "surprises".
It makes total sense to mitigate risk on a commercial project by going with established (well supported, well understood) technology. No argument. But for a personal toy project where you want to be surprised, would you choose something like Ruby on Rails?
Yeah I got trashed karma wise on a previous comment explaining how I had to port some Ruby apps to Java. I don't even care that much about either technology but just mentioning that I had to port something to Java earned me -4.... seriously.
My own bias is to pick the best tool for the job, and not risk hype dictating your decisions. If you're learning for fun and personal learning, that' s great - just realize that you should optimize differently.
I’m running a team of developers where we are using Rails as our first-line tool, but we are also committed to using the best tool to solve the jobs at hand. So far, we have only needed to add Lua for a small piece of what we are doing because we can reason about what our logic is supposed to be doing quickly and easily in Rails.
Less than a third of my team were Ruby or Rails developers before joining us, and we are always pushing forward on learning more so that we have a great bucket of tools available as we try to solve our business problems and we hit those things where trying to reason about the problem is difficult in Rails, or where performance matters more than readability and code clarity.
For those of us who were stuck with the JVM, fortunately there's now Grails (obviously modeled after Rails). Groovy makes programming for the JVM fun IMO.
I've used Groovy/Grails for a number of web apps, both in commercial settings and side projects. Since I had previously been doing a lot of Java, being able to leverage the existing Java ecosystem and libraries with Rails-like productivity was a huge plus.
I wouldn't say I'm stuck on the JVM, I actually prefer building web apps with Grails.
Grails may have a small community, but it makes Java web development really sexy. And I write 50% of my Grails code with Java. Groovy is ok, but I prefer the excellent IDE support I get with Java.
"Stuck with" was probably not the right wording. Where I started with Grails in an enterprise environment, Rails would have been a non-starter (or at least a much tougher sell) because operationally we were a Java shop. With Grails, though, it's just another WAR to drop in your servlet container, so operations doesn't really care.
Which IDE do you use? I find IntelliJ to have great Groovy support. Also, you can optionally type check Groovy, which helps even more.
I use IntelliJ too, and I use static typing and @CompileStatic all the time. I'm not complaining, just being nitpicky. I don't see the point coding Java style with Groovy. And that is in my opinion Groovy's biggest strength, that a Groovy and Java class can work great together. A class written in Groovy works just like a Java class in Java and a class written in Java works like a Groovy class in Groovy :-)
And I'm a big fan of using Groovy when working with JDBC.
slightly off-topic: there's plenty of new Java frameworks out there that can be pretty productive and "fun" - mostly the Sinatra-style ones (Spark, etc) and stuff like Activejdbc for ORM. Plus, there's fun languages on the JVM that allow for less verbose code without going dynamic - eg Kotlin or Scala.
This probably sounds pretty stupid, but once Oracle (or was it Sun?) started bundling other software in the installer that I don't want, I was done with that language. Then Oracle started claiming the Java library API was their IP and protected by copyright. Ugh. I'm probably not going to go back to Java again.
> Now that Rails isn't the cool new thing anymore, is it still a good choice for new projects?
It's probably the best choice for a straight-up CRUD webapp (as was always the case). I wouldn't want to do a project with nontrivial business logic in an untyped language these days (having seen how little flexibility you have to sacrifice for safety in a modern typed language), but your views may differ.
Agree on CRUD, but on typing I'm the opposite. Anything sufficiently complex logic, especially etl or projects with multiple models of the same entity, is easier for me in a language with duck typing. It's just amazing how all our brains adapt slightly differently to the different sorts of problems we face and the bag of tricks we use, in addition to the different languages and tools.
Ad-hoc polymorphism (traits/type classes) and parametric polymorphism (generics) largely solves this, whilst giving you a high degree of confidence that your code correct at compile time.
I've found code written in a duck-typed style brittle and hard to refactor safely - it's very easy to try to restructure something, then find out down the line that something blows up because of some incorrect assumptions in another part of the codebase. You can try to grep for all the method usages, but that is a laborious, error prone process in codebases that are sufficiently large enough.
I feel bad for anyone who has to swim in your wake. People who embrace dynamic typing generally create write-only code that no one can maintain, since they labor under the delusion that little things like clarity of purpose are a waste of time.
Duck typing vastly reduces the amount of code one has to write that does nothing, making the purpose of the code much more clear. The tradeoff is in compilation, not clarity of purpose. The code tends to be more flexible to changes in the underlying data, as it is easier to modify!
A sad example of those defending static typing are the Java programmers. I point out that Java supports duck typing via reflection, even if the syntax is painful. They say they don't use reflection, they use Spring. [Head in hands]
In any case, there are many happy programmers in my wake, they don't need your sympathy! :-)
> Duck typing vastly reduces the amount of code one has to write that does nothing, making the purpose of the code much more clear. The tradeoff is in compilation, not clarity of purpose. The code tends to be more flexible to changes in the underlying data, as it is easier to modify!
It's much harder to make changes because even something like renaming a field requires major testing. You end up writing much more code that does nothing, because the test coverage you need for everything is much longer than the type annotations that would give you the same level of confidence, and whenever you change anything you have to update all your tests by hand. Hope you get the data model right first time! Look at one of those videos of people refactoring Haskell for what a type system can get you.
> A sad example of those defending static typing are the Java programmers. I point out that Java supports duck typing via reflection, even if the syntax is painful. They say they don't use reflection, they use Spring. [Head in hands]
If Java is what you think of when you think of static typing, I don't blame you for hating it. If Java-style typing and duck typing were the only options I'd use duck typing. But there are much better options out there. When I write Scala, most of the time my code looks exactly the same as what I'd write in Python.
Yeah, I got my first exposure to the dynamic side of Java half a year ago. Its honestly not that difficult to deal and the shit it can do is pretty silly.
Field field = instance.getClass().getDeclaredField("secretField");
field.setAccessible(true);
System.out.println("The old private value is " + field.get(instance) + " but lets change it!");
field.set(instance, "new value");
I would say yes, as long as you're building a greenfield project that is a database-driven web application, where your priorities include high productivity and quick time-to-market. It's basically been the default choice for web startups for several years now, lots of startup devs know it, and there are battle-tested libraries available for just about anything you want to do with it. And it is still aggressively adding new features, e.g. first-class support for websockets just came out in rails 5.
Rails certainly is mature, its APIs are not stable at all. With every version,even minor, there are annoying changes that often break 3rd party plugins. It shouldn't happen. That's why JEE has specs, as heavy as they get 3rd parties can always refer to them in order to write custom code. Rails is anything but stable. Hard to complete a single tutorial online without running into API issues.
I got my first error right after `rails new myapp` and `rails server`. After some Googling I found out that apparently I had to install Node.js also, but the error message wasn't very clear. This was the official 'getting started' rails tutorial on the rubyonrails.org site [0].
Well, you need a javascript runtime, eg you could install nodejs, that's what the error says. I agree that it might be confusing as a rails beginner, but Rails uses it to convert CoffeeScript files and for minifying and merging all JS stuff into one file.
It depends on what you want to build. I find nothing novel in either tool, so I don't think it's good to learn in a mind-expanding sense. For building medium-sized external-facing apps, rails is one of the better choices out there. For building long-running client-side applications, angular isn't a bad choice (though I prefer Ember for that constraint, personally.)
If you live in the land of Oracle or other proprietary databases, I wouldn't suggest rails. It has some rough edges in my experience. Otherwise, I think you should find a project and run with it, or join a place already in the rails ecosystem. I wouldn't learn it for its own sake.
About picking the "Best" tool for the job. One annoying thing about Stack Overflow is that they aggressively stop those types of questions with their mod system. Just understanding the Pros and Cons of the major options is very valuable, but not allowed.
I could not agree more. I think they tried to promote other sites in their network for this sort of discussion but as far as I can tell none of them really caught on the same way.
A number of my open-ended questions about picking tools/libraries have been [CLOSED]. It really bugs me. I think there's such a valuable need there; you pick a dev tool and it may have maintenance and development consequences (repercussions is perhaps a less gentle way of stating it) for years or perhaps decades. It really impacts everything. We need to find a way to evaluate tools in a dev-friendly manner, keeping in mind that no dev ever has full time to really read and digest the docs they come into contact with, at least in my experience. (Peter Norvig has some apt statements about the realities of dev time management in his Coders at Work interview, IMO, which could spawn another discussion).
About SO, it's just that this isn't the goal of SO. The goal of SO is asking a precise question and getting a specific result, it's not a place for debate or opinion.
Quora could have been that place, for some reason and because of some odd UX choices ( mandatory signup to browser the site ) , it isn't , which is too bad.
So it would destroy SO if, in the context of programming, there was a best of question? Are they really that tight-assed? Do they not have the bandwidth? Really, I'm curious how those questions would hurt the site. And Quora? Why would SO prefer users to actually go somewhere else? Debate and opinion, despite what the moderators think, is a valuable part of coding. It isn't all "solve for x."
Because the interesting thing about the 'ask a specific question' concept is that some questions are closed because they're too specific. I pretty much abandoned SO. The anal retentive pendants moderating things have turned me off to spending any time contributing.
The strict moderation and categorization is what makes stack exchange useful in general.
Why not use a free-form forum like Reddit for that kind of question? Because you know the answers are going to bullshit opinions and holy wars, mostly by people that are trying to solve different problems than you, or are actually less knowledgeable than you.
Given the fact that Reddit and similar forums suck for finding solutions to specific problems, why should a Q/A site that is good for finding solutions for specific problems try to emulate it?
Quora and Yahoo answers also suck because the questions are almost entirely anecdote and opinion based, and it seems to be acceptable to cite "experience" as a source for bullshit opinions. "Being a pilot with 10 years of experience" is not an adequate reference for a response to a question about the safety of using a cellphone radio on a commercial flight, nor does "being a veteran" count as original research into Iraqi popular support for the 2003 invasion.
Of the good "answers" from Quora that I've seen shared, all are basically long form blog posts that have found a "close enough" question to answer, rather than been motivated by the question, and I would have actually preferred to read them on medium or some other blog site. However interesting they are, they aren't answers.
I think projects like Rosetta code are useful for comparisons of programming languages, because they keep it concrete.
You can also look at big high-quality projects on github or whatever and directly judge the subjective qualities of a language for yourself, based on how readable the code looks to you.
> So it would destroy SO if, in the context of programming, there was a best of question? Are they really that tight-assed?
While I doubt it would destroy the site, it's extremely hard to moderate and clean up giant debate answers. StackOverflow was never advertised as a "programming/coding catchall" site, it's a very specific platform tuned to very specific needs, much like an equation, giving a tuned answer for the question. Open-ended questions are beyond the original scope of the site, and StackOverflow has grown to become the largest coding question platform as a result of it.
I was just singing praises to Rails last night for these reasons.
At my corporate job, we use Java with Spring, and a hellish mess of node packages/libraries/whatever we're calling them now. It's not good.
So when I do side projects or consulting gigs, I always run to Rails which is what got me into development. It's very refreshing.
Reminds me of the jQuery post the other day. Rails is just a little older than jQuery. Rails with some jQuery sprinkled in is as close to development perfection as I've ever seen.
Also re: "too much magic" - Why is magic a bad thing? Creating layers of abstraction to ease building is what programming is really about, right? Why would we want to go backwards to configure everything under the claim of "I need to know how EVERYTHING works!"?
Sometimes (performant) SPAs provide a better user experience than regular views strung together with Ajax/jQuery. But otherwise, I agree. Rails and jQuery were probably the first truly "nice" APIs I've used in programming, and I still get quite a bit of enjoyment from using them, to this day.
This is actually a SPA and a bunch of strung together jQuery. But things subjectively feel "faster" compared to what the site was like before they upgraded to this model.
There is great stuff to say Ruby and RoR. But I have yet not experienced the "smile" that DHH is describing. Especially when I have to read and understand the code written by colleagues (or myself mind you).
To do my job I had first to become a master in grep to find where stuff come from and deciphering half assed documentation. Mostly because exploring objects with hundreds of methods is not my cup of tea.
I also enjoy understanding my tools, and RoR is, in my experience, not particularly easy to understand. This doesn't put a smile on my face.
batiste, I think what you are describing is that the culture around Ruby doesn't put a smile on your face, rather than just Rails.
Ruby's philosophy is quite a bit different from Python, Smalltalk, Perl, Java, and PHP. Ruby is roughly described as "batteries included." Some people don't prefer this, as it encourages meta-programming and introspection rather than explicit instructions.
A lot of libraries and tools around Ruby use meta-magic; some libraries have been attempting to strike a middle ground with meta magic, such as Datamapper (explicit) vs ActiveRecord (implicit). But the bias is definitely towards implicit; or as what DHH calls "omakase."
Lots of people don't like maintaining other or former colleagues' code, especially when the codebase starts turning into a legacy one. This is true in every language.
There are several solutions for this, but I personally take the easy way out: quit your job and be the first developer in a new startup, or do some freelance work. Whatever you need that floats your boat
> Where Java championed forcefully protecting programmers from themselves, Ruby included a hanging rope in the welcome kit.
I don't think this is something to be admired in a language. Java is a bad language to work in because it's not expressive, not because it protects programmers (which it doesn't).
Thankfully, we are seeing this shift the other way with the growing popularity of languages like Rust and Swift.
Java is a bad language to work in because it's not expressive, not because it protects programmers (which it doesn't).
Compared to C/C++, yes it does. Java protects you from out-of-bounds array access, uninitialized access, buffer overflows, use-after-free, double-free, etc etc.
Memory safety is a protective feature as much as sending texts is a smartphone feature. Sure, it is nice and very useful, but almost all languages provide it, so it does not count for much these days.
Thats how it should be, but the frequency of C/C++ threads on HN and the discussions about memory safety that will inevitably follow unfortunately paint a different picture.
God I hope Rust will shoot C++ in the backyard and put it out of its misery.
So, basically nothing in real world domain. The protections are basic at best. The most common errors are runtime exceptions, zero protection offered. YMMV.
The Heartbleed Bug[1] sure felt like a real world domain problem to me. If OpenSSL were written in a memory-safe language like Java it would not have happened.
I'm sure the OpenSSL devs could've figured out some obscene way of messing with the JVM to make it happen. You know just in case you needed to cross compile it for Windows 3.1 using VMS or something.
"Ruby included a hanging rope in the welcome kit" is very poor wording.
There's advantages and disadvantages to flexibility. I personally think there's tradeoffs that need to be balanced. But even if we accept the assumption that more flexibility is always a good thing, the wording is still poor.
That wording vividly and convincingly explained the exact reason why too much flexibility is a bad thing, rather than the good side of it.
If the author happens to read my comment, I recommend a rewrite saying something about trusting developers or maximizing their power instead of giving them a tool to metaphorically kill themselves.
He/she probably means that Java is a language where relatively simple ideas often must be expressed in a needlessly verbose way. Needless verbosity affects a language's quality because it clutters the code and hides the main ideas behind incantations and boilerplate.
I've written old Java (C++ like), enterprise Java, Android Java, and currently am writing modern Java. From Android and forward there have been improvements in verbosity and boilerplate. Modern Java (8) is actually nice. Yes, the enterprise code is still approaches a rude goldberg machine level of complexity and verbosity but that is changing. Frameworks like spark simplify the web side, and projects like Jhipster (horrible name, great project) automate a lot of the boring work and provide a good base to work from.
At the end of the day, verbosity in Java is mostly due to its ecosystem. Its quite different than that of smaller languages like Python, or Go. Where there is a community wide effort to share code and make things simple. Not so in Java.
Still no type inference, pattern matching, or ADTs. In a statically typed language that causes lots of verbose ceremony that shouldn't be needed in the 21st century. We've known how to do this stuff for decades.
That said, I would take Java's verbosity over Ruby's lack of static types. I write Ruby in my day job, and refactoring is a pain, and the same old type errors keep popping up day after day, causing 500s in production. It seems no amount of TDD can prevent them.
Agreed. It does cause lots of verbose ceremony, as you put it (I'm stealing that). Its quite the experience using a Java IDE and noticing how much code is automatically included by pressing tab. Quite comical that Netbeans has shortcuts words for printing to terminal.
Your second point really hits home. I've been battling with Python and runtime types. Its just the nature of the beast. That's why I've been focusing more on languages with solid type systems. I will happily trade verbosity for types. :)
Yeah, Java 8 can be quite clean and expressive. The biggest problem with Java 8 is the lack of support for the new features within the extensive library ecosystem. You either have to revert to using horrible, old, and verbose patterns, or abandon many of the libraries which, to a large extent, are the reason Java is so useful in the first place. I am not convinced this will ever be fully fixed; the burden of legacy is just too great.
One of my biggest complaints is that core libraries and most popular libraries do not support method chaining, builders, or factories. This makes for extremely verbose object creation and configuration. Similarly, the static typing syntax is one of the most verbose in existence. Another problem is asynchronous is hard, anonymous functions don't exist, and you have to resort to abstraction and design patterns in order to achieve what I would deem basic functionality.
I've never been more unhappy programming than when I touch Rails. I'll take python or Java any day of the week.
>Convention over Configuration
Discoverability is totally gone. Walking into a brand new RoR app and it's next to impossible to figure out what's going on. Not having a good IDE doesn't help.
I come from Java/JEE and I would choose Ruby any day of the week. Some former colleagues had bad Python experiences. Some others have their first working experience in Ruby and want to go somewhere where the grass is greener.
IMO what makes programmers happy is not so much a programming language in particular but rather the context surrounding the job: role in the team, age of the codebase, fun colleagues, level of "corporatism", good or bad management if any, how much code you are able to ship per day, etc.
My background is Python, C#, and SQL, and it shows because those languages have affected the way I think about programming.
I strongly disagree with DHH's points 2,3,4, and 6. But I think I'm going to learn the language anyway and use it for some projects because I think it's important to not get in a rut. Using different languages changes the way you think about code, and if you are not constantly updating the way you think about code, you are falling behind.
Besides, I really like the way DHH writes. His language is persuasive even when I quite certainly disagree with him.
Still going to learn a functional language first probably. But then Ruby/Rails.
A tad bit off topic, but for your functional language I'd recommend Haskell. It's given my mind the most trouble out of any of the other functional languages I've tried (which is a good thing). I find it's syntax reasonable, and resources plentiful.
Excellent lecture series on functional programming (language used is Haskell):
Thank you for this. Much appreciated. I have a copy of learn you a Haskell for great good and have been slowly working my way through it in my occasional spare time.
Also interested in F# these days now that Microsoft seems to be open-sourcing . . . pretty much everything.
Learn you a haskell for great good is also a fantastic resource (that I should have mentioned) -- I also worked through it, and found that it was a good not-boring introductory text. It strikes a good balance between being informational and playful, while offering the examples and exercises that you'd expect for building intuition.
One of the rare books I read online (completely free from http://learnyouahaskell.com/), and liked so much that I bought a hard copy to carry/read.
I transcribed an interview with DHH [0] in which he also explains his motivations for choosing Ruby (instead of PHP or Java, for example), and where he explains some design principles for Rails.
"One example I always pull out is “what you gonna call the primary key in your tables?” When I was working with PHP and Java, every single shop, almost every single application, would have its own naming scheme. Some would say they have the ‘Products’ table and then they'd have ‘productid’, others would have ‘product_id’, some people would have ‘prod_id’ or ‘p_id’ or ‘P_id’, and every time somebody made a new design decision it meant configuration. You now have to tell your models, your objects, how they're going to talk to this database table. Because it needs to know what the hell you called the freaking primary key column, and it just doesn't matter! Who cares what the primary key column is called? It just doesn't matter. It's going to have zero impact on the usefulness of your application."
and
"‘Dont repeat yourself’ is all about not having the same intentions spread out in multiple places. Don't have one configuration. If you're calling something, let's again take the example of the primary key. If you're calling that for ‘id’ you shouldn't have to configure that in three different places that all have to work together and all have to be changed together. You should just pick one authoritative place to have that information stored. And then you can make changes from there. It also goes with the the whole Ruby idiom: we don't want those Java boilerplate ten line things: that's repeating yourself. If you have the same idiom, if you have the same intentions, that should really be exceedingly a short expression. And that goes up throughout the entire framework. Just keep one place to change those things, and keep the idioms very short."
The interview is from July 2009. I think Rails already had its ORM then. DHH says:
"The model part in an MVC application is where all the business logic is kept. Those are all the classes like ‘Post’ and ‘Category’ and ‘Author’ and all those things –say if you're making a weblog– you'd keep all that stuff in the Model. And you'd have all the logic about whether the author is allowed to make a post and how the relationship between posts and comments work together. Those are all sitting in the model, so that's all the business logic, very often backed by a database in some sense, not always, but most of the time. And that's where in Rails we're using something called ‘ActiveRecord’. Which is this way of mapping database tables to objects, and then decorating those objects with logic."
It is funny how small things affect your future. I did a lot of stuff with rails back in 2007 or so. However I really got fed up with it because some things were so slow. So for the next project I decided to pick up django, and I've been using django since then.
Would it have made much difference if I had staid with ruby/rails instead of python/django? I dunno. Many of my friends have careers with rails, and they have nice careers. I have nice career as well, as do many other friends with django. In the end they are not that different, I guess.
If you like the Rails Doctrine, check out Phoenix Framework and Elixir language by the former Rails Core Developer Jose Valim. You'll get hooked as you did with Rails 10 years ago.
People can have valid, informed opinions even if they aren't rich bigshots with fancy titles. Distinguishing people according to how many years they have been pushing buttons in the industry and talking themselves up as "A players" really doesn't mean anything.
Mature Ruby projects are very difficult for a new Ruby programmer to parse and understand. In contrast, Go projects are quite easy to understand.
DSLs are part of the reason for this.
Naturally there is a tradeoff. People that have been working with a particular DSL in Ruby for a long time can achieve amazing things in a short amount of time. Equivalent productivity is not really possible in Go (at least not yet, in my experience).
Having said that, I think it is easier to onboard new (and newbie) programmers onto a Go project than a mature Ruby project.
Having been working with Rails for a long time, now I wonder what could be the next cool thing looks like. The only improvement I'd like to see is about performances, and Elixir and Crystal are a good candidates to replace ruby in this direction. But until now, I don't see any other framework equaling the elegance of Rails, great job David and all the community, let's continue to keep Rails weird.
I personally prefer ASP.NET MVC, it has all the core parts of early Rails (back when it was nice and simple), and it's statically typed to boot.
The most magic thing in .NET MVC is Entity Framework, and all it's magic is either a bunch of strongly typed convention classes (of which you can create your own), or LINQ queries, which work pretty well.
If I'm building stuff for Adults with Money I'll choose static typing any day.
This is easily described with a contrast to Python. [...] Ruby accepts both exit and quit to accommodate the programmer’s obvious desire to quit its interactive console. Python, on the other hand, pedantically instructs the programmer how to properly do what’s requested, even though it obviously know what is meant (since it’s displaying the error message).
When you're trying to convince me that your programming language is great because another one is so much shitter in comparison, you're on the defensive and basically telling me you don't trust your own stuff. Especially when this is at the top of your article.
By the way, python handles your example very gracefully in comparison to other REPLs (for instance, node spits out a cryptic, but expected traceback on exit/quit)
He didn't say Python was bad in comparison. He just highlighted a simple example of coding to spoken language expectation even if it means aliasing. It's a minor example of trying to make the development experience more enjoyable, nothing more.
> pedantically instructs the programmer how to properly do what’s requested, even though it obviously know what is meant (since it’s displaying the error message).
As others explained exit is an object and just typing it's name is just calling the __repr__ method. Exiting the program on a __repr__ would be setting an horrible example in the mind of a Python programmer: it's oki to execute program ending code into the representation of an object.
So no, nothing pedantic about setting reasonable expectations about a language... In python if you want things to happen you have to use parenthesis.
Did you read the quote? He very exactly says that python is bad in comparison - by using a concrete python vs ruby example.
If this was a passing mention on some blog post, I'd be inclined to believe you, but this post is not like any other. It's a descriptive update of the current rails "doctrine". When I ask you "why is your X so great" and you tell me immediately "look at how bad Y does", I'm inclined to think you're not feeling very secure about X.
> Anyway, what did this mean for Rails and how does this principle continue to guide its evolution? To answer that, I think it’s instructive to look at another principle that was often used to describe Ruby in the early days: The Principle of Least Surprise. Ruby should behave how you’d expect it to. This is easily described with a contrast to Python:
> code snippet
> Ruby accepts both exit and quit to accommodate the programmer’s obvious desire to quit its interactive console. Python, on the other hand, pedantically instructs the programmer how to properly do what’s requested, even though it obviously know what is meant (since it’s displaying the error message). That’s a pretty clear-cut, albeit small, example of PoLS.
Nowhere in the above is he calling Python bad. He's using an example of how Python handles a thing to illustrate how Ruby handles that exact situation differently inline with his philosophy "Principle of Least Surprise". I'm not trying to get into a semantic argument here, just pointing out that he's making an illustration with a minor detail.
Calling Python "bad" would make no sense, because Python is wonderful. This is just a way to highlight how Ruby does things differently than others have chosen to do them.
Unfortunately it seems like the argument is mainly semantic then - I find it reasonable to think that "pedantically instructs the programmer how to properly do what’s requested, even though it obviously know what is meant" is pretty much a detour to say it's not good, it's implied.
I just don't see why DHH needs to do this - ruby has so many things that make it stand on its own.
I think his example is just very badly chosen then. In Python having something like "exit" execute program ending code is extremely surprising if you know a bit the language.
There is still enough work and projects being built using Rails. Of course NodeJS stole a lot of thunder from Ruby/Rails, but everyone who has been smart either went back to Ruby/Rails or moved on to Go (if performance was an issue). I don't think Python is an issue, it's always have been that people went from Ruby -> Python and vice versa.
The change from Rails to Go must be quite shocking. Going from such a completely framework to a barebones language is a huge step. I write Go and went from Python -> Go and it still was a bit of a jump. :)
I was hit hard by the cognitive dissonance at the start of section 2.
Just after waxing in section 1 on how Rails is designed to his own happiness (including adding quirky methods like 'fifth'), he says "One of the early productivity mottos of Rails went: “You’re not a beautiful and unique snowflake”"
> We have to dare occasionally break and change how things are to evolve and grow.
> ...harder to swallow in practice. Especially when it’s your application that breaks from a backwards-incompatible change in a major version of Rails. It’s at those times we need to remember this value, that we cherish progress over stability...
I encountered this doctrine first hand. A division of a company I worked at had its division's website rewritten in RoR by some outside consultants. Even brand new, it was a mess of Ruby gems of conflicting dependencies which was undeployable. The build system was a train wreck as well. Some of the main web pages of their web sites like rubygems.org were not available - the web site had "progressed" and when you clicked on a link, the page explaining anything had disappeared. I mean hell, go to rubyforge.org this minute (1:15 PM EST) - it is down, of course. The blog of the author of the Ruby gem that then was the main gem that handled web serving did not inspire confidence.
As I would have to maintain it (as a sysadmin, not programmer), I refused to deploy the system, since it was an unreproducable mess of conflicting gems and gem versions and kludges. They decided to pay the RoR consultants additional money, despite them having never delivered a working system. By the time I left, it still was never deployed. The division closed dozens of offices soon after, and then the division shut down - perhaps not completely related, but probably somewhat related to this project.
Meanwhile, the company's other divisions had decent programmers programming for Java application servers, and that code and those servers were much more solid. Builds rolled out easily (and could easily be rolled back if need be). It was really night and day. It makes sense this contempt for stability is explicitly part of their doctrine.
DHH's is talking about the doctrine of the framework, not random apps built atop the framework.
rubyforge.org has been offline for over a year and a half, as announced over 2 years ago.
You describe a Rails application written by outside consultants that was undeployable, and compare it to apps written by internal Java developers. I believe the quality of the developers had more to do with the deployability than the languages of choice. You could just as easily have a Java application written by consultants, with undocumented JARs, magical PATHs, mystical server.xml's to make things work just right, and crazy ant scripts.
> rubyforge.org has been offline for over a year and a half, as announced over 2 years ago.
To those not drinking the RoR kool aid, this is toward my point. Two years ago rubyforge.org was a central repository of Ruby gems. Now it is a web page that says "RubyForge Could Not Connect to Database:". Of course, in the minds of some, this does not reflect poorly on RoR but me - I am supposed to know that two years ago they decided to transform this central hub of Ruby gems to a web page that says "RubyForge Could Not Connect to Database:".
This kind of thing is par for the course with Ruby. I know that the http://perl.org/cpan page I used twenty years ago is still redirecting somewhere sane, but rubyforge.org ? "RubyForge Could Not Connect to Database:" - and the fool is me for not knowing why. This is typical of the kind of thing you deal with in RoR world.
Insofar as projects - a Java project can be junk just like an RoR project can, yes. The thing though is that relatively, the core Java infrastructure, community, API etc. has been much more stable over the past twenty years.
Hearing that rubyforge.org disappeared eighteen months ago to be replaced by this cryptic message makes me more down on RoR-world than if it was just their website being down for a few hours. It's the kind of thing you deal with in RoR-world all the time.
That sounds like a Rails app from the 2.x days (circa 2009). Back then, "a mess of conflicting dependencies" was a indeed problem. With the introduction of Bundler, that problem has been fixed ever since.
I like the philosophy of optimizing for programer happiness even if it's imperfectly implemented. I think those kind of ideas have more power than they are commonly credited with.
We've been happily doing Rails/Ember for about a year now. When we started Ember Data wasn't as stable or as customizable as it is now, so I don't have experience working with that.
In general, we've been happy with it. We ended up writing our own serializer system (similar to ActiveModel::Serializers) to provide legacy clients with the option to use XML without losing our minds. Rails has a lot of view-level niceties that we're not using under this scheme, but the rest of the framework is still very useful for this task.
No real ecosystem can be built on rails since its apis keep on breaking.
That's why in my experience, most people give up on rails.
Stop breaking apis, introduce stability and maybe the framework will be successful again. People don't give up on rails because of ruby, or because it's bloated or slow, but because it became an unmaintainable, non upgradable mess as time passed.
one thing i hate about rails is writing the database migrations. (i thought: "why not just define what the schema should be, and let a diff-like tool figure out update statements?") so that's what i wrote:
I may be wrong but it looks that you just misunderstood what migrations offer and their usage patterns.
What if you have to remove one column and split its data into two new ones? I can provide dozens of similar examples from my production code.
In short, migrations are not only about schema metadata.
It would make more sense if your gem would generate migrations from schema.rb changes.
Also, that rant at the end of README kinda shows that you're hating the tool you're trying to use. Why not use another? You are not tied to ActiveRecord.
I'm not trying to say that migrations are flawless as a tool. I've faced at least one major problem with them. But still.
True, this doesn't do data migrations, and we still write the occasional(1) data migration when needed. But those are no more difficult to write, and the much more common non-data migrations are an order of magnitude easier. So net win.
(1) If your data migrations are not "occasional" (and I mean very occasional) that's a sign you're doing a poor job at modeling your data. Splitting one column into two is almost always an example of someone really f-ing up the original schema.
Think of it this way: how do you switch branches? Do you look up the most recent ancestor, check it out, migrate down to it, then back up the new branch? It's so hard I don't know any rails devs who actually do it. But with a my tool it's a one-line command. PRs w/ schema changes actually get tested now, not just eyeballed.
Also, did you even read the "rant"? Do you seriously like the proposed version control tool modeled after rail's migrations? ;)
I was under impression that you suggest not to use migrations at all.
That "hybrid" approach you just described seems to make sense :) Still not sure if I'm going to try it in production.
As of occasional (or not) data migrations, it depends on project and its history. If project is live, rapidly developed and has faced couple of pivots, migration history will reflect it.
Just to clarify, to me "data migration" is just a fancy name for a one-off script that you run during (or after) a deployment. We don't actually use the rails migration for it. (Mostly because it would overwrite our schema.rb IIRC.) But in general, yep.
So how do you manage these scripts?
When deployment is multistaged and automated you won't just run them by hand.
You need system that runs them automatically and exactly one time at each stage.
I can't see why you have to create a system to manage these scripts if there is good enough built-in system for that purpose?
If automated deployment is not your case I strongly recommend it.
Since I first time managed autodeploy to work properly I've never looked back.
It is SO convenient.
I may be wrong again about your processes and configuration :)
we do auto-deploy, but they aren't required to be run during the deploy process, so we just run them sometime after the deploy. but honestly i can count on one hand the number of these we do a year - i haven't put much effort into streamlining the process. whereas schema changes are quite regular. just had one tonight in fact. output from the deploy log a few mins ago:
Executing in 3...2...1...
BEGIN TRANSACTION
-- column changes for table products
ALTER TABLE "products" ADD COLUMN "dont_email_on_purchase" boolean
-- column changes for table searches
ALTER TABLE "searches" ADD COLUMN "tag_only" boolean DEFAULT 'f'
COMMIT
--==[ COMPLETED ]==--
I understand the skepticism. I presented it at the Houston Ruby group last year, shortly after developing it. You should have seen the looks at the start. But try it on your own project. (It takes like 30 seconds to switch.)
Nice! I program in both Rails and Django and I really like Django's way of both having the schema with the models (it's a form of documentation) and the clever way it can write migrations for you.
hah. then you'll love this: this project was conceptually a port of a django tool i wrote ages ago: https://github.com/keredson/deseb
rather than call "./manage.py syncdb", call "./manage.py evolvedb" and changes to your models will be synced to your schema non-destructively. (ie: without dropping and re-building the table)
The main problem with Rails is that other developers you work with have strong opinions about coding style, and they hammer you on code reviews if you don't code their way.
Work with on open source projects or with with in a company? In either case, having some agreed upon coding style guides may help reduce individual style conflicts.
It's partly a Rails problem because there's a ton of different ways to implement something, so people will always find reasons to disagree with what you did. And the Rails community seems particularly over-opinionated about these things. There's a lot of cargo cult thinking going on when your stuff gets code reviewed.
The worst thing about rails these days is ruby itself. If I'm going to use a non type-safe language, I may as well use the one that's on the client side as well (and has first class functions).
Everyone who has created their own open source framework which supports a multi-million-dollar business that now supports your hobby of driving million dollar race cars, please feel free to cast stones at what rails is and has become.
This is a terrible form of argument. Success does not mean you're correct. Many successful people and things deserve criticism. I don't think DHH or Rails is among them, but that isn't because they're successful.
Err, yes, it does. That's precisely what success means. If you are successful at something, that means you did something right. What that something is is certainly up for debate, but you can't ignore success as an argument.
Right; for example if you're a successful pharma CEO you might be able to afford the one and only copy of a Wu-Tang Clan album.
Unless you define "success" as "being rich", no, I'm sorry, it's not true. It's actually quite easy to become rich by being a complete scumbag with no consideration for other people.
I think a much better, more relatable, and currently very striking example of this fallacious "rich and famous people must know what they're talking about" line of reasoning is the current U.S. Republican presidential primary front-runner.
Granted, it might look "beautiful" in the eyes of a experienced RoR developer, but personally i find it just makes code very hard to read. Just my 2 cents.