←back to thread

140 points ksec | 10 comments | | HN request time: 0.609s | source | bottom
1. stevebmark ◴[] No.41084461[source]
Ruby has a lot going for it, but as other commenters point out, the metaprogramming nightmares of the language have held it back 10-30 years behind modern language ecosystems, depending on the feature you're looking at. Celebrating "jump to source definition" (sometimes working) for such a mature language is a symptom of the nature of the language. Sometimes insane dynamic freedom is really useful, but it comes with heavy drawbacks.
replies(4): >>41085027 #>>41085047 #>>41086943 #>>41092303 #
2. jaynetics ◴[] No.41085027[source]
As someone who uses Ruby as well as plenty of other languages, I agree that it can feel awkward not to have "go to source" work reliably, but in the greater scheme of things, it's not a big drain on time to do the occasional full text search or look something up through programmatic introspection. In other areas that might really slow you down or become blocking, Ruby's ecosystem still seems OK to me. I'm thinking package management, compilation or transpilation, availability of battle-tested libraries etc.

I guess it depends on scale as well. The bigger the codebase, the nicer it is to find implementations and references automatically, and the bigger the company, the more likely they are to have good workarounds for the shortcomings of various language ecosystems or even dedicated dev experience teams, in which case Ruby's potential runtime intricacies might really start to weigh it down. Then again, there seems to be some movement away from that all-too-dynamic stuff e.g. in the rails codebase.

replies(1): >>41085553 #
3. psychoslave ◴[] No.41085047[source]
I don't think metaprogramming is the key point here, though it doesn't help with this kind of issue.

That is, yesterday I spent the afternoon trying to follow a maze of signal observers in a Vue3 project. After a moment, not finding why the redirect to login page was nowhere to be found in the signal obsevers of the concerned transition, it finally reveled to be linked to a more broad route hook mechanism that the framework provides.

No meta programming is involved, be it in signal observers or route hook.

Regarding metaprogramming, Crystal keep only the parts that are straightfoward to deal with in static analysis, from what I grasped when skiming its elevator speech.

On Ruby side the great stuffs I like in it are more linked to the homogeneous approach it follows. Almost everything is an object and something like `42.extend(:custom•module).original•action` is possible due to that. It's not 100% pure object though, reserved keywords like `if` can not be used as objects, that is `if.class` is not valid.

4. KronisLV ◴[] No.41085553[source]
> it's not a big drain on time to do the occasional full text search or look something up through programmatic introspection

Okay, this won't probably be 100% on topic, but in my experience how well these methods work is inversely proportional to the size of the codebase and also quite badly in some cases depending on how the code is written.

The other day I was working on a Java enterprise codebase (monolith, ~300K LoC) and I shouldn't have had that many issues navigating the codebase, however someone made a validator that resolves the logic to a specific class at runtime. So you'd basically have validator.validate(Object someObject). Suddenly if I wanted to find all of the places where validator.validate(MyObject myObject) is called, I could not do that easily and with naming like validator.validate(entity) all over the place, text search didn't help much either. They had an okay type system but chose not to use it, just because they wanted to pass in arbitrary objects, without regard for how easy finding usages will be in the future.

My point is, that you can probably write code that's easy or hard to navigate in any language (within reason), but I'll gladly take whatever tools I can get in any stack out there!

replies(1): >>41085944 #
5. rtz121 ◴[] No.41085944{3}[source]
> however someone made a validator that resolves the logic to a specific class at runtime. So you'd basically have validator.validate(Object someObject).

The pains of not having multiple dispatch.

6. eduction ◴[] No.41086943[source]
I’m very curious how a language that’s not yet 29 years old can be held back 30 years.
replies(1): >>41086957 #
7. sapiogram ◴[] No.41086957[source]
Makes perfect sense to me, it just means the language was already a year behind when it launched.
replies(1): >>41125884 #
8. paholg ◴[] No.41092303[source]
In emacs, there's robe mode which I found to work very well. It keeps a Ruby process running with your code loaded in it.

I wonder why no one's written a Ruby LSP with this approach rather than relying on static analysis.

https://github.com/dgutov/robe

replies(1): >>41115894 #
9. grncdr ◴[] No.41115894[source]
The ruby-lsp project made by Shopify has (or had...) a rails plugin that worked this way. It adds some routes to your server during development and uses them to introspect the running process.
10. brigandish ◴[] No.41125884{3}[source]
Which languages were ahead at that point? Haskell started in 1990, so was it only a year ahead after 5 years in existence but since then it has gone 30 years ahead and Ruby hasn’t moved forward at all, or is has it gone 30 years into Ruby’s future after another 30 years?

Or is it that the original comment showed no knowledge of programming language history? It’s a tough choice!