Yang paling mengejutkan bagi orang yang keranjingan ketika ia baru mulai mempelajari Elixir dengan Phoenix.
Catatan
Saya orang yang sederhana dan saya tidak akan terlalu dalam. Oleh karena itu, akan ada perbedaan dalam tingkat kerja-tani, tetapi tidak ada yang akan dikatakan tentang perbedaan dalam tingkat peluncuran aplikasi, tentang prinsip-prinsip operasi mesin virtual Erlang dan protokol OTP.
Kesan utama
Elixir / Phoenix sangat mirip dengan Rails dan pada saat yang sama sama sekali tidak menyukainya. Seperti beberapa frasa bahasa Inggris: secara individual, kata-katanya akrab, tetapi bersama-sama itu tidak jelas.
Erlang vs Ruby
Berpikir dalam rubel dan mencoba menulis di ramuan itu sulit. Secara teratur Anda menemui jalan buntu, karena apa yang Anda inginkan dilakukan benar-benar berbeda dari apa yang Anda lakukan sebelumnya ... atau, pada kenyataannya, Anda tidak menginginkannya sama sekali.
Adapun sisanya, orang menulis buku tentang perbedaan Erlang dan Ruby, jadi saya akan singkat. Bagi saya, penyergapan utama adalah dengan penggantian โlokomotif uapโ rel dengan pipa, dengan reorientasi pemikiran ke fungsionalisme (manfaatnya adalah pengalaman lama inject
dan kecintaan yang sama terhadap inject
/ foldr
) dan, secara subyektif, persyaratan yang lebih ketat untuk tipe data (meskipun, secara resmi, , kedua bahasa dengan pengetikan dinamis yang ketat).
Pencocokan pola tidak menimbulkan kejutan, dan saya masih tidak mengerti mengapa ada begitu banyak pembicaraan tentang dia. Hanya alat yang menarik.
Ruang lingkup umum
Dalam Elixir, semuanya terletak pada modul. Tidak ada ruang lingkup global. Panggilan C #.
Dengan kata lain: relnya rata dan di beberapa tempat mengganggu pembuatan hierarki (saya ingat pernah ada bug dengan pengontrol yang terbaring di modul). Elixir - sebaliknya, semuanya ada dalam modul. Di rel, Anda bisa menebak tujuan objek oleh kelas induk, dan di elixir, dengan nama lengkap kelas / modul.
Compilability
Di satu sisi, inilah yang terkadang tidak saya miliki di pagar. Karena Anda dapat menemukan setengah kesalahan yang baik saat dikompilasi, dan tidak di runtime saat produksi. Kompilasi, di sisi lain, membutuhkan waktu. Tetapi di pihak ketiga, itu perlu sedikit, dan saya belum melihat proyek besar pada elixir (dan bukan dengan aturan erlang untuk menulis monolith besar). Terlebih lagi, para elixir melakukan pekerjaan yang hebat untuk secara dinamis memuat kembali kode dan halaman. Dan sejauh ini, kecepatan kerja, ditambah dengan kurangnya zeus / musim semi yang tak bertuhan, menghangatkan jiwa saya.
Tentu saja, ini juga menimbulkan kontra, tetapi mereka keluar kemudian. Di suatu tempat di bidang lingkungan produksi dan penyebaran. Lebih lanjut tentang ini di bawah ini.
Berikut ini adalah hal menarik yang secara fisik tidak dapat terjadi pada rel: migrasi dan hal-hal lain yang dalam rel melalui rake
in elixir memerlukan kompilasi proyek dan hal seperti ini dapat terjadi: lupa menulis rute, jalur helper dalam pandangan merujuk kepada mereka, tetapi migrasi jatuh. Pada awalnya - sangat tidak biasa.
Dokumentasi
Situs dengan dokumentasi elixir terlihat jauh lebih kuat daripada rubidock dan apidok. Tapi di sini ada jumlah dokumentasi dan contoh - di sinilah letak ruby โโ/ rail jauh di depan. Elixir tidak memiliki contoh untuk semuanya yang sedikit lebih rumit daripada feses. Dan deskripsi beberapa metode, pada kenyataannya, tidak melampaui tanda tangan. Itu sulit bagi saya, karena saya terbiasa dengan banyak contoh dan deskripsi, dengan beberapa metode elixir. Kadang-kadang saya harus melihat-lihat dan bereksperimen dalam waktu yang lama untuk memahami cara menggunakan metode ini atau itu, karena saya tidak begitu mengerti bahasa sehingga saya bisa membaca kode sumber paket dengan bebas.
Independensi lokasi file dari isinya
Seperti yang mereka katakan "dengan kekuatan besar datang tanggung jawab besar". Di satu sisi, Anda dapat membuat bacchanalia dan menguraikan benda-benda sehingga musuh pasti tidak akan lewat. Dan di sisi lain, Anda dapat memberi nama path dengan lebih logis dan jelas, menambahkan level logis dari direktori yang tidak ada dalam hirarki kelas. Secara khusus, kita dapat mengingat trailblazer dan sejenisnya dengan ide menggabungkan segala sesuatu yang berkaitan dengan aksi di satu tempat. Dalam elixir, ini bisa dilakukan tanpa pustaka pihak ketiga dan banyak kelas hanya dengan memindahkan file yang ada dengan benar.
Jalur permintaan transparan
Jika dalam Rails pertanyaan tentang rack adalah atribut yang sangat diperlukan dari setiap wawancara, karena rail adalah puncak gunung es dan dari waktu ke waktu Anda ingin membuat middleware Anda. Bahwa dalam ramuan keinginan seperti itu tidak muncul sama sekali (walaupun mungkin aku masih muda dan semuanya di depan). Ada serangkaian saluran pipa yang secara eksplisit dilewati permintaan. Dan di sana Anda dapat dengan jelas melihat di mana sesi diambil, di mana flash-messge diproses, di mana csrf divalidasi dan semua ini dapat dikontrol sesuka Anda di satu tempat. Di rel, seluruh pertanian ini sebagian dipaku, dan sebagian tersebar di berbagai tempat.
Rute dalam ke luar
Dalam Rails, situasi di mana satu tindakan dapat merespons dalam beberapa format adalah norma. Bahkan di sana (.:format)
diletakkan tepat di rute. Dalam elixir, karena properti yang disebutkan di atas dengan pipa, pemikiran format analog tidak muncul sama sekali. Format yang berbeda menggunakan saluran pipa yang berbeda dan memiliki url yang berbeda. Bagi saya itu sangat sehat.
Sirkuit dalam model
Ini umumnya dongeng. Saat Anda menggambarkan bidang model, itu akan menjadi begitu. Tidak ada jenis pemeran tersirat. Plus, tidak ada kruk untuk membatasi akses ke bidang, yang ada di database, tetapi karena alasan tertentu tidak dapat digunakan dalam aplikasi web.
Validasi dan Callback
Tidak ada panggilan balik di elixir. Di sana semuanya lebih mudah. Dan saya pikir saya menyukainya.
Alih-alih rails-way dalam elixir changeset , yang menggabungkan strong_parameters, validasi, dan beberapa callback. Dan sisa panggilan balik melalui Multi , yang memungkinkan untuk mengumpulkan banyak operasi, melakukan transaksi dan memproses hasilnya.
Singkatnya, semuanya hanya berbeda. Awalnya ini tidak biasa. Kemudian di tempat-tempat itu membuat saya marah, karena Anda tidak bisa menahan panggilan balik lain untuk semuanya dan tidak memikirkan kasus bisnis yang berbeda. Dan kemudian Anda mulai memperhatikan "pesona yang tidak bisa dijelaskan" , karena Anda harus melakukannya dengan benar, dan tidak seperti dulu.
Bekerja dengan DB
Alih-alih ActiveRecord, beberapa Ecto.Repo , Ecto.Query, dan beberapa saudara mereka muncul. Untuk mengatakan semua perbedaan adalah artikel terpisah. Karena itu, saya akan mengatakan sensasi subyektif utama.
Dalam debug lebih nyaman daripada AR. Karena ada ruang lingkup umum, konstanta dari jalur beban dimuat ketika mengaksesnya dan Anda cukup membuka rails c
, tulis User.where(email: 'Kane@nod.tb').order(:id).first
dan dapatkan hasilnya.
Di Elixir, konsol tidak cukup. Sejumlah tindakan perlu dilakukan:
- mengimpor metode untuk membangun kueri sql:
import Ecto.Query, only: [from: 2]
; - tambahkan kelas untuk menghindari mengeja nama lengkap mereka:
alias MyLongApplicationName.User
- untuk menulis User
alih-alih MyLongApplicationName.User
;alias MyLongApplicationName.Repo
- sama untuk mengakses kelas yang dapat mengeksekusi sql dan mengembalikan hasil;
- dan hanya sekarang Anda dapat menulis
from(u in User, where: u.email == "Kane@nod.tb") |> Repo.one
Di sisi lain, dalam kode aplikasi, "formalitas" ini memberikan kode yang lebih mudah dibaca, ditambah ada perasaan bahwa Anda mengendalikan apa yang terjadi, dan bukan menjalani kehidupannya sendiri. Artinya, Anda memilih metode, model, dan objek apa yang perlu Anda kerjakan, Anda memuatnya secara eksplisit dan menggunakannya.
Nama aplikasi
Dalam gambar dan rupa Rails, saya berasumsi bahwa nama aplikasi digunakan dalam sepasang konfigurasi dan hanya itu. Karena itu, saya tidak memperhatikan panjang nama. Namun sia-sia. Di Elixir, modul dengan nama aplikasi adalah level teratas dalam hierarki modul aplikasi web dan akan muncul di mana-mana.
Saya menelepon kotak pasir Comindivion saya. Dan sekarang saya sedikit menderita, karena ini nama yang agak panjang dan Anda harus menulisnya terus-menerus. Baik di file kelas dan di konsol saat memanggil apa pun. Ngomong-ngomong, ya, siapa yang peduli, ini kotak pasir di GitHub .
N +1
Di Rails, kami memilikinya di luar kotak, tetapi di Elixir di luar kotak tidak ada masalah seperti itu. Di sana, pada tahap perakitan permintaan, Anda dapat menentukan hubungan mana yang diperlukan dan mereka akan dimuat selama pelaksanaan permintaan ini. Tidak diunggah? Anda tidak akan memiliki akses ke hubungan ini. Semuanya sederhana dan indah.
Permintaan pemrosesan dan respons
Singkatnya: di phoenix, semuanya lebih jelas daripada di pagar.
Di mana-mana samb
Karena negara tidak disimpan dalam tumpukan objek yang berbeda, maka harus diseret dalam satu objek. Mengingatkan request
dari ActionController
, hanya lebih komprehensif. Dia disebut connection
Phoenix. Ini berisi segalanya: request
, flash
, session
dan segalanya. Dia muncul dalam panggilan semua yang berhubungan dengan pemrosesan permintaan yang tiba.
Di sini dan kontra, karena yang pertama sangat malas untuk memahat di mana-mana conn
dan tidak sepenuhnya mengerti mengapa. Rel dalam hal ini korup. Anda menulis render atau flash dan tidak ada pikiran bahwa tindakan ini berkaitan. Dan di Phoenix conn
selalu mengingatkan Anda untuk bekerja dengan koneksi atau soket tertentu, dan bukan hanya metode yang dipanggil dan keajaiban terjadi di dalam.
Sebagian & templat
Di Phoenix, tidak ada pemisahan antara parsial dan templat. Akhirnya seluruh fungsinya. Ada satu lagi pesona di sini: rel, bahkan di lingkungan prod, terus-menerus merangkak di balik tampilan pada disk dan menghasilkan IO plus overhead untuk mengubahnya dari erb / haml / etc ke html. Dan di Elixir semuanya adalah fungsi, termasuk pandangan. Kompilasi tampilan sekali dan semua: dapatkan argumen, keluarkan html, tidak masuk ke disk.
Tampilan
Dalam Rails, view dipahami sebagai sebagian dan templat, sedangkan di Phoenix mereka terletak pada templat, dan dalam view, secara kasar, ada berbagai cara penyajian data. Secara khusus, ada ganti render.
Artinya, secara default, controller tidak membuat apa pun. Semuanya disebut secara eksplisit. Dan jika Anda tidak memiliki sebagian dan Anda tidak benar-benar membutuhkannya (misalnya, dalam kasus json, ketika mudah dibangun oleh kelas layanan), Anda mendefinisikan ulang render dengan cara seperti ini:
def render("show.json", %{groups: groups}) do %{ groups: groups } end
Dan sebagian tidak lagi dibutuhkan.
Heplers
Tidak ada di Phoenix. Dan ini luar biasa! Karena di rel kereta, biasanya, semua sampah dikumpulkan, yang entah malas didorong di sudut-sudut, atau hanya perlu mengisi sesuatu dengan cepat.
Namun, metode dalam pengontrol, tampilan, dll. Anda bisa menambahkan. Ini dilakukan di tempat khusus web/web.ex
dan terlihat lumayan.
Statika
Dalam perkembangannya, semuanya seperti biasa, kecuali bahwa di phoenix mereka masih mengacaukan isi ulang live, yang pertama memanggil "Wow!" efek. Ini adalah ketika saya mengubah css, kembali ke browser, dan di sana perubahan itu sendiri sudah dimuat.
Dalam produksi di Phoenix, perilaku statika sedikit berbeda dari rel. Secara default, tempat-tempat di mana Anda dapat menyeret statika terdaftar secara eksplisit dan Anda tidak bisa hanya menambahkan file ke aset untuk mendistribusikannya. Masih ada pemetaan aset default, sehingga Anda tidak berkeliaran di sekitar FS sekali lagi, tetapi segera mengambil file yang diinginkan dan memberikannya.
Aset
Keluar dari kotak di Phoenix - makan siang . Anda bisa menggantinya dengan webpack . Tetapi ada lelucon yang cukup jujur โโtentang fakta bahwa banyak proyek yang bengkok pada tahap pengaturan webpack.
Singkatnya, js dan css lebih atau kurang terkumpul, tetapi dengan sisa statis di brunch tidak terlalu. Salin dengan tangan Anda langsung ke proyek dari node_modules (saya tidak suka opsi ini sama sekali), atau menulis kait di bash. Contohnya seperti itu .
Bekerja dengan SSL
Out of the box di Phoenix adalah server http kecil yang disebut koboi . Tampak seperti cougar ruby. Mereka bahkan memiliki jumlah bintang yang sama di GitHub. Tetapi entah bagaimana saya tidak mendapatkan pengaturan SSL di salah satu di atas. Terutama dengan Let's Encrypt , file konfigurasi server web tambahan dan perpanjangan sertifikat reguler. Jadi sebagai server http - ok, tapi untuk ssl saya mengambil proxy ke localhost melalui apache / nginx.
Sebarkan
Secara umum berbeda dibandingkan dengan rel. Di Rails, dalam versi minimum, ia mengendarai lobak ke server, menari dengan rebana untuk bundel, konfigurasi, aset, dan meluncurkan aplikasi. Dan elixir menyusun dan menggali trem untuk meyakinkan lobak tidak akan naik. Perlu mengumpulkan paket. Dan di sini dimulai:
- Anda akan mengetahui mengapa aplikasi diperlukan di
mix.exs
, karena tanpa menunjukkannya dengan benar di mix.exs
, kesalahan yang luar biasa; - Anda belajar bahwa variabel lingkungan dikompilasi pada saat paket itu dibuat, dan bukan pada saat diluncurkan, dan ini untuk pertama kalinya kejutan yang mengejutkan; maka Anda belajar tentang relx bersama dengan
RELX_REPLACE_OS_VARS=true
dan membiarkannya sedikit; - Anda terkejut bahwa dalam paket yang dikompilasi untuk produksi tidak ada yang mirip dengan menyapu, khususnya tidak ada migrasi dan Anda perlu entah bagaimana menjalankannya secara terpisah, misalnya, dari lingkungan dev melalui port forwarding ke database (atau melalui eDeliver , yang akan melakukan hal yang sama) .
Dan kemudian, saat Anda berurusan dengan hal di atas, pro memulai:
- Anda dapat membuat paket swasembada dan tidak menaruh apa pun dari ketergantungan pada kendaraan tempur; unzip tarball dan jalankan isinya; kecuali erlang mungkin diperlukan untuk diluncurkan, karena versi kompilasi silangnya sedikit tidak penting dalam perakitan;
- Anda dapat melakukan rilis upgrade untuk digunakan tanpa downtime.
Debag
Elixir memiliki Pry dan bekerja seperti batu delima. Bahkan ada rails c
mitra yang terlihat seperti iex -S mix
.
Tetapi dalam produksi, Anda harus menggunakan konsol secara berbeda, karena paket dibuat dan mix
tidak ada di dalamnya. Anda harus terhubung ke proses kerja. Ini sangat berbeda dari rail dan pada awalnya Anda menghabiskan banyak waktu mencari cara untuk meluncurkan konsol elixir dalam produksi, karena Anda mencari sesuatu yang mirip dengan rail. Akibatnya, Anda memahami bahwa Anda perlu melakukan segalanya secara berbeda dan memanggil sesuatu seperti: iex --name trace@127.0.0.1 --cookie 'from_env' --remsh 'my_app_name@127.0.0.1'
.
Dilanjutkan ...
Fuh, saya lupa sesuatu. Oh baiklah Anda sebaiknya memberi tahu kami apa yang mengejutkan Anda di Elixir, dibandingkan dengan bahasa lain.