From: Stephen Bannasch Date: 2010-08-29T23:53:05+09:00 Subject: [ruby-core:31928] Re: Avoiding $LOAD_PATH pollution At 2:01 PM +0900 8/29/10, Eric Hodel wrote: >On Aug 28, 2010, at 23:45, Run Paint Run Run wrote: >> >>>> How confident are we that this API would be sufficient for replacing the >>>> multiude of require hacks present in the various RubyGems replacements? >> >>> I know of no successful RubyGems replacement that alters Kernel#require >>> (rvm, bundler, isolate depend on RubyGems, RubyOpals never got off the >>> ground, RPA is long dead). >> >> Ah, OK. I thought I'd read about various libraries overriding `require`, and >> chaos resulting, but I can't find the thread again, so was possibly >> hallucinating. > >Yes, I recall this thread... I don't know of any wide-spread use of the idea besides RubyGems. I think it was a theoretical discussion. > >> Theoretically, the presence of arbitrary objects in $LOAD_PATH breaks backward >> compatibility in that users may expect an Array of Strings. That's not a >> significant hurdle, however. > >Yes. > >How often do people use $LOAD_PATH besides printing it? Scanning through a local dir with many gems most of the uses are adding to $LOAD_PATH using '<<', 'unshift', 'shift',and 'push' Scanning through these gems: aasm, activerecord-import, activerecord-jdbc-adapter, arel, aruba, awesome_print, awestruct, bj, bones, buildr, bundler, chef, cloud-crowd, compass, composite_primary_keys, couch_foo, cucumber, datamapper, desert, docrails, dropbox, earth, em-http-request, execwar, extlib, fakeweb, ffi-zlib, gem-this, gherkin, gist, git_remote_branch, goio, goio-ffi, haml, has_many_polymorphs, jammit, jasmine-gem, jeweler, journeta, libxml, mail, merb, mixlib-cli, mongrel, neo4j, nokogiri, ohm, passenger, persevere, prawn, prawn-format, rack, rack-fiber_pool, rack-reverse-proxy, radiant, railroad, rails, rainbows, rake, rake-compiler, rawr, rcov, rdoc, redcar, ri_cal, rjack, rspec, rspec-core, rspec-rails, ruby-debug, ruby-debug-ide, showoff, sinatra, sinatra_more, specjour, spork, sqlite3-ruby-1.2.4, strokedb, test23, threadz, treetop, ttfunk, ultraviolet, warbler, webrat, words, yajl-ruby, yard Here's the interactions with $LOAD_PATH that don't involve adding to it using: '<<', 'unshift', 'shift', 'concat' and 'push' or directly printing it: $LOAD_PATH.clear $LOAD_PATH.delete File.expand_path('../unregistered_handler', __FILE__) $LOAD_PATH.delete(@other_load_path) $LOAD_PATH.delete(@path) $LOAD_PATH.each do |base| $LOAD_PATH.each do |path| $LOAD_PATH.include?(File.expand_path(__DIR__)) $LOAD_PATH.include?(__DIR__) || $LOAD_PATH.index(File.join(RAILS_ROOT, 'lib')) || 0 $LOAD_PATH.insert(application_lib_index + 1, path) $LOAD_PATH.reject! do |p| $LOAD_PATH.reject! { |path| !(original_load_path.include?(path)) } $LOAD_PATH.replace @_sandbox[:load_path] $LOAD_PATH.should include(libdir) $LOAD_PATH.should include(specdir) $LOAD_PATH.should_receive(:unshift).with("a/dir") $LOAD_PATH.stub!(:unshift) $LOAD_PATH.uniq! !$LOAD_PATH.include?(component_path) $servlet_context.log("LoadError while loading '#{library}', current path:\n " + $LOAD_PATH.join("\n ")) %w{test lib ext/libxml}.each{ |path| $LOAD_PATH.unshift(path) } @options[:load_paths].each {|p| $LOAD_PATH << p} @snoop[:load_path] = $LOAD_PATH @snoop[:load_path] = $LOAD_PATH @_sandbox[:load_path] = $LOAD_PATH.clone abs = $LOAD_PATH.map { |path| ::File.join(path, loaded) }. ar_lib_path = $LOAD_PATH.detect {|p| p if File.exist?File.join(p, ar_version)} assert $LOAD_PATH.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib')) assert $LOAD_PATH.include?(File.join(plugin_fixture_path('default/stubby'), 'lib')) assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib')) >= assert $LOAD_PATH.index(File.join(plugin_fixture_path('default/stubby'), 'lib')) >= stubbed_application_lib_index_in_LOAD_PATHS assert load_paths_count.select { |k, v| v > 1 }.empty?, $LOAD_PATH.inspect def add_dir_from_project_root_to_load_path(dir, load_path=$LOAD_PATH) # :nodoc: def rake_require(file_name, paths=$LOAD_PATH, loaded=$") describe $LOAD_PATH do dir = $LOAD_PATH.find { |dir| File.exist? File.join(dir, file) } env["test.$LOAD_PATH"] = $LOAD_PATH f << "$LOAD_PATH.unshift 'file:' + dir + '/#{rack_dir}'\n" f << "$LOAD_PATH.unshift dir + '/#{rack_dir}'\n" files = $LOAD_PATH.map do |p| if $LOAD_PATH.first != LIBDIR if ( $LOAD_PATH.index( ext_dir ).nil? ) it "should prepend gemspec require paths to $LOAD_PATH in order" do libs.map {|lib| $LOAD_PATH.unshift lib} libs.reverse.each{|lib| $LOAD_PATH.unshift(lib)} load_paths = spec.load_paths.reject {|path| $LOAD_PATH.include?(path)} load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) } load_paths_count = $LOAD_PATH.inject({}) { |paths, path| on("--dev", "Add this project's bin/ and lib/ to $LOAD_PATH.", on("-I PATH", "Add PATH to $LOAD_PATH") do |path| opts.on("-I", "--include PATH", String, "Add PATH to $LOAD_PATH") do |path| opts.on('-I', '--include PATH', String, 'Add PATH to $LOAD_PATH') do |path| original_load_path = $LOAD_PATH ORIGINAL_LOAD_PATH = $LOAD_PATH.dup ORIGINAL_LOAD_PATH.each { |path| $LOAD_PATH << path } parser.on('-I DIRECTORY', 'specify $LOAD_PATH directory (may be used more than once)') do |dir| path = $LOAD_PATH.grep(/#{gem_name}[\w.-]*\/lib$/).first paths = ['./', *$LOAD_PATH].uniq plugin.load_paths.each { |path| $LOAD_PATH.unshift(path) } plugin_load_paths.each { |path| assert $LOAD_PATH.include?(path) } puts $LOAD_PATH.grep(/activesupport/i) puts( $LOAD_PATH.inject([]) do |res, path| require spec_classes_path unless $LOAD_PATH.include?(spec_classes_path) template_dir = $LOAD_PATH.map do |path|