Ruby: require vs require_require_require - Ruby < 1.9.2 및 >= 1.9.2에서 실행되는 문제를 해결하기 위한 모범 사례
원하는 경우 가장 좋은 방법은 무엇입니까?require
루비에 있는 상대 파일과 1.8.x와 >=1.9.2 모두에서 작동하기를 원합니다.
몇 가지 옵션이 표시됩니다.
- 해요.
$LOAD_PATH << '.'
다 요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ - 하다, 하다, 하다, 하다, 하다, 하다, 하다, 하다, 나다
$LOAD_PATH << File.dirname(__FILE__)
require './path/to/file'
- 확인해 보다
RUBY_VERSION
< 1.9.2, 정의를 정의합니다.require_relative
~하듯이require
,사용하다require_relative
에 - 확인해 보다
require_relative
하는 경우. 존재하는 경우 이전 사례와 같이 진행해 보십시오. - 와 같은 이상한 구조를 사용합니다.
Ruby 1.9에서 완전히 작동하지 않는 것 같습니다. 예를 들어, 다음과 같은 이유가 있습니다.require File.join(File.dirname(__FILE__), 'path/to/file')
$ cat caller.rb require File.join(File.dirname(__FILE__), 'path/to/file') $ cat path/to/file.rb puts 'Some testing' $ ruby caller Some testing $ pwd /tmp $ ruby /tmp/caller Some testing $ ruby tmp/caller tmp/caller.rb:1:in 'require': no such file to load -- tmp/path/to/file (LoadError) from tmp/caller.rb:1:in '<main>'
- 더이한구조상::
효과가 있는 것 같지만, 이상하고 잘 생기지 않았습니다.require File.join(File.expand_path(File.dirname(__FILE__)), 'path/to/file')
- 백포트 보석 사용 - 약간 무겁고 루비 보석 인프라가 필요하며 다른 해결 방법도 많이 포함되어 있습니다.
require
관련 파일로 작업할 수 있습니다.
StackOverflow에는 몇 가지 사례를 더 제공하는 밀접한 관련이 있는 질문이 있지만, 이 질문은 명확한 답변을 제공하지 않습니다. 이는 모범 사례입니다.
Ruby <1.9.2와 >=1.9.2 모두에서 내 애플리케이션을 실행할 수 있는 괜찮은 범용 솔루션이 있습니까?
갱신하다
명확화:저는 "당신은 X를 할 수 있습니다"와 같은 대답을 원하지 않습니다 - 사실, 저는 이미 문제의 대부분의 선택을 언급했습니다.저는 이론적 근거, 즉 왜 그것이 최선의 관행인지, 그것의 장단점은 무엇인지, 그리고 왜 그것이 다른 것들 중에서 선택되어야 하는지를 원합니다.
이에 대한 해결책이 'aws' 보석에 추가되어 이 게시물에서 영감을 얻었기 때문에 공유하려고 생각했습니다.
https://github.com/appoxy/aws/blob/master/lib/awsbase/require_relative.rb
unless Kernel.respond_to?(:require_relative)
module Kernel
def require_relative(path)
require File.join(File.dirname(caller[0]), path.to_str)
end
end
end
사할수있다를 사용할 수 .require_relative
1 1과 12의 루비 1.8과 1.9.1의 루비 1.9.2와 마찬가지로.
1.9.2로 점프하기 전에는 상대적인 요구 사항을 위해 다음을 사용했습니다.
require File.expand_path('../relative/path', __FILE__)
처음 봤을 때는 좀 이상한데, 시작 부분에 '...'가 더 있는 것처럼 보이기 때문입니다.는 그는이 때문입니다.expand_path
두 번째 인수를 기준으로 경로를 확장하고 두 번째 인수는 디렉토리인 것처럼 해석됩니다. __FILE__
분명히 디렉토리는 아니지만, 그 이후로 그것은 중요하지 않습니다.expand_path
이 존재하는지 여부에 관계없이, 파의존여재상이단같, 다것확은것다들적니입용할과 같은 몇 가지 할 것입니다...
,.
그리고.~
만약 당신이 처음을 극복할 수 있다면, "잠깐만요, 여분이 있지 않나요?"..
?" "요?" 잘 하는 것 같습니다.저는 위의 라인이 꽤 잘 작동한다고 생각합니다.
라고 가정하면,__FILE__
이라/absolute/path/to/file.rb
요.expand_path
" 열을구할것입다니성문자다▁the▁string"를 생성합니다./absolute/path/to/file.rb/../relative/path
에 '아니다', '아니다', '아니다', '아니다' ...
구성요소를 .file.rb
), 이경우, 반환을 반환합니다./absolute/path/to/relative/path
.
이게 최선의 방법입니까?무슨 뜻인지에 따라 다르지만, 레일즈 코드 베이스에 온통 깔려 있는 것 같아서 적어도 충분히 일반적인 관용구라고 생각합니다.
곡괭이에는 1.8에 대한 토막글이 있습니다.여기 있습니다.
def require_relative(relative_feature)
c = caller.first
fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/)
file = $`
if /\A\((.*)\)/ =~ file # eval, etc.
raise LoadError, "require_relative is called in #{$1}"
end
absolute = File.expand_path(relative_feature, File.dirname(file))
require absolute
end
기본적으로 테오가 대답한 것만 사용하지만 그래도 사용할 수 있습니다.require_relative
.
$LOAD_PATH << '.' $LOAD_PATH << File.dirname(__FILE__)
이것은 좋은 보안 습관이 아닙니다. 왜 전체 디렉토리를 노출해야 합니까?
require './path/to/file'
루비_VERSION < 1.9.2이면 작동하지 않습니다.
와 같은 이상한 구조를 사용합니다.
require File.join(File.dirname(__FILE__), 'path/to/file')
더 이상한 구조:
require File.join(File.expand_path(File.dirname(__FILE__)), 'path/to/file')
백포트 보석을 사용합니다. 루비젬 인프라가 필요하고 다른 해결 방법도 많이 포함되어 있지만, 저는 상대적인 파일로 작업하기를 원합니다.
이러한 옵션이 최선의 옵션이 아닌 이유에 대해 이미 답변하셨습니다.
RUBY_VERSION < 1.9.2인지 확인한 다음 require_relative를 필요에 따라 정의하고 이후 필요한 모든 곳에서 require_relative를 사용합니다.
require_message가 이미 있는지 확인하고, 이미 있으면 이전 사례와 같이 진행해 보십시오.
이 방법이 효과적일 수도 있지만 로드 오류 예외를 처리하는 더 안전하고 빠른 방법이 있습니다.
begin
# require statements for 1.9.2 and above, such as:
require "./path/to/file"
# or
require_local "path/to/file"
rescue LoadError
# require statements other versions:
require "path/to/file"
end
저는 rbx-require-relative gem(소스)을 사용하는 것을 좋아합니다.원래 루비니우스를 위해 작성되었지만 MRI 1.8.7도 지원하며 1.9.2에서는 아무것도 수행하지 않습니다.보석을 요구하는 것은 간단하며, 제 프로젝트에 코드 스니펫을 던질 필요가 없습니다.
Gem 파일에 추가:
gem "rbx-require-relative"
그리고나서require 'require_relative'
앞에서require_relative
.
예를 들어 테스트 파일 중 하나는 다음과 같습니다.
require 'rubygems'
require 'bundler/setup'
require 'minitest/autorun'
require 'require_relative'
require_relative '../lib/foo'
이것은 이러한 IMO 중에서 가장 깨끗한 솔루션이며, 보석은 백포트만큼 무겁지 않습니다.
이제 보석을 통해 백포트를 개별적으로 로드할 수 있습니다.
그러면 간단하게 다음을 수행할 수 있습니다.
require 'backports/1.9.1/kernel/require_relative'
# => Now require_relative works for all versions of Ruby
것이.require
최신 버전에는 영향을 주지 않으며 다른 기본 제공 메서드도 업데이트하지 않습니다.
다른 옵션은 인터프리터에게 검색할 경로를 알려주는 것입니다.
ruby -I /path/to/my/project caller.rb
__FILE_을 기반으로 한 솔루션에서 제가 지적하지 않은 한 가지 문제는 심볼릭 링크와 관련하여 중단된다는 것입니다.예를 들어 다음과 같이 가정합니다.
~/Projects/MyProject/foo.rb
~/Projects/MyProject/lib/someinclude.rb
메인 스크립트, 진입점, 응용 프로그램은 foo.rb입니다.이 파일은 내 $PATH에 있는 ~/스크립트/foo에 연결되어 있습니다.이 require 문은 'foo'를 실행하면 깨집니다.
require File.join(File.dirname(__FILE__), "lib/someinclude")
__FILE__이 ~/Scripts/foo이므로 위의 require 문은 ~/Scripts/foo/lib/some include.rb를 찾습니다.해결책은 간단합니다.__FILE__이(가) 심볼 링크인 경우 이 링크를 참조 취소해야 합니다.pathname#realpath는 다음과 같은 상황을 해결하는 데 도움이 됩니다.
경로 이름 필요File.join(File.dirname(Pathname.new(__FILE__).realpath), "lib/some include")가 필요합니다.
보석을 만들고 있다면 적재 경로를 오염시키고 싶지 않을 것입니다.
그러나 독립 실행형 응용 프로그램의 경우 처음 두 예에서와 같이 현재 디렉터리를 로드 경로에 추가하면 매우 편리합니다.
저의 투표는 목록의 첫 번째 선택지로 갑니다.
저는 탄탄한 루비 베스트 프랙티스 문헌을 보고 싶습니다.
나는 나 자신을 정의할 것입니다.relative_require
존재하지 않는 경우(예: 1.8 이하), 모든 곳에서 동일한 구문을 사용합니다.
Ruby on Rails way:
config_path = File.expand_path("../config.yml", __FILE__)
언급URL : https://stackoverflow.com/questions/4333286/ruby-require-vs-require-relative-best-practice-to-workaround-running-in-both
'programing' 카테고리의 다른 글
R을 사용하여 지정된 확장자를 가진 모든 파일 나열 (0) | 2023.06.07 |
---|---|
.xib 파일과 .storyboard의 차이점은 무엇입니까? (0) | 2023.06.02 |
온라인에서 안드로이드 소스 코드를 어디서 찾을 수 있습니까? (0) | 2023.06.02 |
Android 소프트 키보드를 프로그래밍 방식으로 닫거나 숨기는 방법은 무엇입니까? (0) | 2023.06.02 |
IMvcBuilder AddJsonOptions는 어디에서 사용되었습니까?Net Core 3.0? (0) | 2023.06.02 |