Ideal Worlds
Ruby possesses a trait that very few languages can compete with; if you can imagine what you want your code to look like, you can probably achieve that in Ruby. Between the introspection, dynamism, and sheer flexibility, so much is possible.
When working with intermediate developers, I often coach them towards a solution by asking them what code they want to write and have them write it out. We then iterate on it, working towards making that code work.
This pushes them towards outside-in design, which tends to be quite effective when building the kinds of software we build. You pretend you have the dependencies you need, then work through those dependencies, fleshing them out as you go.
Yes, you often discover things about the problem you're solving as you go and need to rework your approach. That's fine, but you might as well implement your ideal solution until the universe shows you why it isn't actually ideal and forces you to adapt.
The thing about Ruby is that you can do terrible, terrible things to make the code you want to write work. I'm reminded of Kevin Kuchta's talk, Ruby is the Best JavaScript. In the talk, Kevin manages to make some valid, working Ruby code that appears to be JavaScript.
I've certainly experimented with similarly absurd approaches. At RubyConf in Houston, Shopify had daily code challenges. I provide a solution to the first day's puzzle where I decided my "ideal" solution was actually a solution to Fizz buzz and found a way to make it solve the actual problem.
I'm not advocating for going to the lengths that Kevin or I went to in your production code. If the code you want to write is JavaScript, you should probably write JavaScript. Disguising your code so it looks like something else is an objectively bad idea unless you're doing something malicious.
My point is that Ruby allows you to push complexity around it ways that are impossible in most languages. This allows us to write code that's exceptionally clear in its intent and pushes the messy details to down the object tree.
I used to tell people to avoid metaprogramming in Ruby unless absolutely necessary. I'd used it when I shouldn't have and ended up creating situations where whenever someone touched the code in question, they had to come find me and get an explanation.
That's obviously bad, but I overcorrected. I've since used metaprogramming in plenty of places where I was successful in hiding the messy details from future devs. I've created abstractions and DSLs that made future developers' work easier.
I now agree with Noel Rappin's In Defense of Ruby Metaprogramming. Ruby has sharp tools and, sure, they should be used sparingly, but you should definitely learn and use them.
Ruby's dynamism and flexibility are a core part of what makes the language so productive and fun to write. These aspects should be embraced, not avoided.
These week I'm highlighting New Zealand's Shepherds of Cassini. I wasn't familiar with them prior to their new release, In Thrall to Heresy, but I've had it on heavy rotation since it dropped. I'm a little iffy on the mixing (turn the vocals down a bit, guys), but compositionally this record is great. Love me some heavy prog. Check it out.