5 ms·
From the bottom of the comments on that issue: sovereign> @drbrain It's a different approach, where a dependency resolver in runtime is no longer needed. I've
by ollysb 13y ago
From the bottom of the comments on that issue:
sovereign> @drbrain It's a different approach, where a dependency resolver in runtime is no longer needed. I've been using that approach for the past six years, and during all that time I have been the happiest rubyist in town while my friends struggle with Bundler. The idea is to trade space for complexity. Once the gems are installed in isolation, there's no need for dependency resolution in runtime. </sovereign
Isn't the point of the Gemfile.lock that your dependencies are not resolved at runtime? If I've misunderstood I'd really appreciate an explanation of the difference compared to say NPM. I've also never seen any practical difference between NPM and Bundler and have often wondered why people like the NPM implementation so much.
- plorkyeran 13y agoWith Bundler, you have a single copy of each (version of each) library installed, and Bundler decides at runtime which to make visible (which is trivial with Gemfile.lock, since all of the interesting logic is done when creating that). This decision is a global one, so if you depend on two libraries that themselves depend on libfoo, both of those libraries have to use the same libfoo, and there's no difference between having a direct dependency on libfoo and depending on a library that depends on libfoo. With npm, each library has its own set of dependencies (and those libraries have their own sets of dependencies, and so on) that are entirely separate. Thus, if you depend on two libraries that use libfoo, those two libraries have their own copies of libfoo - and those two copies can be different versions, if needed (and if libfoo depends on libbar, you'll have two copies of that too). This makes the presence of dependencies much less leaky and eliminates most problems with incompatible gem versions at the cost of wasted disk space, (usually trivially) increased memory usage and some potential confusion. It also happens to make npm pretty mind-numbingly simple compared to bundler's dependency resolution logic.
- yxhuvud 13y agoIt sounds like npm quite easily can become a dependency hell where you have no idea whatsoever what code is actually being run.
- pilif 13y agoOn one hand that's certainly true. On the other: Do you care how $LIB does some work for you? Does it matter to you whether $LIB uses $OTHERLIB in version 0.1 or 0.2? Does it matter to you whether $LIB bundles $OTHERLIB as a package or whether it just includes the source code of $OTHERLIB? Yes. I see the security implications of running an outdated $OTHERLIB, but that's $LIB's responsibility, no matter whether they include a copy of $OTHERLIB as its own package in a subdirectory or whether they just copy $OTHERLIB into their own code base. Once you bundle dependencies, you're responsible for security holes in them. The other issue of course is RAM usage once you start running multiple identical copies of $OTHERLIB, but that's only if they use identical versions. If it's different versions, you will have to run multiple copies at once or you risk breaking your dependencies. Or you don't run at all (Bundler's "solution")
- stormbrew 13y agoI'm not sure there's any universal answer to the questions you pose in your first paragraph. The problem is that sometimes you do care (sometimes a library is actually an interface into some kind of stateful machine) and sometimes you don't (when it's just objects that hold their own state). To some extent javascript gets a bit of a free ride on this question because most libraries are designed around there being only one global state machine (the event loop), but ruby doesn't impose an execution model on you.
- plorkyeran 13y agoYeah, I think npm's model is the correct one for node, but it's not universally better than all others by any means. It's not possible at all in many languages, would result in absurd compilation times and disk space usage in compiled languages, and makes security audits much more difficult. It's certainly not very compatible with an environment where every dependency requires external approval.
- jrochkind1 13y ago> Do you care how $LIB does some work for you? Does it matter to you whether $LIB uses $OTHERLIB in version 0.1 or 0.2? Only when debugging. But that's a pretty big 'only when'
- djur 13y agoRubygems doesn't have the luxury of providing that kind of system, though, because of how 'require' works in Ruby. AMD/RequireJS allows requires to be scoped, while Ruby requires dump directly into the global namespace.
- xs_kid 13y agoRight and the guy of the last comment of the issue is proposing also an solution for it: https://github.com/soveran/cargo https://github.com/soveran/cargo
- ollysb 13y agoI was wondering how you could achieve the same level of isolation in ruby, this looks like a very interesting project. Ruby projects move fast and even though they're pretty good about semantic versioning this isn't enough to save you when your Gemfile starts filling up. Cargo looks like a huge improvement over require.
- stormbrew 13y agoNo matter what it's too leaky an abstraction. Everything in the stdlib uses require. Every fundamental piece of ruby code not in the stdlib uses require. The process of getting from point A to point C involves crossing a point B so frustrating, limiting, and ugly no one is really willing to cross it. Ruby's global constant namespace was probably a mistake in hindsight, but at this point it'd be a language fork to change it meaningfully.
- rschmitty 13y agoCan't you just "vendor everything" and now each project will install all of the gems locally to vendor and not be concerned about global choices? http://ryan.mcgeary.org/2011/02/09/vendor-everything-still-applies/ http://ryan.mcgeary.org/2011/02/09/vendor-everything-still-a...
- tomphoolery 13y agoSure, but if you use Git this can get pretty hard to deal with especially on large repos with lots of history. A `git clone` downloads an entire repo, and all of its history...so if you have a bunch of gems or executables in there that boosts the contents of your repo tremendously. This is why there is `bundle install --deployment`, which "freezes" the Gemfile and ensures it has not changed from what has been committed to the repo. If it has, `bundle install` will not succeed.
- tomphoolery 13y agoI do like npm's simplicity. You used to have to be really careful with the versions, because if you didn't specify it would just download the latest version, and sometimes some of your dependencies would use the wrong versions of libraries and APIs would change and things go haywire. I think they've fixed a lot of that now, though...it was certainly easier a few months ago than it was a few years ago.