Ruby : require vs require_relative-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_relativerequire_relative이미 존재 하는지 확인하고 , 존재하는 경우 이전과 같이 진행하십시오.루비 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.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문자열을 구성합니다 /absolute/path/to/file.rb/../relative/path다음 해당 말한다 규칙 적용 ..(그 전에 경로 구성 요소를 제거해야합니다 file.rb반환,이 경우에는) /absolute/path/to/relative/path.
이것이 모범 사례입니까? 그 의미에 따라 다르지만 Rails 코드베이스 전체에있는 것처럼 보이므로 적어도 일반적인 관용구라고 말하고 싶습니다.
곡괭이에는 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
기본적으로 Theo가 응답 한 것을 사용하지만 여전히을 사용할 수 있습니다 require_relative.
$LOAD_PATH << '.' $LOAD_PATH << File.dirname(__FILE__)
좋은 보안 습관은 아닙니다. 왜 전체 디렉토리를 공개해야합니까?
require './path/to/file'
RUBY_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')Use backports gem - it's kind of heavy, it requires rubygems infrastructure and includes tons of other workarounds, while I just want require to work with relative files.
You have already answered why these are not the best options.
check if RUBY_VERSION < 1.9.2, then define require_relative as require, use require_relative everywhere where it's needed afterwards
check if require_relative already exists, if it does, try to proceed as in previous case
This may work, but there's safer and quicker way: to deal with the LoadError exception:
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
I'm a fan of using the rbx-require-relative gem (source). It was originally written for Rubinius, but it also supports MRI 1.8.7 and does nothing in 1.9.2. Requiring a gem is simple, and I don't have to throw code snippets into my project.
Add it to your Gemfile:
gem "rbx-require-relative"
Then require 'require_relative' before you require_relative.
For example, one of my test files looks like this:
require 'rubygems'
require 'bundler/setup'
require 'minitest/autorun'
require 'require_relative'
require_relative '../lib/foo'
This is the cleanest solution out of any of these IMO, and the gem isn't as heavy as backports.
The backports gem now allows individual loading of backports.
You could then simply:
require 'backports/1.9.1/kernel/require_relative'
# => Now require_relative works for all versions of Ruby
This require will not affect newer versions, nor will it update any other builtin methods.
Another option is to tell the interpreter which paths to search
ruby -I /path/to/my/project caller.rb
One issue I've not seen pointed out with the solutions based on __FILE__ is that they break with regards to symlinks. For example say I have:
~/Projects/MyProject/foo.rb
~/Projects/MyProject/lib/someinclude.rb
The main script, the entry point, the application is foo.rb. This file is linked to ~/Scripts/foo which is in my $PATH. This require statement is broken when I execute 'foo':
require File.join(File.dirname(__FILE__), "lib/someinclude")
Because __FILE__ is ~/Scripts/foo so the require statement above looks for ~/Scripts/foo/lib/someinclude.rb which obviously doesn't exist. The solution is simple. If __FILE__ is a symbolic link it needs to be dereferenced. Pathname#realpath will help us with this situation:
require "pathname" require File.join(File.dirname(Pathname.new(__FILE__).realpath), "lib/someinclude")
If you were building a gem, you would not want to pollute the load path.
But, In the case of a standalone application it is very convenient to just add the current directory to the load path as you do in the first 2 examples.
My vote goes to the first option on the list.
I would love to see some solid Ruby best practices literature.
I would define my own relative_require if it doesn't exist (i.e. under 1.8) and then use the same syntax everywhere.
Ruby on Rails way:
config_path = File.expand_path("../config.yml", __FILE__)
'Programming' 카테고리의 다른 글
| iOS 앱 오류-자체를 하위보기로 추가 할 수 없습니다 (0) | 2020.06.08 |
|---|---|
| 타일링 알고리즘지도 (0) | 2020.06.08 |
| Android 앱에 어떤 Eclipse 버전을 사용해야합니까? (0) | 2020.06.08 |
| 힘내 : 저장소에서 파일을 삭제하지 않고 색인에서 파일을 제거하는 방법 (0) | 2020.06.07 |
| 두 저장소 간의 차이점 얻기 (0) | 2020.06.07 |