Spring創始人Rod大叔對YAML的真實想法
如果你在Twitter上關注我,你可能會認為我討厭YAML。
我不反對YAML,只是反對濫用 YAML。我想幫助防止人們濫用YAML並在此過程中無意對自己和同事施加了殘忍。
YAML的優勢在於結構化資料格式。是的,它有問題。空白是一個雷區。它的語法非常複雜。它有這樣的結論:“任何使用YAML的人都會在試圖縮寫Norway時最終被燒燬 。” 但是YAML是人類可讀的並且支援評論:這是推動其受歡迎的兩個主要好處。
它可能出錯的地方是我們使用YAML來描述行為的地方。
考慮CI域中的一些示例。這不是YAML以這種方式被濫用的唯一領域,但它是最嚴重的罪犯之一。
以GitLab的管道定義來實現自己 :1170行:
gitlab:assets:compile: <<: *dedicated-no-docs-pull-cache-job image: dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.5.3-git-2.18-chrome-71.0-node-8.x-yarn-1.12-graphicsmagick-1.3.29-docker-18.06.1 dependencies: - setup-test-env services: - docker:stable-dind variables: NODE_ENV: <font>"production"</font><font> RAILS_ENV: </font><font>"production"</font><font> SETUP_DB: </font><font>"false"</font><font> SKIP_STORAGE_VALIDATION: </font><font>"true"</font><font> WEBPACK_REPORT: </font><font>"true"</font><font> # we override the max_old_space_size to prevent OOM errors NODE_OPTIONS: --max_old_space_size=3584 DOCKER_DRIVER: overlay2 DOCKER_HOST: tcp:</font><font><i>//docker:2375</i></font><font> script: - node --version - yarn install --frozen-lockfile --production --cache-folder .yarn-cache - free -m - bundle exec rake gitlab:assets:compile - time scripts/build_assets_image - scripts/clean-old-cached-assets artifacts: name: webpack-report expire_in: 31d paths: - webpack-report/ - <b>public</b>/assets/ </font>
請注意script包含shell指令碼列表的塊。這看起來像資料嗎?這是指定執行的正確模型嗎?
有許多類似的案例。以下是Tekton示例中 的一個片段,這是一種基於Kubernetes的新型交付解決方案:
apiVersion: tekton.dev/v1alpha1 kind: Task metadata: name: build-push spec: inputs: resources: - name: workspace type: git params: - name: pathToDockerFile description: The path to the dockerfile to build <b>default</b>: /workspace/workspace/Dockerfile - name: pathToContext description: The build context used by Kaniko (https:<font><i>//github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)</i></font><font> <b>default</b>: /workspace/workspace outputs: resources: - name: builtImage type: image steps: - name: build-and-push image: gcr.io/kaniko-project/executor command: - /kaniko/executor args: - --dockerfile=${inputs.params.pathToDockerFile} - --destination=${outputs.resources.builtImage.url} - --context=${inputs.params.pathToContext} </font>
哎喲,變數,合格的名字?引數?這不是結構化資料,這是偽裝成配置的程式設計。
我們之前沒有遇到變數和連續指令等概念嗎?為什麼笨拙地重新發明指令式程式設計?模組化和可測試性如何?那麼可以用程式語言免費獲得的可擴充套件性呢?為什麼要重新發明在現代語言中嚴格定義的異常處理?邏輯運算怎麼樣,更不用說更先進和優雅的FP或OOP概念了?
支援這種基於YAML的語法的最佳理由是它是一個外部DSL,強制執行一個有益的結構。但是,由於以下幾個原因,這樣的理由就不成立:
- 規定性結構在很大程度上是一種幻覺。工作的大部分被壓入等shell指令碼(GitLab例子),在實踐中,它是狂野的西部。
- 如果在DSL的設計中缺少一個步驟,那麼你就會碰壁。例如,CI工具通常將交付階段建模為YAML節。如果你需要一個獨特的階段,你可能會運氣不好。
- 對於外部DSL來說,YAML是一種糟糕的格式,就像XML一樣 。流行的配置格式總是被這種方式誤用。
無論如何,你可能不需要外部DSL:我們在Atomist上學到了很多東西。
外部DSL ......就像小狗一樣 ,它們都開始可愛而快樂,但隨著它們的成長,它們無一例外地變成了惡毒的野獸。
現代程式語言足夠靈活,可以使內部DSL越來越引人注目,具有更好的工具和可擴充套件性。
試圖將資料格式用作程式語言是錯誤的。這樣使用它實際與資料格式的優點無關。
YAML作為資料格式是可以的。YAML不是一種程式語言。如果您正在程式設計,請使用程式語言。你應該歸功於Turing,Hopper,Djikstra以及無數其他電腦科學家和從業者,他們建立了我們的計算機學科。要用到你所學!