YAML: Czy potrzebuję cudzysłowów dla ciągów w YAML?

398

Próbuję napisać słownik YAML do internacjonalizacji projektu Rails. Jestem jednak trochę zdezorientowany, ponieważ w niektórych plikach widzę ciągi znaków w cudzysłowach, a niektóre nie. Kilka punktów do rozważenia:

  • przykład 1 - wszystkie ciągi znaków używają podwójnych cudzysłowów;
  • przykład 2 - bez ciągów (oprócz dwóch ostatnich) użyj cudzysłowów;
  • Cookbook YAML mówi: Zamknięcie napisów w cudzysłowach pozwala na użycie escapings do reprezentowania ASCII i Unicode znaki. Czy to oznacza, że ​​muszę używać podwójnych cudzysłowów tylko wtedy, gdy chcę uciec przed niektórymi postaciami? Jeśli tak - dlaczego używają podwójnych cudzysłowów wszędzie w pierwszym przykładzie - tylko ze względu na jedność / powody stylistyczne?
  • dwie ostatnie linie przykładu 2 używają !- niespecyficzny znacznik, podczas gdy dwie ostatnie linie pierwszego przykładu nie - i oba działają.

Moje pytanie brzmi: jakie są zasady korzystania z różnych rodzajów cytatów w YAML?

Czy można powiedzieć, że:

  • ogólnie nie potrzebujesz cytatów;
  • jeśli chcesz uciec od znaków, użyj podwójnych cudzysłowów;
  • użyj !z pojedynczymi cudzysłowami, kiedy ...?!?
Alexander
źródło
1
Drugi link już nie działa, sugeruję postawić swoje przykłady w pytaniu.
heroina

Odpowiedzi:

565

Po krótkiej recenzji książki kucharskiej YAML cytowanej w pytaniu i kilku testach, oto moja interpretacja:

  • Zasadniczo nie potrzebujesz cytatów.
  • Użyj cudzysłowu, aby wymusić ciąg, np. Jeśli klucz lub wartość jest, 10ale chcesz, aby zwracał ciąg, a nie Fixnum, zapis '10'lub "10".
  • Użyj cudzysłowów, jeśli wartość ta zawiera znaki specjalne (np :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, \).
  • Pojedyncze cudzysłowy pozwalają wstawić prawie dowolny znak w ciągu i nie będą próbować analizować kodów specjalnych. '\n'zostanie zwrócony jako ciąg \n.
  • Podwójne cudzysłowy parsuj kody ucieczki. "\n"zostanie zwrócony jako znak przesunięcia wiersza.
  • Wykrzyknik wprowadza metodę, np. !ruby/symAby zwrócić symbol Ruby.

Wydaje mi się, że najlepszym rozwiązaniem byłoby nie używać cudzysłowów, chyba że musisz, a następnie używać pojedynczych cudzysłowów, chyba że chcesz przetwarzać kody specjalne.

Aktualizacja

„Tak” i „Nie” powinny być ujęte w cudzysłowy (pojedyncze lub podwójne), w przeciwnym razie będą interpretowane jako wartości TrueClass i FalseClass:

en:
  yesno:
    'yes': 'Yes'
    'no': 'No'
Mark Berry
źródło
16
To nie do końca pełny obraz. Na przykład, @i `może być użyte w dowolnym miejscu w zwykłym ciągu znaków, z wyjątkiem początkowych, ponieważ są to zastrzeżone wskaźniki .
Adam Spiers
19
Nie próbowałem zapewnić pełnego obrazu, tylko kilka praktycznych zasad. Tak, czasami wygląda na to, że niektóre znaki specjalne (zarezerwowane wskaźniki) mogą być używane bez cudzysłowów (o ile zarezerwowany wskaźnik nie uruchamia zwykłego skalara), ale nie jest źle używać cudzysłowów, gdy widzisz znak specjalny.
Mark Berry
33
Reguły dla ciągów w YAML są niezwykle skomplikowane, ponieważ istnieje wiele różnych rodzajów ciągów. Napisałem tutaj tabelę: stackoverflow.com/questions/3790454/…
Steve Bennett
56
Biorąc pod uwagę wszystkie powyższe zastrzeżenia, wolałbym używać cytatów wszędzie: - /
Vicky Chijwani
6
Oto też całkiem kompletne odniesienie, które napisałem: blogs.perl.org/users/tinita/2018/03/…
tinita
0

Miałem ten problem podczas pracy z aplikacją Rails z Dockerem .

Moim najbardziej preferowanym podejściem jest generalnie nie używanie cudzysłowów. Obejmuje to niestosowanie cudzysłowów dla:

  • zmienne takie jak ${RAILS_ENV}
  • wartości oddzielone dwukropkiem (:) jak postgres-log:/var/log/postgresql
  • inne wartości ciągów

Używam jednak podwójnych cudzysłowów dla integerwartości, które należy przekonwertować na ciągi znaków, takie jak:

  • wersja dokera-komponowania jak version: "3.8"
  • numery portów jak "8080:8080"

Jednak w szczególnych przypadkach podoba booleans, floats, integers, i inne przypadki, w których przy użyciu podwójnych cudzysłowów dla wartości wejściowych może być interpretowany jako strings, proszę nie używać podwójnych cudzysłowów.

Oto przykładowy docker-compose.ymlplik wyjaśniający tę koncepcję:

version: "3"

services:
  traefik:
    image: traefik:v2.2.1
    command:
      - --api.insecure=true # Don't do that in production
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

To wszystko.

mam nadzieję, że to pomoże

Obiecaj Preston
źródło