66 comments

[ 3.0 ms ] story [ 147 ms ] thread
Love it a great way for encouraging more syntax experimentation in the wild. A less functional and more conceptional library is the pragma gem [1] - that lets you turn on the future today or add your own ideas for easy (re)use for everyone - let's evolve the ruby language together by experimenting in the wild in a pragma(tic) way.

[1]: https://github.com/s6ruby/pragmas

Yes. It is hard to actually know whether the new Syntax is good or not by just "looking" at it. It will needs to be put in the wild and see how it works out. But you also dont want to support a syntax indefinitely for compatibility reason.
I've had to deal with Ruby for the last 2 years, and one of the main problem is the gem ecosystem. The language and standard libraries are pretty narrow, unless you add Rails (which adds a new variety of breaking upgrade headaches).

Thus, there's always the desire to use third-party gems to achieve pretty basic stuff (localization, decent networking/REST, database drivers, etc). These then tend to go out of date. It's pretty common to find well-used gems that haven't been updated in 5, even 10 years. This puts the developer in a tough spot - reinvent the gem/wheel? Or be forced to stay on an EOL version of Ruby?

> The language and standard libraries are pretty narrow

Compared to which other language?

> Compared to which other language?

Java, for one, but obviously it's subjective

You can use JRuby and then have access to both library ecosystems.
Not JavaScript or Go, that's do sure...
This is because the next generation of hot coders is working on JS or something more exotic like Rust. This is why I think that even though Rails is still a good platform for building a certain class of webapps the writing is on the wall and I'm planning to transition away from it over the next few years.
In 5 years there'll be another shiny thing everyone will flock to. It's part of the fun, but there are some languages that just do that particular thing just right. Ruby/Rails is bittersweet to me. It does that thing just so right, but it feels like there's an evolution around the corner that could be an upgrade when it comes to the ecosystem. It certainly doesn't feel like Rust is a good replacement if you enjoy Ruby syntax and dynamic typing simplicity. Ruby reminds me a lot of how Perl 5 is a great language, yet finding jobs in Perl 5 is becoming more and more difficult.

I'd love to think that Raku (formerly Perl 6) would be that language, but it doesn't seem like the trajectory is there.

Just because something is new and shiny doesn't mean it's not a step forward. People dismissed Rails with these same criticisms in the beginning. Sometimes new tech gives us a big step up in productivity and I think we can now do better than Ruby/PHP/Python.
Or you could become an open source contributor and improve the ecosystem by submitting PRs to existing gems or writing your own.

The community is us. Ruby is what we make it. So let's make it better.

Rails has been very good to me over the years so I am tempted to try to help out but I think if I'm going to volunteer I'd prefer to help a more modern stack like KTOR.
Consider Laravel (PHP) and Django (Python) if you want a like-for-like replacement in a better supported ecosystem.
I'd probably go for Django but it feels like a step sideways more than a step forward. Once you've gotten used to a more modern language with great tooling, typechecking & null handling it's frustrating to go back to a stack where you're getting errors in production that would have been caught by a compiler.
I'm in the same spot. I still use & love Rails, but having adopted TypeScript & VS Code (w/ React) for the front-end, I find myself missing those luxuries when I switch back to Ruby/Rails/Vim.

I'm leaning towards a full TypeScript stack for my next project. The idea of sharing types & code between client & server is incredibly seductive. But there's no Rails for TS/Node, so I know it's going to be a shit show assembling all of my chosen libraries into a cohesive whole.

Although looking at your previous comment, perhaps I should give Kotlin / Ktor a try?

I'm in exactly the same boat. Rails gives you so much functionality for free. Kotlin/KTor is not a drop in replacement since it's closer to something like Sinatra in scope but it still looks like the best bet going forward to me.
Does the dependency manager not enable fork + override dependency?
Yes, but you can easily get in a situation where say Github says "gem X is vulnerable, upgrade it", but can't generate it needs to update version of dependent gem Y, and that would break gem Z which is version locked because ruby versions etc...
This happens, but it's not really that common, and it's certainly not insurmountable.

You can fork any gem in github, fix whatever issue it has, and point your Gemfile at your fork on github. Bundler treats it as the same package so it doesn't break your dependency tree either above or below it. I've used this to fix an incompatibility in the middle of my dep tree before. It's annoying, but it's not exactly a big deal.

Ruby is generally very backwards compatible, so I rarely run into an issue where an old gem requires that I run an old Ruby version.
A lot of gems don’t need to be updated. Stable software is a thing, especially in more mature ecosystems such as Ruby.
I haven't had your same problem and I've been working with Ruby for the last 8 years. I've also deployed Go, Python, Elixir, and Javascript to production. Here are my thoughts on Ruby in 2020:

