IT TIP

Rails는 YAML을 기호로 해시 및 참조에로드합니다.

itqueen 2020. 11. 22. 21:00
반응형

Rails는 YAML을 기호로 해시 및 참조에로드합니다.


Rails 3.0.9에서 다음과 같이 YAML 파일을로드합니다.

APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))

계층 적 해시와 같은 모든 콘텐츠를로드합니다. 문제 없습니다. 내가 싫어하는 부분은 해시가 작은 따옴표 나 큰 따옴표로만 액세스 할 수 있지만 기호는 사용할 수 없다는 사실입니다.

APP_CONFIG['mailer']['username']  # works fine
APP_CONFIG[:mailer][:username]    # doesn't

이견있는 사람?


HashWithIndifferentAccess를 다음 과 같이 사용해보십시오.

APP_CONFIG = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../app.yml', __FILE__))))

대체 솔루션은 콜론이 추가 된 기호로 액세스하려는 키를 갖는 것입니다. 예를 들면 :

default: &default
  :symbol: "Accessed via a symbol only"
  string: "Accessed via a string only"

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default

나중에 다음과 같이 액세스 할 수 있습니다.

APP_CONFIG[:symbol]
APP_CONFIG['string']

나는 YAML::ENGINE.yamler = "syck". 이것이 psych. (Psych는 내가 예제에서 보여준 것처럼 키 병합을 확실히 지원하지 않습니다.)

사용 정보 HashWithIndifferentAccess: 사용하면 중복 키를 만드는 부작용이 있습니다. 하나는 기호 액세스 용이고 다른 하나는 문자열 액세스 용입니다. YAML 데이터를 배열로 전달하는 경우 이는 사악 할 수 있습니다. 해당 솔루션을 사용하는 경우 이것을 알고 있어야합니다.


Ruby on Rails에서 작업 하는 경우 OP가 요청한 작업을 정확히 수행 하는 symbolize_keys ()를 살펴볼 수 있습니다 . 해시가 깊으면 deep_symbolize_keys(). 이 접근 방식을 사용하면 대답은

APP_CONFIG = YAML.load(File.read(File.expand_path('../app.yml', __FILE__))).deep_symbolize_keys

이것은 선택한 답변과 동일하지만 더 나은 구문을 사용합니다.

YAML.load(File.read(file_path)).with_indifferent_access 

주변을 파헤 치면서 발견 한 또 다른 잠재적 인 대답이 있습니다.

대신 YAML 파일의 맨 위에 다음을 추가하여 HashWithIndifferentAccess.new를 잊을 수 있습니다.

--- !map:HashWithIndifferentAccess

그런 다음 평상시처럼 단순히 YAML.load. 유일한 트릭은 이니셜 라이저 등에서 사용하기 위해 환경에서이 작업을 수행하는 경우 레일이 이미로드되어 있어야한다는 것입니다 (예 : 나처럼).


  1. Rails에는 키를 상징하는 특별한 방법이 있습니다.
  2. load_file 메소드를 사용하고 File.read를 제거 할 수 있습니다.
  3. expand_path도 필요한지 확실하지 않은 경우 기본 디렉토리는 rails root입니다.

그렇게 간단하게 작성하겠습니다.

YAML::load_file('app.yml').symbolize_keys


Rails의 params 해시에 익숙 할 것입니다. 이것은 실제로 표준 루비 Hash 객체가 아닌 HashWithIndifferentAccess입니다. 이를 통해 'action'과 같은 문자열이나 : action과 같은 기호를 사용하여 내용에 액세스 할 수 있습니다.

HashWithIndifferentAccess를 사용하면 무엇을 사용하든 동일한 결과를 얻을 수 있지만 이것은 HashWithIndifferentAccess 개체에서만 작동한다는 점을 명심하십시오.

따라서 YAML에서이 작업을 수행하려면 다음과 같이 YAML.load의 결과를 HashWithIndifferentAccess에로드해야합니다.

APP_CONFIG = HashWithIndifferentAccess.new(   YAML.load(File.read(File.expand_path('../app.yml', __FILE__)))   )

순수 Ruby (예 : Rails 없음)를 사용하는 경우 중간에 JSON 형식으로 변경할 수 있습니다. JSON lib의 parse메서드는 키를 상징 할 수 있습니다.

http://ruby-doc.org/stdlib-2.0.0/libdoc/json/rdoc/JSON.html#method-i-parse

제가 의미하는 바는 다음과 같습니다.

JSON.parse(JSON.dump(YAML.load_file(File.expand_path('../app.yml', __FILE__))), symbolize_names: true)

참고 : 이것은 json과의 변환 오버 헤드를 추가합니다.


나는 일반적으로 HashWithIndifferentAccess혼란을 피하고 액세스하는 방식의 불일치를 방지하기 위해 사용하지 않으므로 대신 .deep_symbolize_keys기호 키 형식으로 모든 것을 가져 오기 위해 a 를 사용합니다.

참고 URL : https://stackoverflow.com/questions/7072986/rails-load-yaml-to-hash-and-reference-by-symbol

반응형