[ruby-on-rails] Rails 3의 lib 폴더에서 모듈 / 클래스를로드하는 가장 좋은 방법은?

최신 Rails 3 릴리스는 더 이상 lib에서 모듈 및 클래스를 자동로드하지 않으므로이를로드하는 가장 좋은 방법은 무엇입니까?

github에서 :

A few changes were done in this commit:

Do not autoload code in *lib* for applications (now you need to explicitly
require them). This makes an application behave closer to an engine
(code in lib is still autoloaded for plugins);


답변

Rails 2.3.9 부터 config/application.rb자동로드하려는 파일이 포함 된 디렉토리를 지정할 수 있는 설정 이 있습니다.

application.rb에서 :

# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)


답변

# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

출처 : Rails 3 퀵팁 : 모든 하위 디렉토리를 포함한 lib 디렉토리 자동로드, 지연로드 방지

lib 폴더에 포함 된 파일은 서버가 시작될 때만로드됩니다. 편안하게 파일을 자동으로 다시로드하려면 Rails 3 빠른 팁 : 개발 폴더에서 lib 폴더 자동 다시로드를 읽으십시오 . 영구적 인 재로드로 인해 시스템 속도가 느려지므로 프로덕션 환경에는 적합하지 않습니다.


답변

자동 로딩 기능의 마법

자동 로딩 작업이 수행되는 폴더를 제어하는 ​​옵션은 다른 답변에서 충분히 다루어졌습니다. 그러나 필요에 따라 자동로드 경로를 수정했지만 다른 사람이 문제가있는 물건을로드하는 경우이 답변은이 자동로드의 마술이 무엇인지 설명하려고 시도합니다.

하위 디렉토리에서 물건을로드 할 때 알아야 할 규칙이나 규칙이 있습니다. 때때로 루비 / 레일 매직 (이번에는 대부분 레일)이 왜 무슨 일이 일어나고 있는지 이해하기 어렵게 만들 수 있습니다. 자동로드 경로에 선언 된 모든 모듈은 모듈 이름이 상위 디렉토리 이름과 일치하는 경우에만로드됩니다. 따라서 lib/my_stuff/bar.rb다음과 같은 것을 넣으려고하면 :

module Foo
  class Bar
  end
end

자동으로로드되지 않습니다. 그런 다음 부모 디렉토리의 이름을 바꾸면 foo경로에서 모듈을 호스팅합니다 lib/foo/bar.rb. 당신을 위해있을 것입니다. 다른 옵션은 모듈 이름으로 자동로드하려는 파일의 이름을 지정하는 것입니다. 분명히 그 이름으로 하나의 파일 만있을 수 있습니다. 물건을 여러 파일로 분할 해야하는 경우 물론 하나의 파일을 사용하여 다른 파일을 요구할 수는 있지만 개발 모드에서 다른 파일을 수정할 때 Rails가 자동으로 수행 할 수 없기 때문에 권장하지 않습니다 당신을 위해 그들을 다시로드하십시오. 그러나 정말로 원한다면 모듈 이름으로 하나의 파일을 가지고 모듈을 사용하는 데 필요한 실제 파일을 지정합니다. 따라서 두 개의 파일을 가질 수 있습니다 . 그것은 동일하게 작동합니다.lib/my_stuff/bar.rb 그리고lib/my_stuff/foo.rb 이상과 한 줄을 포함하는 후자와 같은 인 전 :require "bar"

추신 : 나는 한 가지 더 중요한 것을 추가해야한다고 생각합니다. 최근에 자동로드되어야하는 lib 디렉토리에 무언가를 갖고 싶을 때마다 이것이 실제로이 프로젝트를 위해 특별히 개발하고있는 것이라면 생각하기 시작합니다 (일반적으로 언젠가는 많은 프로젝트 또는 git 서브 모듈 등에 사용되는 “정적”코드 스 니펫으로 전환하십시오 (이 경우 반드시 lib 폴더에 있어야합니다). 그러면 아마도 그 위치는 lib 폴더에 전혀 없을 것입니다. 아마도 앱 폴더 아래의 하위 폴더에 있어야 할 것입니다. 이것이 새로운 방식의 일이라고 생각합니다. 분명히, 당신이 물건을 넣은 자동로드 경로에 관계없이 동일한 마술이 작동하므로 이러한 것들에 좋습니다. 어쨌든, 이것은 주제에 대한 나의 생각입니다. 당신은 동의하지 않습니다. 🙂


업데이트 : 마법의 유형에 대해 ..

세 버린이 그의 의견에서 지적했듯이 핵심 “모듈 메커니즘 자동로드”는 루비의 일부이지만 자동로드 경로는 그렇지 않습니다. Rails가 필요하지 않습니다autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar"). 그리고 Foo 모듈을 처음으로 참조하려고하면로드 될 것입니다. 그러나 Rails가하는 일은 등록 된 폴더에서 물건을 자동으로 불러 오거나로드 할 수있는 방법을 제공하며, 명명 규칙에 대해 무언가를 가정하는 방식으로 구현 된 것입니다. 그렇게 구현되지 않았다면 현재로드되지 않은 것을 참조 할 때마다 모든 자동로드 폴더의 모든 파일을 통과하고 참조하려는 항목이 포함되어 있는지 확인해야합니다. 이것은 자동 로딩과 자동 로딩의 아이디어를 잃게됩니다. 그러나 이러한 규칙을 준수하면 모듈 / 클래스에서 정의 된 위치로로드하려고 시도하고로드 할 수 있습니다.


답변

경고 : ‘lib’폴더에서 ‘monkey patch’또는 ‘open class’를 로드 하려면 ‘autoload’접근법을 사용하지 마십시오 !!!

  • config.autoload_paths “접근 방식 : 한 곳에서만 정의 된 클래스를로드하는 경우에만 작동합니다. 어떤 클래스가 이미 다른 곳에 정의되어 있다면이 방법으로 다시로드 할 수 없습니다.

  • config / initializer / load_rb_file.rb “접근 방식 : 항상 작동합니다! 대상 클래스가 새 클래스이거나 기존 클래스의 “공개 클래스”또는 “원숭이 패치”인 경우 항상 작동합니다!

자세한 내용은 https://stackoverflow.com/a/6797707/445908을 참조하십시오.


답변

매우 비슷하지만 조금 더 우아하다고 생각합니다.

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]


답변

내 경우에는 단순히 lib 디렉토리 아래에 파일을 직접로드하려고했습니다.

application.rb 내에서 …

require '/lib/this_file.rb' 

콘솔에서도 작동하지 않고 시도했을 때

require './lib/this_file.rb' 

레일은 파일을 완벽하게로드합니다.

나는 여전히 꽤 멍청하고 이것이 왜 작동하는지 잘 모르겠지만 작동합니다. 누군가 나에게 설명하고 싶다면 감사하겠습니다 : DI 희망이 누군가에게 도움이되기를 바랍니다.


답변

나는 같은 문제가 있었다. 내가 해결 한 방법은 다음과 같습니다. 솔루션은 lib 디렉토리와 모든 서브 디렉토리 (직접뿐만 아니라)를로드합니다. 물론 모든 디렉토리에 사용할 수 있습니다.

# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]