Ruby, between versions, doesn't have many breaking changes, if any. They're more additive changes than they are subtractive. That obscure gem that has a last commit date of 2 years ago? Probably still works. Bundler complaining the Ruby version isn't supported in the gemspec? Fork, edit, push, bundle, success.

When you say basic stuff, I think of "busy work that's already solved by someone else, probably in a more complete than my half-assed attempt would be just so I can focus on more domain-specific problems and implement business logic." That's a fine tradeoff. My clients don't pay me to implement things like authentication or design an ORM: They pay me to do business logic. `bundle add devise; rails g devise:install; rails g devise User; rake db:migrate` gets me rock-solid authentication and I didn't have to think twice about it.

"Look at all the things I'm not doing" was something DHH said when he released Rails. A lot of Ruby is the same way. That's fine with me, and a lot of others.

There's a lot to love with Ruby in 2020. I still find it to be the most hyper-productive ecosystem and it doesn't change daily (see: Javascript's ecosystem). It's a language that's expressive, enjoyable, and plain fun. And for the very vast majority of web applications — which are CRUD-centric — Rails is still an extremely valuable means to get up and running. Scale? 99% of us won't need to worry about scale, and when we do, that's a great problem. Speed? For 99% of us, our database will be the slowest part of our application — even when indexed and tuned.

Sure, it may not be 2020 sexy. The socks you're wearing probably aren't either, but they still get the job done.

Ruby is plenty sexy to me! Been working in a large "modern" Typescript codebase for about a year now, and every chance I get to go back to writing Ruby, it's a breath of fresh air!
Ruby is a joy and I'm always a little confused by it getting so much negativity on internet forums. I guess we all have our preferences, but the Ruby ecosystem feels sane and stable to me.
A lot of people are put off by all the 'magic' and weird syntax. I've heard a lot of criticisms from the python crowd about hidden state and whatnot... but you have to understand where those folks are coming from and what language principles they subscribe to. (Python and Ruby are principally opposed in many areas, as an example that I'm familiar with)

Personally I don't mind magic or hidden state that much but then again I came from perl.

Like a Ruby dev is going to take lip from someone who thinks midnight is false.
Never realized this... yay for Javascript-like screwy type coercion. Now I have some more ammo to rib the pythonistas in my life. Thanks!
Good points, and I certainly understand why the Ruby community is so passionate. The language is expressive, mutable, and has some nice syntax. My personal problems are:

- Rails is the monolith that gives you all of that auth/database/etc capability, and it's very non-trivial to upgrade

- Refactoring a large codebase with a dynamic, untyped language like Ruby is extremely difficult without 100% test coverage

- Unusual syntax conventions which can get you into trouble (y = x.blah vs x.blah!), strings vs symbols, magical naming conventions for Rails, etc etc

- Auto-loading is a mess

- ActiveRecord is great until you care about DB performance, and then you end up continually working around it's quirks (the N+1 problem, indexes failing due to int/string type conversion, etc)

- Everything in Rails is convention over configuration. File paths, names of classes, names of routes, mapping of AR to DB table, etc. Sure it "just works", but when it doesn't, it's not always easy to figure out why.

- Monkey-patching is cute, but, seriously? Hot-patching system library functions?

- What's a variable? What's an accessor? What's a function? Parentheses are optional, return is optional (yet @ is required for class/instance vars?)

Again, none of this prevents you from building a quick and easy CRUD app, but I've found the deeper I go, the less I like it.

Your points are valid. Understanding the quirks and features of Rails is a lot, too.

It sounds like you had to dive head-first into a mess where it was hacked together by non-Rubyists who learned "just enough" to push to production, and were by no means diligent about following Rails conventions.

Obviously, this issue is agnostic of what language one chooses. But it certainly leaves a bad taste when there's all this "magic" happening (see: metaprogramming). That magic is what makes working with Rails so productive.

Rails makes it easy to do bad things because of how magical it is. `@post.comments.each { }` when you didn't preload `comments` is bad. This is fixed with `Post.includes(:comments)`.

Similarly, if you avoid its conventions — overriding `table_name` on your model, in your example — and try work against it, rather than with it — it becomes more of a chore than it does a treat.

Like all frameworks, they require a little bit of diligence and care and understanding to really get the full effect. Rails is great because it makes a lot of assumptions at the cost of brainpower, and for the vast majority of things this is good. It's not always the right tool, and it doesn't need to be. But when it is — again, a large majority of web apps are just CRUD — and when it's written with a little bit of care, it's great.

I've been working with Ruby professionally for something like 10 years and all of those points are generally just things you learn to work around.

And Rails itself is less monolithic than you think. You can swap out most of the components for other gems, like ActiveRecord vs. DataMapper (though I am not aware of anyone who does this anymore and the level of support for Rails gems generally outclasses everyone else) or remove those components entirely.

Much of the "Rails magic" is inside ActiveSupport, which you can import without bringing in all of Rails proper. Personally I think much of the stuff in ActiveSupport should go core.

These issues could be applied to any modern language - I don't see them as specially affecting Ruby. As someone who has worked in many languages professionally for 20 years, Ruby/Rails is my favorite productivity tool for web apps, hands down.

FYI see Zeitwerk gem for autoloading improvements.

The article mentions about the use of "refinement" that only monkey patches to your local scope and won't affect the rest of the codes.

Also, type hinting is coming to ruby 3.

> magical naming conventions for Rails

That's rails' problem. I don't like it either but nothing to do with ruby.

Seems like half your problem comes from rails.

> The language and standard libraries are pretty narrow, unless you add Rails

Rails is neither the language nor the standard library, so the “unless” part seems superfluous.

> These then tend to go out of date. It's pretty common to find well-used gems that haven't been updated in 5, even 10 years. This puts the developer in a tough spot - reinvent the gem/wheel?

If it's open source, why would reinvention rather than forking and assuming maintenance (for one's own needs, not necessarily publicly) be an issue?

Ruby is super backwards-compatible with new versions. Even to much. The core team almost made religion from it. So I don't really understand what the problem is - aside from using not maintained library. It will work, unless it was written for 1.8 or something.
Just because something hasn't been updated for a while doesn't mean it's broken.
I have mixed feelings about this as I do JavaScript transpilers.

I’m totally in favour of using transpilers to support older platforms.

What has happened though in JS land is developers started using them in reverse - writing to future standards that are not supported by the current underlying interpreter.

Hoping here the same thing does not happen in Ruby

I think I see what you're saying, and I agree about supporting older platforms.

But wow, when the ES6 features hit, and I could use them NOW, in spite of having to support IE? That was huge, and made the code so much nicer in so many ways.

I was really glad that I could, as the snaky folks say, "import from future".

Likewise. We have a big important codebase that was started a little before all the ES6 features hit. Had it been written in ES5 at the time it would be a pain to work in. However it's still a pleasure because it is ES6 with snippets from ES7. We no longer use the transpiler, and were disciplined about only using features that were definitely coming. I'm glad we did.
Yeah, there's no way to convince people to write ES5 once they've seen ES6+. :-) But the problem was that the JS ecosystem never totally got a consistent story about how to stop transpiling. They were transpiling in Node, which makes no damn sense. They were shipping transpiled bundles without the code needed to turn the transpilation off in the future. It was and is a big mess where now that ES6 is supported everywhere, you can't actually use it because even though everything is written in ES6, it's shipped as ES5 and you're saddled with this polyfilled crap even if you don't want it.

It's not the worst problem for an ecosystem to have, but as someone who wants to ship smaller JS bundles, I find it annoying.

Bloody regenerator is the worst for this (I know, IE11 support and all...). Or, even worse, the "regenerator runtime is not defined" error
> even though everything is written in ES6, it's shipped as ES5 and you're saddled with this polyfilled crap

This is somewhat mitigated by the use of babel-preset-env and browserslist.

https://github.com/browserslist/browserslist

Where I work, our build tool uses a list that's (very slowly) getting reduced to evergreen browsers. On some projects, a simpler list can be used for little to no polyfills.

> transpiling in Node, which makes no damn sense

A legitimate use case would be for server-rendered apps, where it's advantageous to share code with client-side, namely transpiling module import/export (rather than CommonJS) and JSX. I do enjoy how recent versions of Node.js are embracing modern language features, even pipeline operator. Still, there are situations where transpiling server-side code makes sense.

Another maybe more relevant reason is using TypeScript, which arguably provides a leap in developer experience and code quality, beyond what browsers (or the V8 engine) would implement in the foreseeable future.

But this is taking one of the worst parts of the Javascript ecosystem and inventing it for Ruby. Despite Ruby not suffering from Javascript problems like having a subpar standard library and missing essential language features like a standard import syntax.
I am biased from working so much with SPA frameworks like Angular and React, at this point I've given up. So many frontend processes these days involve some kind of build process to minify or transpile that I figure... why not always use the most advanced features?

May as well pick the JavaScript/TypeScript flavor with the best developer ergonomics.

I would say more developers like this about the JavaScript ecosystem than don't.

It's awesome to be able to use new features and kick their tires before the core engine dev teams invest resources in building them out.

It seems like a win / win situation here.

js devs get to use and reason about tomorrow's features today and help guide whether or not they are a good idea or even more easily come up with new ones.

Js engine devs get to see how features are used and whether or not to invest.

Honestly what is not to like about this?

