Jadi, saya tahu saya bisa melakukan sesuatu seperti ini:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
Dan memiliki sitelist
dan anotherlist
keduanya mengandung www.foo.com
dan www.bar.com
. Namun, apa yang saya inginkan adalah untuk anotherlist
untuk juga mengandung www.baz.com
, tanpa harus mengulang www.foo.com
dan www.baz.com
.
Melakukan ini memberi saya kesalahan sintaks di parser YAML:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
- www.baz.com
Hanya dengan menggunakan jangkar dan alias, sepertinya tidak mungkin melakukan apa yang saya inginkan tanpa menambahkan level substruktur lain, seperti:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
Artinya, pengguna file YAML ini harus menyadarinya.
Apakah ada cara YAML murni untuk melakukan sesuatu seperti ini? Atau apakah saya harus menggunakan beberapa pemrosesan pasca-YAML, seperti menerapkan substitusi variabel atau pengangkatan otomatis jenis substruktur tertentu? Saya sudah melakukan pasca-pemrosesan semacam itu untuk menangani beberapa kasus penggunaan lainnya, jadi saya tidak sepenuhnya menolaknya. Tetapi file YAML saya akan ditulis oleh manusia, bukan yang dibuat oleh mesin, jadi saya ingin meminimalkan jumlah aturan yang perlu dihafal oleh pengguna saya di atas sintaks YAML standar.
Saya juga ingin dapat melakukan hal serupa dengan peta:
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
Saya telah mencari melalui spesifikasi YAML , dan tidak dapat menemukan apa pun, jadi saya curiga jawabannya adalah "tidak, Anda tidak dapat melakukan ini". Tapi jika ada yang punya ide, itu bagus.
EDIT: Karena tidak ada jawaban, saya berasumsi bahwa tidak ada yang melihat apa pun yang belum saya lihat di spesifikasi YAML dan ini tidak dapat dilakukan di lapisan YAML. Jadi saya membuka pertanyaan untuk ide pasca-pemrosesan YAML untuk membantu hal ini, jika ada yang menemukan pertanyaan ini di masa mendatang.
Jawaban:
Jenis kunci gabungan mungkin yang Anda inginkan. Ini menggunakan
<<
kunci pemetaan khusus untuk menunjukkan penggabungan, memungkinkan alias ke pemetaan (atau urutan alias tersebut) untuk digunakan sebagai penginisialisasi untuk bergabung menjadi satu pemetaan. Selain itu, Anda masih dapat mengganti nilai secara eksplisit, atau menambahkan lebih banyak nilai yang tidak ada di daftar gabungan.Penting untuk dicatat bahwa ini berfungsi dengan pemetaan, bukan urutan sebagai contoh pertama Anda. Ini masuk akal ketika Anda memikirkannya, dan contoh Anda sepertinya tidak perlu berurutan. Cukup mengubah nilai urutan Anda ke kunci pemetaan sudah cukup, seperti pada contoh berikut (belum teruji):
sitelist: &sites ? www.foo.com # "www.foo.com" is the key, the value is null ? www.bar.com anotherlist: << : *sites # merge *sites into this mapping ? www.baz.com # add extra stuff
Beberapa hal yang perlu diperhatikan. Pertama, karena
<<
merupakan kunci, itu hanya dapat ditentukan sekali per node. Kedua, saat menggunakan urutan sebagai nilainya, urutannya signifikan. Ini tidak masalah dalam contoh di sini, karena tidak ada nilai yang terkait, tetapi perlu diperhatikan.sumber
yaml.load(...)
menggunakan Python, saya mendapatkan kamus sebagai representasi dari pemetaan YAML. Ya, mudah untuk memposting prosesnya menjadi satu set, tetapi saya harus tahu bahwa itu terjadi (dan kerumitan semantik saat membaca / menulis file konfigurasi jauh lebih tinggi jika aturannya adalah "set ditulis sebagai peta dengan nilai null" ). Mengingat bahwa saya memerlukan pemrosesan pasca antarayaml.load(...)
dan menggunakan data yang dihasilkan apakah saya menggunakan<<
atauMERGE
, saya mungkin akan tetap menggunakannyaMERGE
(yang telah saya terapkan sekarang).!!set
berhasil. Terlalu banyak boilerplate yang tidak jelas. File-file ini dibuat agar dapat dibaca / ditulisi manusia, oleh orang-orang yang belum tentu ahli YAML. Orang-orang akan menuliskan daftar situs mereka sebagai daftar YAML, kemudian ingin menggabungkannya dan harus mengubah semuanya menjadi satu set DAN ingat untuk secara eksplisit menandainya sebagai satu set ... Saya punya beberapa pos standar lainnya- memproses hal-hal bersamaMERGE
. Terima kasih atas bantuan Anda!Seperti yang ditunjukkan oleh jawaban sebelumnya, tidak ada dukungan bawaan untuk memperluas daftar di YAML. Saya menawarkan cara lain untuk menerapkannya sendiri. Pertimbangkan ini:
defaults: &defaults sites: - www.foo.com - www.bar.com setup1: <<: *defaults sites+: - www.baz.com
Ini akan diolah menjadi:
defaults: sites: - www.foo.com - www.bar.com setup1: sites: - www.foo.com - www.bar.com - www.baz.com
Idenya adalah untuk menggabungkan konten kunci yang diakhiri dengan '+' ke kunci yang sesuai tanpa '+'. Saya menerapkan ini dengan Python dan menerbitkannya di sini .
Nikmati!
sumber
sites
dansites+
. Maksud saya alat yang harus diterapkan oleh pengguna karena ini bukanyaml
perilaku default ?(Menjawab pertanyaan saya sendiri jika solusi yang saya gunakan berguna bagi siapa saja yang mencari ini di masa mendatang)
Tanpa cara murni-YAML untuk melakukan ini, saya akan menerapkan ini sebagai "transformasi sintaks" yang berada di antara pengurai YAML dan kode yang benar-benar menggunakan file konfigurasi. Jadi aplikasi inti saya tidak perlu khawatir sama sekali tentang tindakan penghindaran redundansi yang ramah manusia, dan hanya dapat bertindak langsung pada struktur yang dihasilkan.
Struktur yang akan saya gunakan terlihat seperti ini:
foo: MERGE: - - a - b - c - - 1 - 2 - 3
Yang akan diubah menjadi setara dengan:
foo: - a - b - c - 1 - 2 - 3
Atau, dengan peta:
foo: MERGE: - fork: a spoon: b knife: c - cup: 1 mug: 2 glass: 3
Akan diubah menjadi:
foo: fork: a spoon: b knife: c cup: 1 mug: 2 glass: 3
Secara lebih formal, setelah memanggil pengurai YAML untuk mendapatkan objek asli dari file konfigurasi, tetapi sebelum meneruskan objek ke aplikasi lainnya, aplikasi saya akan menjalankan grafik objek mencari pemetaan yang berisi kunci tunggal
MERGE
. Nilai yang terkait denganMERGE
harus berupa daftar daftar, atau daftar peta; substruktur lainnya adalah kesalahan.Dalam kasus daftar daftar, seluruh peta yang berisi
MERGE
akan diganti dengan daftar turunan yang digabungkan bersama dalam urutan kemunculannya.Dalam kasus daftar peta, seluruh peta yang berisi
MERGE
akan diganti dengan satu peta yang berisi semua pasangan kunci / nilai di peta anak. Jika ada tumpang tindih dalam kunci, nilai dari peta anak yang terjadi terakhir dalamMERGE
daftar akan digunakan.Contoh-contoh yang diberikan di atas tidak begitu berguna, karena Anda bisa saja menulis struktur yang Anda inginkan secara langsung. Ini lebih mungkin muncul sebagai:
foo: MERGE: - *salt - *pepper
Memungkinkan Anda membuat daftar atau peta yang berisi semua yang ada di node
salt
danpepper
digunakan di tempat lain.(Saya terus memberikan
foo:
peta luar itu untuk menunjukkan bahwaMERGE
harus menjadi satu - satunya kunci dalam pemetaannya, yang berarti ituMERGE
tidak dapat muncul sebagai nama tingkat atas kecuali tidak ada nama tingkat atas lainnya)sumber
Untuk memperjelas sesuatu dari dua jawaban di sini, ini tidak didukung secara langsung di YAML untuk daftar (tetapi didukung untuk kamus, lihat jawaban kittemon).
sumber
Untuk mendukung jawaban Kittemon, perhatikan bahwa Anda dapat membuat pemetaan dengan nilai null menggunakan sintaks alternatif.
foo: << : myanchor bar: baz:
alih-alih sintaks yang disarankan
foo: << : myanchor ? bar ? baz
Seperti saran Kittemon, ini akan memungkinkan Anda untuk menggunakan referensi ke jangkar di dalam pemetaan dan menghindari masalah urutan. Saya mendapati diri saya perlu melakukan ini setelah menemukan bahwa komponen Symfony Yaml v2.4.4 tidak mengubah
? bar
sintaks.sumber
myanchor
terlihat seperti apa