[ruby-on-rails] 변수와 함께 YAML 사용

YAML 파일 내의 변수가 가능합니까? 예를 들면 :

theme:
  name: default
  css_path: compiled/themes/$theme.name
  layout_path: themes/$theme.name

이 예 theme: name: default에서 다른 설정에서 어떻게 사용할 수 있습니까? 구문은 무엇입니까?



답변

저도 같은 질문을했는데, 많은 조사 끝에 불가능한 것 같습니다 .

cgat의 대답은 올바른 방향이지만 실제로 이와 같은 참조를 연결할 수는 없습니다.

다음은 YAML에서 “변수”로 수행 할 수있는 작업입니다 (이를 설정하면 공식적으로 “노드 앵커”라고하고 나중에 사용할 때는 “참조”라고 함).

값을 정의하고 나중에 정확한 사본을 사용하십시오.

default: &default_title This Post Has No Title
title: *default_title

{또는}

example_post: &example
  title: My mom likes roosters
  body: Seriously, she does. And I don't know when it started.
  date: 8/18/2012
first_post: *example
second_post:
  title: whatever, etc.

자세한 내용은 YAML에 대한 위키 페이지의이 섹션을 참조하십시오. http://en.wikipedia.org/wiki/YAML#References

객체를 정의하고 나중에 수정하여 사용합니다.

default: &DEFAULT
  URL:          stooges.com
  throw_pies?:  true
  stooges:  &stooge_list
    larry:  first_stooge
    moe:    second_stooge
    curly:  third_stooge

development:
  <<: *DEFAULT
  URL:      stooges.local
  stooges:
    shemp: fourth_stooge

test:
  <<: *DEFAULT
  URL:    test.stooges.qa
  stooges:
    <<: *stooge_list
    shemp: fourth_stooge

https://gist.github.com/bowsersenior/979804 의 훌륭한 데모에서 직접 가져 왔습니다.


답변

몇 가지 검색 후 %연산자를 사용하는 더 깨끗한 솔루션을 찾았습니다 .

YAML 파일에서 :

key : 'This is the foobar var : %{foobar}'

루비 코드에서 :

require 'yaml'

file = YAML.load_file('your_file.yml')

foobar = 'Hello World !'
content = file['key']
modified_content = content % { :foobar => foobar }

puts modified_content

출력은 다음과 같습니다.

This is the foobar var : Hello World !

@jschorr이 주석에서 말했듯이 Yaml 파일의 값에 여러 변수를 추가 할 수도 있습니다.

Yaml :

key : 'The foo var is %{foo} and the bar var is %{bar} !'

루비 :

# ...
foo = 'FOO'
bar = 'BAR'
# ...
modified_content = content % { :foo => foo, :bar => bar }

출력 :

The foo var is FOO and the bar var is BAR !


답변

이것은 오래된 게시물이지만 비슷한 필요가 있었고 이것이 내가 생각해 낸 해결책입니다. 약간의 해킹이지만 작동하고 다듬을 수 있습니다.

require 'erb'
require 'yaml'

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data['theme']['name'] %>
  layout_path: themes/<%= data['theme']['name'] %>
  image_path: <%= data['theme']['css_path'] %>/images
  recursive_path: <%= data['theme']['image_path'] %>/plus/one/more
EOF

data = YAML::load("---" + doc)

template = ERB.new(data.to_yaml);
str = template.result(binding)
while /<%=.*%>/.match(str) != nil
  str = ERB.new(str).result(binding)
end

puts str

큰 단점은 존재하거나 존재하지 않을 수있는 변수 이름 (이 경우 “데이터”)을 yaml 문서에 빌드한다는 것입니다. 아마도 더 나은 해결책은 $를 사용한 다음 ERB 이전에 Ruby의 변수 이름으로 대체하는 것입니다. 또한 눈에 훨씬 더 쉬운 data.theme.name 유형 표기법을 허용 하는 hashes2ostruct 를 사용하여 테스트했습니다 . 필요한 것은 YAML :: load를 다음과 같이 감싸는 것입니다.

data = hashes2ostruct(YAML::load("---" + doc))

그러면 YAML 문서가 다음과 같이 보일 수 있습니다.

doc = <<-EOF
  theme:
  name: default
  css_path: compiled/themes/<%= data.theme.name %>
  layout_path: themes/<%= data.theme.name %>
  image_path: <%= data.theme.css_path %>/images
  recursive_path: <%= data.theme.image_path %>/plus/one/more
EOF


답변

Rails / ruby ​​프레임 워크는 템플릿 화를 할 수 있습니다 … 환경 변수를로드하는 데 자주 사용됩니다 …

# fooz.yml
  foo:
    bar: <%= $ENV[:some_var] %>

YML 형식이 json의 상위 집합이라고 생각하므로 이것이 자바 스크립트 프레임 워크에서 작동하는지 알 수 없으며 yml 파일을 읽는 것에 따라 다릅니다.

당신은 등 템플릿 사용할 수있는 경우 << >>또는 {{ }}당신이 그 직후에 당신의 독자에 따라 스타일을 …

다른 yml 파일에서 …

# boo.yml

development:
  fooz: foo

기본적으로 동적으로 설정 될 때마다 원본 파일을 참조로 변수를 삽입 할 수 있습니다. 읽을 때 나는 또한 여러 언어에 대한 객체로 YML 파일을 즉시 생성하거나 열 수 있다는 것을 보았습니다. 파일을 만들고 일련의 YML 파일을 작성하거나 동적으로 생성 된 파일을 모두 정적으로 가리 키도록 할 수 있습니다.


답변

요구 사항이 여러 변수를 대체하는 구문 분석과 같은 경우 해시 / 또는 다른 것으로 사용하면 다음과 같이 할 수 있습니다

require 'yaml'
require 'json'
yaml = YAML.load_file("xxxx.yaml")
blueprint = yaml.to_json % { var_a: "xxxx", var_b: "xxxx"}
hash = JSON.parse(blueprint)

yaml 안에 다음과 같은 변수를 넣으십시오.

"%{var_a}"


답변