This is also my only complaint with Rails.
I'm a programmer, not a wizard, and I'm not good at magic.
We are surrounded by magic (which only means things we can not realistically be bothered to take the time to really understand, in contrast to things which are incomprehensible). I have no real clue why the terminal works. I have no real clue why my OS works. I have no real idea how TCP/IP does its thing. Sure, I can use them – but I couldn't really explain and much less recreate them.
What I need in all the above is replicability. I do x, and I know y is going to happen. Get x, do y. This is true in Rails.
If I really wanna know more Rails is open and easily explorable. No one is preventing me from finding out how any piece of the "magic" works.
"Magic" class inheritance is a thing in JS as much as it is in Rails.
What is so special about Rails and "magic"?
I'll state my case as clearly as possible: The magic in Rails REQUIRES memorization... freaking everywhere. And it provides virtually no hints to jog your memory.
There's just too much tooling, hidden away out of sight, and applied through shenanigans with Ruby that other languages/frameworks make MUCH more obvious.
Simple trivial example? Rails fucks with imports left and right. Rails allows you to not even write a require statement half the time - it's just going to load things from places. Hope you have that list memorized.
Does it save you some time? Yes.
Does it make the code look "Cleaner"? Sure.
Does it make my life a fucking chore every time I have to run a damn console to find the source location of an object at runtime because it's entirely unintuitive about where it freaking came from? Damn right it does.
---
If you started early in your career with Rails - you probably don't notice this. But if you have experience with a solid selection of languages (ex professionally I've used: GoLang, C, C++, JS/Typescript, C#, Java, Netlogo, Rust & Ruby) I find the discoverability in Ruby/Rails about the lowest on the list.
Very fast to work with if you happen to have it all memorized. But that's about the only compliment I can give it.
What's interesting to me about this comment is that among the languages I'm familiar with that you list, the difference between the best discoverability and the worst feels way larger than the difference between the worst one and Ruby. To me, C is barely any better than Ruby; sure, Ruby lets you define methods/types at runtime, but C doesn't even _have_ methods, making finding all the things you can do with a given type way worse in my opinion. Plus, you can still have some wonky generated stuff with macros, although I'll concede that's usually less common than Ruby metaprogramming. Java, C++, and Go are a bit better, since you get a namespace instead of just a random identifier without context, but these namespaces are generally split across multiple files, so in practice I would need to rely on tooling to do this for me, and at least with RubyMine this wasn't in practice _that_ much worse.
In my book it's a write-only coding environment like everyone used to complain about with Perl and PHP. People crank that stuff out really fast and move on and leave future generations to suffer. But they love it, of course.
1.
These are fair criticisms. These kinds of problems can also be difficult to demonstrate to others who may help.
For example "some function `f(x)` gives 5 when it should give 7" will get an answer in 5 minutes on stack overflow, whereas "my thing's not working and I don't know why" will receive 4 downvotes and no answer in the same time.
2.
I tend to be the kind of learner who doesn't sit down for 30 days and read the docs cover to cover, but rather I start using the new tool on day 1 and figure out what I need to know as a I go. But rails rewards the former approach (i.e. reading through the rails guides - or even just skimming them). This may take a few weeks, but it gives the ability to at least know where to start to look if something has gone wrong.
3.
> And it provides virtually no hints to jog your memory.
I kinda agree. I feel like this should be easily addressed (although I'm not totally sure how).
In Typescript, entities have types and when you misuse something the typescript checker tells you while you're coding why, that's not what you're supposed to do. You can super easily track down the type and navigate the code base to the source and adapt either your code or edit the source. Easily. With rails, you're often required to do mental gymnastics to debug simple things, after the fact
It really isn't that common just like it isn't that common to do it in JS or in Python. Some people used to do that shit a decade ago, it became frowned upon and I don't really see it anymore.
You just see these functions and there is no require in the file to tell you where they come from. Rails just loads that shit from somewhere. It could be from a mixin, it could be from one of the 50 classes in your hierarchy, who the hell knows. You press jump to definition and rubymine just fucking chokes and gives you like 30 different method definitions with the same name in different places.
I don't know how much blame to put on Rails, Ruby, or the teams I worked on, but in the end it was very frustrating.
Aside from that I like Ruby a lot, and Rails only a bit less. But it's a big aside :)
class Foo; puts "foo.rb was parsed"; end
is a simple example of nothing is really special.
After using Rails every day for 12 years I know pretty much all the ins and outs, and what is "magic" to others is just the robust tooling I love. Just like any tools, they are overwhelming and daunting when you don't know how to use them, but once you become proficient with them, they make your life so much easier. While it might be difficult when the "magic" doesn't do exactly what you want for your edge case, when you have a sufficient level of mastery, it's easy to find a way to adapt/modify/override the tooling and make it do what you want. Further, many times the tooling is there to keep you from doing things you probably should not be doing, and this kind of strict, opinionated, best practice enforcing philosophy has gotten me out of trouble at times, and I think it makes it much easier for engineers to move between Rails codebases and start being productive even faster.
I've done plenty of Node/JS/React and I honestly do not understand how people can prefer to use these stacks over Rails. For full stack web dev, Rails is such a pleasant place to work every day.