Require возвращает массив вместо логического

#ruby #require

#ruby #требовать

Вопрос:

Согласно документации для ядра#require, метод возвращает логическое значение. Однако я заметил в сеансе IRB, что для некоторых файлов require возвращает массив.

 ruby-1.8.7-p330 :001 > require 'net/http'
=> true 
ruby-1.8.7-p330 :002 > require 'date'
=> true 
ruby-1.8.7-p330 :003 > require 'lib/data_provider'
=> ["DataProviders"] 
  

Возвращаемый массив содержит имя модуля, определенного в data_provider.rb:

 module DataProviders
  module Cached
    class Foo
    # ...
    end
  end

  class Foo
  # ...
  end
end
  

Это признак того, что я делаю что-то неправильно или какое-то недокументированное поведение require ?

Комментарии:

1. Я не могу воспроизвести это ни в 1.8.7, ни в 1.9.2. Кроме того, я взглянул на исходный код (eval.c: 7405), и функция, похоже, не может вернуть ничего, кроме true / false.

2. Хорошо, думаю, теперь я понял. Оказалось, что у меня было require 'rubygems' и require 'active_support' ранее в этом сеансе IRB. И похоже, что ActiveSupport от Rails вызывает разницу в поведении. В require ActiveSupport есть метод::Dependencies::Loadable .

Ответ №1:

Я тоже не могу его воспроизвести. Но возможно, что какой-то gem переопределяет Kernel#require :

 module Kernel
  alias_method :old_require, :require
  def require(str)
    old_modules = []
    ObjectSpace.each_object(Module) {|m| old_modules << m }

    old_require(str)

    new_modules = []
    ObjectSpace.each_object(Module) {|m| new_modules << m unless old_modules.include?(m) }
    new_modules
  end
end
  

и когда вы пытаетесь потребовать

 module DataProviders
  module Cached
    class Foo
    end
  end
  class Foo
  end
end
  

вы получите

 irb(main):012:0> require 'data_provider'
=> [DataProviders::Cached::Foo, DataProviders::Foo, DataProviders::Cached, DataProviders]
  

Комментарии:

1. Да, вы правы — смотрите Мой комментарий к вопросу. Драгоценный камень, который должен быть переопределен require , является ActiveSupport от Rails.

2. 1 да, Activesupport делает много плохих вещей, переопределяя основные методы. Надеюсь, Ruby 2 решит это с помощью «уточнений» yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice