It was mostly syntactical, and it didn't do much to improve readability.
I guess I was hoping to see functional improvements, where they address the pain points of ruby: performance, tooling, dependency hell, unicode support, lack of things like co-routines or generators, the ability to restrict access to internals.
```
enum = Enumerator.new{|y| a = 0; loop{y << a; a += 1}}
enum.next => 0
enum.next => 1
etc
```
I believe this has existed since 1.8x
enum = 0.upto(Float::INFINITY)
enum.next # => 0
enum.next # => 1Performance and Unicode other people have mentioned alreaedy, and have been areas of improvement. Explicit library support for semi-coroutines and coroutines was added in 1.9 via Fiber and Fiber::Core, and Ruby already had generator support in 1.8.
So many of the things you say you were hoping to see have been addressed since 1.8, and at least one was already addressed in 1.8.
I used Rails when it was still `config.gem` with no dependency resolution, and it was an absolute nightmare, so I think I know what you're talking about here. But then bundler came along and, well, completely solved the problem.
What's odd is that "performance, tooling, dependency hell, unicode support, ... co-routines ... generators" reads like a list of things that have been worked on heavily since 1.8. Performance has been a major focus of every release since 1.9.1; integrating Rubygems considerably helped with tooling and dependency issues; encoding-aware strings were a major feature of 1.9; coroutines and generators can be implemented more effectively with 1.9's Fibers.
* If I want to increase performance, my option is basically a c module. Except, this doesn't have e.g. the Cython tooling the python community has. * Tooling is miserable. There are few ways to restrict the way people abuse the language, and as a result, style is often highly inconsistent and subjectively-based. Say you want to find all the places people have parse CSVs in an ad-hoc manner: you're pretty much screwed because there are a dozen ways to do it, so a code search only likely to return a subset of your intended code. This may sound like a critique of dynamic languages, but I have not experienced this nearly as much with either scheme or python. * unicode support was still sub-optimal; I personally don't like mixing string/locale operations with encoding operations. I haven't played with this in a while, however, so it may have changed. * Integrating Rubygems was the dependency hell I was talking about. It's as bad as NPM—dependency bounds are often impossible to resolve because there have been breaking changes since the gem last updated. Warnings or conflicts are often ignored until someone offers a pull request, and sometimes (the nightmare scenario) they only appear during runtime. Vendor repositories (or a list of pinned versions) become critical, and security patches can sometimes can all-nighter patches to third-party modules you desperately depend on. This may speak more to the community, but I would have expected better ability to at least provide a (semantic) guarantee a minor point change would not break the api interface. This might not be possible with a dynamic language, but even trivial tooling would help here. * co-routines and generators do exist now, my apologies. The syntax is, again, awkward, but this is a subjective note that I've learned is not universal.
I guess I'm just surprised ruby hasn't doubled down on making the platform attractive to agile enterprise teams, and right now it seems like a money sink compared to e.g. scala/go/python, all of which offer comparable productivity (IMHO) with greatly increased guarantees for maintainability, performance, profiling/tooling/backend options. It makes the prospect of having a technology pivot of some sort nauseous.