Skip to content(if available)orjump to list(if available)

Ruby 3.5 Feature: Namespace on read

ezekg

I feel like this is a solution to a problem nobody really has in practice, by simply following conventions, and I've been using Ruby for over 10 years. If byroot -- who works at Shopify on the largest Rails codebase in existence -- echos the same sentiment, then maybe it should be scrapped.

graypegg

I really like Ruby, I do sort of wish it could focus on it's own identity a bit.

Some new features feel almost prescribed from other languages? Like, RBS and Namespaces specifically... they don't really fit the model of Ruby exactly, but they need to be there so Ruby can be presented as "having" type-safety and a-solution-for-monkey-patching. I'm all for taking inspiration from other places, but Ruby wasn't quite built around the same axioms that other programming languages started from.

andruby

I would like to second (or _third_) this opinion.

I've been working with Ruby for 20 years, and I've not needed something like this. This feels like adding a lot of complexity for little practical benefit. The trade-off feels off. I don't think this is worth the additional complexity.

fellowniusmonk

I think byroot got it exactly right with:

>First, I'm not convinced by the motivations:

>

>Avoiding name conflicts between libraries: Applications can require two different libraries safely which use the same module name.

>

>Is this a problem that happens on a regular basis? I believe Ruby has a pretty well established convention for libraries to expose a single module with a name that correspond to their gem name.

I really don't think we want to make it easier for newbies to alter gem naming conventions and run multiple versions of a gem within the same project, this sounds like a genuine nightmare to me. I've found from jumping in to fix broken and crippled rails projects for startups that the fuckup surface area is already high enough.

usrbinenv

I disagree. I've also been working with Ruby for almost 20 years and quite a few times I came across a situation where I definitely wanted to wrap my library in a module for name-spacing and it was almost always cumbersome. I'd rather not wrap it and let others (or myself) use the library name-spaced under whatever name they choose. Right now, if you're working on a gem, you have to think really hard how to name it so its top-level classes an modules don't conflict with any other modules and classes found in the Ruby ecosystem.

ezekg

> Right now, if you're working on a gem, you have to think really hard how to name it so its top-level classes an modules don't conflict with any other modules and classes found in the Ruby ecosystem.

Follow gem naming conventions and this is a non-issue -- both FooBar::Record and BazQux::Record can coexist for foo_bar and baz_qux gems, respectively. If a gem is defining other top-level constants outside of their gem module, then that's considered against convention, i.e. bad practice, and the language should not be modified to allow such a thing.

I'd like to hear of a real use case for namespaces that existing conventions don't already solve.

hosh

I thought being able to do this with Nodejs was a near capability.

Over the past two years, I have come to understand that this contributes to the nightmare that is the Nodejs ecosystem (and the browser JS exosystem in general), at least when it comes to writing reliable software.

hartator

Yeah, and I rather them focusing on performance instead of features. 2.7.8 is still the fastest and it’s getting old.

tiffanyh

You can see Ruby core perf improvements at the link below, going back 4-years.

Even though this is from the YJIT folks, they include the non-jit improvements as a comparison.

https://speed.yjit.org/history.html

dalyons

Huh? How is 2.7 the fastest ? There have been tons and tons of major performance gains since then, even without getting into yjit

null

[deleted]

frou_dh

I remember Matz gave a presentation touching on how Ruby was inspired by Lisp and particularly Emacs Lisp, which was the one he had access to. You still can feel a similarity up to now with the single big old dynamic namespace where you can monkey-patch anything if you feel like it.

semiquaver

This is a really interesting feature addressing something Ruby has long-lacked.

But I think the more interesting story is the widespread opposition to the way this was forced through in spite of major conceptual problems, bugs and performance regressions.

monooso

Identifying it as an experimental feature (disabled by default) seems like a reasonable way to make progress and iron out any problems.

irjustin

I wish ruby went with hard/explicit imports like python or js.

Solves this problem and "magic" that so many complain about while retaining all the other great things to love about Ruby.

bm5k

Ew. No.

felipemesquita

This post (2019) by David Bryant Copeland about npm security goes into some of the complications that arise when multiple versions of a dependency are allowed to be loaded simultaneously:

https://naildrivin5.com/blog/2019/07/10/the-frightening-stat...

Alifatisk

First the Data class and now this, very interesting to see! Is there any certain use case where this is well suitable? Because we already have Modules and from my understanding, can be used to namespace things. Or is the appeal here that you can perform the namespacing dynamically through ”require”?

vinceguidry

It allows you to namespace things that aren't themselves namespaced. That way you can just require things that, might say, have the same module names as your own code without worry. I'm curious if this namespace mechanism could, say, isolate monkey patches. Probably not, but it would be nifty.

chao-

>I'm curious if this namespace mechanism could, say, isolate monkey patches.

Wasn't that the purpose of refinements? Perhaps I am misremembering, because I never had a need to reach for refinements myself.

vinceguidry

You still need to rely on the library maintainers to use them. This mechanism allows you to sandbox a library that doesn't.

usrbinenv

Using Ruby modules to namespace things is certainly possible, but is very often cumbersome. Modules also "hardcode" a namespace: that is, if I use modules for name-spacing, it will always be "MyModule::MyClass" everywhere -- or, in other words, namespacing is controlled by library author, not user. The proposed feature shifts that control to library user.

zwnow

I know Ruby is still used in some codebases but what's its actual relevance in the webdev/fullstack landscape? I am currently 5 months into learning Elixir/Phoenix for fullstack and I already know a few Js based frameworks. Ruby always intruiged me, but I'd like to stay employable

afavour

