DSL Ruby sama sekali bukan DSL, dan saya benar-benar benci menggunakannya karena dokumentasi mereka benar-benar terletak pada bagaimana mereka bekerja. Mari kita ambil ActiveRecord sebagai contoh. Hal ini memungkinkan Anda untuk "menyatakan" asosiasi antara Model:
class Foo < ActiveRecord::Base
has_one :bar
has_one :baz
end
Tetapi deklaratif "DSL" ini (seperti deklaratif classsintaksis Ruby itu sendiri) adalah kebohongan mengerikan yang dapat diungkapkan oleh siapa pun yang memahami bagaimana Ruby "DSL" sebenarnya bekerja:
class Foo < ActiveRecord::Base
[:bar,:baz,:qux,:quux].each do |table|
has_one table if i_feel_like_it?(table)
end
puts "Just for shits and giggles, and to show"
puts "just how fucked up Ruby really is, we're gonna ask you"
puts "which SQL table you want the Foo model to have an"
puts "association with.\n"
puts "Type the name of a table here: "
has_one gets.chomp.to_sym
end
(Coba lakukan sesuatu yang dekat dengan itu dalam tubuh defclassbentuk Lisp !)
Segera setelah Anda memiliki kode seperti di atas dalam basis kode Anda, setiap pengembang pada proyek harus sepenuhnya memahami bagaimana Ruby DSL sebenarnya bekerja (bukan hanya ilusi yang mereka buat) sebelum mereka dapat mempertahankan kode. Dokumentasi yang tersedia akan sama sekali tidak berguna, karena mereka hanya mendokumentasikan penggunaan idiomatik , yang mempertahankan ilusi deklaratif.
RSpec bahkan lebih buruk daripada yang di atas, karena memiliki kasus tepi yang aneh yang membutuhkan rekayasa balik yang ekstensif untuk debug. (Saya menghabiskan sepanjang hari mencoba mencari tahu mengapa salah satu kasus pengujian saya dilewati. Ternyata RSpec mengeksekusi semua kasus pengujian yang memiliki konteks setelah kasus pengujian tanpa konteks, terlepas dari urutan kemunculannya di sumber. , karena contextmetode ini menempatkan blok Anda dalam struktur data yang berbeda dari biasanya.)
Lisp DSL diimplementasikan oleh makro, yang merupakan kompiler kecil. DSL yang dapat Anda buat dengan cara ini bukan hanya penyalahgunaan sintaksis Lisp yang ada. Mereka adalah mini-bahasa aktual yang dapat ditulis agar benar-benar mulus, karena mereka dapat memiliki tata bahasa mereka sendiri. Sebagai contoh, LOOPmakro Lisp jauh lebih kuat daripada eachmetode Ruby .
(Saya tahu Anda sudah menerima jawaban, tetapi tidak semua orang yang membaca ini ingin membaca keseluruhan On Lisp .)