7 ms·
Ruby 3.5 Feature: Namespace on read
- semiquaver 1y agoThis 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 1y agoIdentifying it as an experimental feature (disabled by default) seems like a reasonable way to make progress and iron out any problems.
- baggy_trough 1y agoI'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- 1y agoI 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.
- Alifatisk 1y agoFirst 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 1y agoIt 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- 1y ago>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 1y agoYou still need to rely on the library maintainers to use them. This mechanism allows you to sandbox a library that doesn't.
- psychoslave 1y agoOk, understood. This being into account, would it not even better to make the most obvious way to code some logic most likely shaped without this issue in the first place. Because, if the external dependency smells that bad, what the root cause? If that is crap code produced thus for some reason (unskilled/over-time-bound-pressured person for example), then probably this is better to avoid using this code altogether. And if this is instead because the language encourage easy path with bad outcomes, then it might make more sense to make a proposal with a facility to instead make the path of least resistance be something of more enjoyable outcome.
- zwnow 1y agoI 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
- rileytg 1y agoRuby on Rails is still very much alive and well. https://news.ycombinator.com/item?id=43130546 https://news.ycombinator.com/item?id=43130546 https://news.ycombinator.com/item?id=43881035 https://news.ycombinator.com/item?id=43881035 https://news.ycombinator.com/item?id=42253735 https://news.ycombinator.com/item?id=42253735 and more: https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=false&query=rails&sort=byPopularity&type=story https://hn.algolia.com/?dateRange=pastYear&page=0&prefix=fal...
- afavour 1y agoI'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 1y agoYea, 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 1y agoI 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
- frou_dh 1y agoI 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.
- JohnBooty 1y agoIn 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."
- hartator 1y agoYeah, and it kind of defeat passing PORT as a global variable. Like you might expect PORT=2917 to do effect these apps ports.
- JohnBooty 1y agoI'd call that some pretty bad behavior; behavior that I'd like to... if not dissuade, at least not encourage.
- tinco 1y agoI 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.
- ezekg 1y agoI 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.
- hartator 1y agoYeah, and I rather them focusing on performance instead of features. 2.7.8 is still the fastest and it’s getting old.
- dalyons 1y agoHuh? How is 2.7 the fastest ? There have been tons and tons of major performance gains since then, even without getting into yjit
- tiffanyh 1y agoYou 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 https://speed.yjit.org/history.html
- chao- 1y agoHaving upgraded one large and two small applications in the last few years, this is not my experience. Even without YJIT, just upgrading to Ruby 3.2 and beyond saw performance improvements over the same application on 2.7.
- andruby 1y agoI 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.
- usrbinenv 1y ago
- felipemesquita 1y agoThis 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-state-security-around-npm-package-management.html https://naildrivin5.com/blog/2019/07/10/the-frightening-stat...
- irjustin 1y agoI 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 1y agoEw. No.
- zoky 1y agoI mean, nothing is stopping you from doing something like: require 'foo' Bar = Foo::Bar
- PufPufPuf 1y agoMost definitely. When I worked with existing Ruby codebases, it was surprisingly hard to answer the question "where is this defined" when every import is dumped into a single global namespace. I had no idea where stuff came from, and neither the IDE.
- sethrin 1y agoUse the `method` method to get a reference to the one you are concerned with, then call `source_location` on it.
- irjustin 1y agoThat's only during runtime. Simply reading code can be annoyingly difficult without hard references. Especially when the code is coming from a gem. Many times LSP's can't figure out where the code is coming from if it's a few layers deep. Then you're stuck with the time consuming method of running the code and doing something like what you're describing above just to read it.
- Spivak 1y agoAnd even good type checkers can't infer every symbol statically where Python/JS has no issue with it.
- deleted 1y ago[deleted]
- Joker_vD 1y agoAs 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. Edit: apparently, people who do love Ruby are also against this feature, for roughly the same reasons. Kinda funny, but entirely reasonable in hindsight.
- gejose 1y agololwut?
- usrbinenv 1y agoTo add to my other comments ITT, I was thinking how the proposed name-spacing in Ruby would work is, in one way, diametrically different from Go where you'd normally import a package with the name that was chosen by the package author. But, at the same time, you could choose to import it under a different name or with no namespace at all, using the dot prefix. I'm not sure which is better. I suppose I could agree Go has a better default when it comes to namespaces.
- vidarh 1y agoIt's not straightforward to prevent the original name from existing, though you can play games with File.read() and class_eval, but if you just want it to be available under a different name, and don't mind that the old one is there too, you can just do: require 'foo' module MyPreferredNamespace include Foo end
- gitroom 1y agoHonestly after 15 years in ruby, changes like this always make me wonder who they're for. Saw way more value in the old-school simplicity - you ever feel like new language features just pile on more headaches than they fix?
- dudeinjapan 1y agoI'm against this because it will be abused, and cause chaos vis-a-vis well-established conventions in the Ruby world. The example given in the ticket, defining a global constant PORT in the root namespace and then loading it separately into two apps--nobody actually does in Ruby this today, because it is well-known that it will cause conflicts. Any gem (Ruby library) that did this sort of thing has long-since been barked at and corrected--the solution is simply to nest the constant inside your main module e.g. MyGem::PORT. Now, gems will be free to define whatever constants/modules/etc. they want. When someone files an issue, the response can be: "Oh you don't like that I redefined Array? Load my gem in a namespace!"
- benatkin 1y agoI think in a way it's similar to ShadowRealm in JavaScript. https://github.com/tc39/proposal-shadowrealm/blob/main/explainer.md#Motivations https://github.com/tc39/proposal-shadowrealm/blob/main/expla...
- jacobevelyn 1y agoI see a lot of comments here asking about practical motivations for this feature. One I'll share is that in a gem I help maintain, we benchmark git branches of the gem against `main`, and we also benchmark against multiple other gems that sometimes have namespace collisions with each other. To make this work, we use a third-party gem[0] and an anonymous module trick[1] that are each a bit hacky. That being said, I have no particular stance on whether this feature is a good change to the language; in a decade of Ruby this is the only situation I can recall that really merited it, and the concerns articulated by byroot and others do resonate with me. [0] https://github.com/panorama-ed/memo_wise/blob/main/benchmarks/benchmarks.rb#L17-L19 https://github.com/panorama-ed/memo_wise/blob/main/benchmark... [1] https://github.com/panorama-ed/memo_wise/blob/main/memo_wise.gemspec#L10-L12 https://github.com/panorama-ed/memo_wise/blob/main/memo_wise...
- transfire 1y agoDo we really need a new “code container” type for this? Could modules not serve the purpose by localizing require. e.g. module Foo require “bar” … end So everything bar.rb loads in safely within Foo?
- achernik 1y agothis would be a major breaking change
- krispyfi 1y agoNamespaces are one honking great idea -- let's do more of those!
- kristel100 1y ago[dead]
- deleted 1y ago[deleted]