I'd say Ruby is more relevant than Elixir. But you're correct (IMO) that Ruby had a big moment but has died down since. At one point it almost felt like the default choice in startup land. Not so today.

Ruby on Rails specifically has a batteries included approach that lets you get up and running very quickly. But my perception is that as JavaScript has leaked into the server (benefits of writing the same language on front and back end) it's eaten into Ruby's mindshare. Python also finally moved on from its 2 vs 3 nightmare and shares many of the benefits of Ruby.

zwnow

Yea, I am tackling Elixir to avoid learning tech specifically designed for solving scaling issues with languages not made for scaling. Elixir is wonderful for this. How's Ruby considering scaling and performance? I always compare Ruby on Rails to Laravel for some reason

freedomben

I did Ruby on rails professionally for many years, and have also done elix Phoenix professionally for many years now, and I would advise you to continue with Phoenix. Getting really good at elixir and Phoenix can make you an extremely powerful and employable developer. Should you find yourself in a situation where you need to switch to Ruby and rails, you will have a huge leg up because rails follow as many of the same patterns as Phoenix, and the Ruby language is very simple to learn for someone coming from elixir. Just my two cents of course

afavour

You typically choose Ruby on Rails because you want to get up and running fast, not because you want performance. That said, in most RoR codebases the performance bottleneck is networking, database etc not the language itself. As and when e.g. the database becomes a bottleneck there are various mitigations available to you.

ezekg

Shopify, GitHub, Intercom, among others are built on Ruby/Rails. I think it'll scale fine.

dismalaf

> How's Ruby considering scaling and performance?

Shopify, Github, AiBnB, Square, Instacart, etc...

There's more big apps/websites using Rails than Elixir or Phoenix...

skyfantom

As much as I enjoy using Elixir, I’m not sure at the moment learning Elixir over Ruby gives more options for being hired.

Open any “Who is hiring” and compare number of Elixir positions vs Ruby.

graypegg

Use whatever you feel most effective in. I would say Ruby is around much more than you might expect by the sounds of it. (The usual big names touted on the Rails homepage + many start ups + agency products) though it's definitely over the hype period.

For being employable... I'd say Ruby is going to be near the middle of the pack. Elixir is going to be near the harder-side, and JS is going to be near the easier-side... on average IMO.

If you think ruby intrigues you, give it a try! You've got precious time + motivation for this sort of thing, but messing around with a programming language is not much effort if you're intrigued. Getting a feel for it is a sub-weekend project away. It's my favourite language for bodging, the scripts I make in ruby for little data-mashing or system things are surprisingly stable and readable, even a year or two later. (Compared to a nodejs, perl or shell script... which all tend to have understandability-half-lives of a month for me haha) Automate something you find annoying.

JohnBooty

In the micro, this is definitely a useful crutch for using badly-written/badly-behaved code.

(In the example, it usefully provides a way to maintain sanity when `app1.rb` and `app2.rb` both define a global constant named `PORT`)

However, I'm not sure how much existing code is defining stuff in such a poorly considered way. (I don't mean that rhetorically. Maybe it's more pervasive than I think)

Furthermore, would adding this feature to the language actually encourage such bad behavior? (Would it even be "bad" behavior at that point?)

So I'm kind of leaning toward "I can see how this would be useful, but I don't want the language to condone such a bad practice."

tinco

I can rest your mind, I've being coding Ruby for 17 years now, and I've never seen two gems or even files define the same global constant in a way that wasn't intentional. It's fair to say it's not at all pervasive.

That said, I do think there's use to this. First of all it would allow fancy platforms like RoR to make more effective use of namespaces. Right now you always need to specify the fully qualified name of a constant whenever you're defining it, which is just not aesthetically pleasing.

Another potentially useful place for this is in migrations. If you could just move the old implementation of a thing into a subdirectory and then load it into a namespace you make references to it a lot more explicit, and you give the replacement architecture full freedom within its root namespace.

Just to say, it's not only bad behavior that would be enabled by this feature. I definitely agree that having gems not sticking to their own modules would be a very bad thing indeed.

hartator

Yeah, and it kind of defeat passing PORT as a global variable. Like you might expect PORT=2917 to do effect these apps ports.

baggy_trough

I've been happy with some of the great improvements to Ruby in the past year. But this one really leaves me scratching my head. It seems like a lot of complexity for what I perceive as a negative value feature. I'm concerned about damage to the gem ecosystem by encouraging gems to bundle version locked dependencies. The last thing I want is a gem deciding to have multiple versions of other gems in my app.

chao-

I agree and I am overall mixed on this.

One of the tradeoffs that (imo) has been net positive in the Ruby ecosystem, is how a project has to ultimately load and run a single set of versions of all dependencies. It creates some extra maintenance work on one hand, but the result is that it encourages the ecosystem to not have to face the hell of having 3 or 5 or 10 versions of each common dependency within a project.

I recognize that this is an occasional cost to library maintainers, but in the long-term has contributed to benefits. My perception is that Ruby libraries have smaller list of dependencies than similar libraries in some other languages. There are several reasons for this, but this ecosystem pressure to stay compatible with a range of dependency versions is one of them.

It feels to me like this leads to a sweet spot for small- and medium-sized projects, and I can see it might have an upper limit? I have not been in the situation, but heard of situations where the largest projects inevitably run into needing specific versions of two separate libraries that don't agree on a version of a common dependency.

Joker_vD

As someone who can't stand Ruby, I am personally against this feature. I'd rather have my Ruby experience universally miserable, with no deception, instead of having, say, half of the language decent and sane, and another half, well, be traditional Ruby.