This. Async/await was a dream for standards orgs - yet I was using it. It felt like shaping, or at least sampling, the future
> What has happened though in JS land is developers started using them in reverse - writing to future standards that are not supported by the current underlying interpreter.

JavaScript's a bit unique in this regard though, in that you don't have the option to upgrade the underlying interpreter. In most contexts where Ruby is used, it'd be much simpler just upgrade to a newer version of Ruby than start using a transpiler.

Right- with JS the developer has little insight into or control over what interpreter will be used to run the code, so with Ruby I think there are fewer advantages to portability.

My bigger issue is that this shifts control over the language from Matz and the community to the maintainers of this transpiler. Maybe they decide they want to support something like the ++ operator as a workaround to Matz's insistence that it should not be the language. Then what?

Probably the same as happened to CoffeeScript: people with codebases in CoffeeScript are now stuck with a language that just few people know and is hardly maintained any more, and additionally doesn't really have that many particularly exciting features any more compared to the language proper.
I also don't get what the value add is in this case.

On the JS side, sure, you don't control the env that'll eventually run it, so a source to source compiler makes sense.

On the ruby side, why is this just not in the standard runtime? Are people trying to run newer code on older VMs that they control the deployment of?

> Are people trying to run newer code on older VMs that they control the deployment of?

If you mean “don't control”, probably, at least, they might be given this tooling: e.g., Ruby on App Engine Standard is 2.5, not the current 2.7.

> writing to future standards that are not supported by the current underlying interpreter.

What is the problem here? You can't expect billions of browsers to be updated so soon and I'd be hairless if I still had to write in ES5 just because there are still IE out there.

Currently I favor in writing TypeScript but if Ruby Next starts supporting type hinting for Ruby 3, then I'd like to give it a go as soon as possible which can even be deployed on current environment. The only problem would be the lack of editor support for the new syntax.

> I’m totally in favour of using transpilers to support older platforms.

> What has happened though in JS land is developers started using them in reverse - writing to future standards that are not supported by the current underlying interpreter.

Why is that in reverse. A transpiler is, after all, and using a compiler to be able to write in a language more expressive than the language to which your code is compiled is rather normal.

Actually, that's not even “in reverse” compared to “to support older platforms”, that's how trabspilers are used to support older platforms.

If I'm using Babel to support, say, IE9 (an older platform), what I am doing is using it to compile JS not supported by IE9, largely because it's a newer standard than IE9 supported, and compiling it to what IE9 understands.

If there a difference between doing that with language features from ES6 on IE9 vs ES2019 on IE11 vs something that is a currently a Stage 3 proposal on current Chrome, sure, but none of those is the reverse of the other, they are all variations on a theme in the same direction.

Great project!

A bit shocking to see how much ancient Ruby is in use. It is not like they massively change the language with every release like e.g. Swift. Probably breaking changes in Rails are a bigger blocker for updating to a new Ruby than Ruby itself?

New rails major and minor versions commonly lock the ruby version to a mature recent release, though this is not always intuitive.

I can see a number of companies sticking on Ruby 2.2 because you can happily upgrade Rails from 3.2 to 5.2 while only changing to a minor bugfix release of 2.2.10.

Rails 6 locks in at 2.5.0 which was over a year old at the time of the Rails 6 release.

https://stackoverflow.com/questions/9087116/which-ruby-on-ra...

This is interesting. I’ve maintained a dozen or so production ruby apps and have found language updates are generally painless and quick. In most cases my test suite will issue a few deprecation warnings after an upgrade, but those have always been easy to fix and are also safe to ignore for a little while.

I do see the author’s point with regards to writing gems, though. Just because it’s easy to upgrade to 2.7 doesn’t mean I rush to do it. Usually the new language features added are nice, but not mind-blowing. It’s a mature language.

One thing that has been great is steady performance improvement every year. We usually see a few percent reduction in compute after a ruby bump, which is good for a smile. I’ve heard and am hoping that the 3.0 bump will be a little bigger.

you know, it just occurred to me that transpilers are basically lisp like macros for programming languages that don't support it. i.e. Rewriting your preferred syntax into a syntax that is supported by the programming language.
"We can write a compiler as a set of macros." -- Peter Norvig
Love seeing this. This let's people avoid the pains of forced migrations or forking when a new version of a library has critical changes but drops older Ruby support.

Also, I found this statement hilarious:

> Unlike front-end developers, we, Rubyists, usually do not need to “build” code (unless you’re using mruby, Opal, etc.).

It wasn't that long ago that front-end developers used to say the reverse.

This kind Man brought my Lover back In less than 3 days, i saw wonders, my Lover came back to me and my life got back just like a completed puzzle… am so happy.. thanks to Robinsonbucler@ { gmail }. com for saving my life. Mr Robinson is the best I’ve ever met! Thanks, thanks thanks_____________