Hacker News new | past | comments | ask | show | jobs | submit login

Ruby is the only language where extensively deep magic feels okay to me, for some reason.

I don't like it in python, I don't like it in Java.

But e.g. in Rails, sure I bump my head sometimes, but overall I like how magical Rails feels because it lets me go so fast.

Maybe it's because Ruby alone is willing to sacrifice so much speed (though not THAT much vs python tbh) and is willing to go all-in on it, that they enable magic to be so deeply magical that it can deliver adequate value to compensate for being more inscrutable?

Whereas other languages' metaprogramming systems keep you a little more leashed.




Ruby's metaprogramming allows you to create really nice, ergonomic abstractions. I can write `has_one :posts` in a User model class in Rails and a ton of useful functionality pops into existence.

On the other hand, that deep magic metaprogramming can be really hard to follow if you need to understand how it works. Tracing back through (or even debugging) a metaprogramming-heavy codebase is a nightmare.

I'd argue that deep magic metaprogramming is great for when you have abstractions you almost never need to dig into. Rails is great because it's relatively rare that I need to go spelunking in the rails codebase itself (and thus understand the deep magic). Instead, I can rely on a huge pile of documentation, stack overflow answers, conference talks, etc to figure out how to use rails' abstractions (like `has_one :posts`) without needing to understand their implementation.

On the other hand, the average production codebase should minimize their use of metaprogramming. When I don't understand how Joe's `Whatsit` interface works, I'm much more likely to need to dig into Joe's code to understand how to use that abstraction. If I have to understand Joe's deep magic every time I do that, it's a net loss.


for debugging, I can't recommend pry (and pry-byebug for older pre-Ruby 3 codebases) heavily enough. being able to do show-source post.author and have it automatically unwind all of the metaprogramming and magic is really helpful


The new Ruby debug module is even better than pry. It has all of the step-into, step-out-out, object inspection, etc. featuring I’ve ever wanted.


Coming from C/C++, and then C#, F# I am annoyed by the fact that debugging is not a first class experience in these languages.

This lack of easy debugging capabilities has cultivated a whole group of developers whose primary way of debugging is 'let me out in a print statement'.


I haven't gotten a chance to try it yet! definitely looking forward to it after we figure out the whole keyword arguments nightmare :)


On the topic, I urge you to check out https://rubyjard.org/

I have never looked back.


Unfortunately it seems like it's not maintained anymore


I'm in touch with the author, and he is responsive to concerns.

Jard is a tool that is simply done/complete/ready.

JavaScript as a developer culture seems to have convinced a lot of folks that if a package isn't updated at least a few times a year, it's "dead".


People do like to blame this on JS, but it's been true as long as I've been writing software. "Don't build on unmaintained libraries" was a lesson I learned hard in Ruby, long before the javascript ecosystem was a thing.

RubyJard looks cool, but the repo is marked as "Archived" and the last commit predates Ruby 3. And, in fact, it looks like there are issues with Ruby 3.2 and RubyJard.

Most software cannot really ever be "done", if only because no software operates in a vacuum. Nearly all software relies on a language, a standard library, an OS, direct dependencies, indirect dependencies, etc. The only way your software can be "done" is if it relies on absolutely nothing, and very little useful software does that.


Damn, you're actually right about the archived stamp. I'm confused because he actually did the pry version bump when I asked for it, and he appears to have rolled it back and yanked the gem build from the server. I'm at a bit of a loss, tbh - this is a real Mandela Effect moment for me.

Well, that sucks. Still, I urge people to clone a copy, update the pry dependency and give it a try because I've never run into any issues and it's at the center of my debug game. I'd be devastated to lose it.


It’s not even has_one :posts, it’s has_one :post because of even more rails pluralization magic :)

Agree with everything you said


could be a model called Posts and plural is "postses" :-)

(disclaimer: I do rails all day)


I've worked with Ruby for over fifteen years off and on and the last seven exclusively -- in a large codebase with a fair amount of metaprogramming. We've onboarded engineers, junior and senior, who previously have never used Ruby and it's been interesting to see who does and doesn't have a hard time with it. It doesn't seem to match overall experience and skill level. It's more of a sense that people with patience and a kind of outcome oriented approach (over fixating on why something is done a certain way) will have an easier time unwinding the complexity.

One thing I've noticed, and this is something that seems to bother non-Ruby engineers, is the people that flourish in a complex Ruby application prefer to read code over documentation.


> It's more of a sense that people with patience and a kind of outcome oriented approach (over fixating on why something is done a certain way) will have an easier time unwinding the complexity.

You hit the nail on the head.


This is so true, I comprehend with this almost every other day


Makes sense. In some ways there's less magic to ruby, because it's not using macros, templates, reflection, generics etc. In other languages you're stepping out of "normal" code into "special" code to make the magic work.


I loved it.. until something broke and searching a method name didn’t work because it was using dynamic method names. A full day of unpacking the Spree Commerce shipping system put me off a bit.


Yeah sure - it absolutely has drawbacks. I too have spent time going "what the heck is this actually doing". But man when you're not debugging one of those wonky things, Rails just feels like programming with a rocket strapped to your chair.

