(1) Is "batteries included"
(2) Has the gem/engine ecosystem where basically every problem is already solved.
(3) Expressive code like has_many :things
If we could get those things + static typing + performance everyone would switch. But that doesn't exist.
Python is very "batteries included," and there is a large set of exisitng packages for most things. One can monkey-patch things and invent cute syntax, but most python is rarely hard to reason about what's actually going on.
It's easy to bag on parts of python (eg some syntax and terrible distribution story), but I feel much less crazy (and suspicious of every punctuation mark) when working on a modern python app than when working on a modern ruby app, especially in the presence of rails.
Java is fine as a programming language. Java as a web app more or less means Spring. And Spring means XML files and annotations which come with their own problems. Kind of an out of the pan and into the fire thing.
(alternatives like Vert.x, the less-annotation-heavy quarkus, etc).
For Java web dev I actually like Kotlin better - ktor is pretty nice.
First of all there is more to Java Web development than JEE and Spring, which in any case, other eco-systems don't have a mature answer for many of their deployment scenarios and cross system integrations.
XML is beautiful, there is yet a format that supports machine manipulation, IDE graphical tooling, comments, schema validation as XML.
Anyone that praises Rails will be right at home with XML and annotations magic.
And Pascal, Ada, Haskell, Eiffel, Standard ML, ...
None of the language you mention had any sort of wide-spread visibility at that time, meaning they were not representative of the (overwhelming) majority experience with statically typed languages.
That is not the timeline we're talking about here. Dynamically typed languages started taking off at the turn of the millenium and really exploded in the second half of the aughts. Java didn't even exist in the early 90s.
It really doesn't.
Languages like PHP and Ruby "have won out" over statically typed languages because the representatives of statically typed languages at the time were Java and C++, both of which were bad (they still are, but they were): verbose, difficult (and verbose) to leverage for type-safety, missing a bunch of tremendously useful pieces (type-safe enums to say nothing of full-blown sum types), nulls galore, …
As a result, the gain in expressiveness and terseness (even without trying to code-golf) of dynamically typed languages was huge, the loss in type-safety was very limited given the choice was "avoid leveraging the type system" or "write reams of code because the language is shit", and the fast increase in compute performances more than compensated for the language's loss in efficiency.
And that's before talking about the horror show that Java's web frameworks ecosystem was circa 2006.
> Languages that tend to work well with it are those that are highly flexible around the corner cases of these technologies, and allow you to quickly iterate through the process of gluing them together.
That's really complete hogwash outside of the client, which isn't what we're talking about here since neither php nor ruby run there. On the server you have clear interfaces between "inside" and "outside", and there's no inflexibility to properly taking care of cleaning up your crap at the edges. Quite the opposite, really.