Is it the most maintainable code? No. Is it the easiest to understand? It depends tbh. Rails provides so much out-of-the-box stuff that lots of rails apps end up looking sufficiently similar, especially if they're small-to-medium-sized. But yes you can end up writing some dreadful spaghetti without a bit of discipline, but imo that's true of python and (node) js as well.

But damn is it SO fast to get up and going. And given product-market fit is why most projects and products fail, it's hard to argue against using Rails for me, since if I'm even still here to complain about it later, that's already a win.


> Rails just feels like programming with a rocket strapped to your chair.

I know this feeling!


I'm not super proficient with Ruby/Rails but we use it for our backend at work, and this reflects a large portion of the time I've spent using it. People who use Rails every day take for granted just how much magic there is and how confusing it can be for someone less experienced with it.


Adding here, a lot of this unknown is mitigated by convention over configuration in Rails.

If one using Rails accepts this and tries not to fight it, then the metaprogramming of Rails provides a lot of goodies.


Which is great in theory, until you realize that there are 200 pages of convention, and there is just enough room for interpretation that different companies have slightly different takes on it.


I think here, different people have different preferences.

I prefer convention over configuration because once learned it just works. For me in Rails when I look at an URL, I kinda know what is the file that handles that (the controller). And that is what I appreciate.

Of course, different needs require different solutions. I also worked with Sinatra which does not have this. But I choose it exactly because it is light and it allows me to group my logic in a different way.


Ruby metaprogramming breaks `grep` and static analysis tools. This is a no-go for any large project for me


I like metaprogramming for gems, libs, DSLs, etc. stuff that rarely changes, where the maintainers knows where all the bodies are buried. I rarely use it for business logic for the reason above.


Same for me. I am now happily using Crystal as a ruby-with-a-compiler and the joys of the beginning are coming back.


+1 for Crystal; amazing language.


That’s what irb is for. But yeah it’s not always obvious how to reproduce a prod issue. Frankly it tends to be a lot of tribal knowledge, so if you’re working at a big Ruby shop don’t be shy about asking the more knowledgeable devs questions.


Other than a 60ms startup differential Ruby doesn't sacrifice ANY speed compared with Python. Those days are over.


If you're just using it for quick scripting, which is where startup time mostly matters, and you only use the stdlib and no external gems, you can use --disable-gems and it starts in half the time as python for me.


Hey, you're right. Down from 100ms to 30ms which is 10ms faster than Python. So it's game over for Python, not Ruby, after all ;-)


Well, both are quite slow for what it’s worth, compared to most other programming languages.

Which is still plenty fast for CRUD web applications even at large scales, don’t get me wrong, I’m just pointing out that JS for example often has a 10x multiplier between it and Ruby/Python.


It hasnt' stopped Python, by some metrics, from competing in popularity with JS. Some even put Python ahead.


As I wrote, performance is not the end-all goal.

Python is the de facto glue language.


Has Python launch time gotten faster? It used to take a second to start up, where Ruby would be instant on the same machine.


> overall I like how magical Rails feels because it lets me go so fast

You going "fast" now means that others (including the future you) will go "slow" later.


I don't know if thats true. I've been working on Rails apps for over 10 years (some poorly written.) I worked on one particular Rails app for 7 years.

I've also worked on Java, Go, Elixir, and Haskell codebases.

I find that anytime we went "Slow" was because of decisions that were made around the data model, which can happen in any framework or language.

The thing that I love about working in Ruby is Rubyists tend to write fantastic tests (which double as documentation of what ever business logic), and the culture around "convention over configuration."

So even when we decided to port one of those Rails apps to Elixir/Phoenix, it wasn't an absolutely awful rewrite.


Is that true in languages like Lisp or Smalltalk? Is it true with Rails?


Future maintainers will go slow no matter what.


That isn’t my experience. Using a good statically typed language means that refactors will be fast. Using Ruby/Rails or similar means that you may not be confident after you’ve introduced important changes in your code base. So you might be more conservative? Take more time, do more testing (than was necessary if you used less meta programming and a more statically typed language)


The deeper you go in ruby, the more you regret metaprogramming.

It's fine for those 2-3 cases, and should be banned everywhere else. In rails is highly abused. What rails achieved and it's good at can be achieved with less metaprogramming, but of course nobody is going to build another rails, since rails is already there.


Rust does it well, too. For such a crunchy language, there are a surprising number of macros, but my experience using them has always been fantastic.


Rust’s macro system is the first I’ve seen with the same potential. But of course, an equal to Rails has yet to surface; and even if one does, being a compiled language still counteracts a lot of its ergonomics.


Excuse me netizen, do you have a moment to talk about our Lord and Savior, Lisp?


With Lisp, is it even metaprogramming? Or maybe everything is metaprogramming…


Or everything is just a list.


Try Clojure. It takes metaprogramming to a level higher than Ruby's.


This would be compelling if your goal in using Ruby is to gain easy access to metaprogramming tools.

Metaprogramming is just one of the things that make Ruby a joy to use. It's not really a reason unto itself.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: