ما أصاب القرصنة المتحمسة أكثر من أي وقت مضى عندما بدأ للتو في دراسة إكسير مع فينيكس.
ملاحظة
أنا شخص بسيط ولن أتعمق. لذلك ، ستكون هناك اختلافات في مستوى الفلاحين العاملين ، ولكن لن يتم ذكر أي شيء حول الاختلاف في مستوى إطلاق التطبيق ، حول مبادئ تشغيل الجهاز الظاهري Erlang وبروتوكول OTP.
الانطباع الرئيسي
الإكسير / فينيكس يشبه إلى حد كبير ريلز وفي نفس الوقت ليس مثله على الإطلاق. مثل بعض العبارات الإنجليزية: بشكل فردي ، الكلمات مألوفة ، ولكن معًا ليست واضحة.
ارلانج مقابل روبي
من الصعب التفكير في روبل ومحاولة الكتابة على إكسير. أنت تدخل في طريق مسدود بانتظام ، لأن ما تريد القيام به ليس على الإطلاق ما كنت تفعله ... أو ، في الواقع ، لا تريد هذا على الإطلاق.
أما بالنسبة للبقية ، فإن الناس يكتبون كتبًا عن اختلافات إرلانج وروبي ، لذا سأكون موجزًا. بالنسبة لي ، كانت الكمينات الرئيسية هي استبدال قاطرات "قاطرات البخار" بالأنابيب ، مع إعادة توجيه التفكير إلى الوظيفة (كانت الفائدة هي تجربة inject
القديمة والحب المشترك inject
/ foldr
) ، وبشكل شخصي ، متطلبات أكثر صرامة من نوع البيانات (على الرغم من ، كلتا اللغتين مع الكتابة الديناميكية الصارمة).
لم تتسبب مطابقة الأنماط في أي مفاجأة ، وما زلت لا أفهم لماذا كان هناك الكثير من الحديث عنه. مجرد أداة مثيرة للاهتمام.
النطاق العام
في إكسير ، كل شيء يكمن في الوحدات. لا يوجد نطاق عالمي. المكالمات C #.
بعبارة أخرى: السكة مسطحة وفي بعض الأماكن تتداخل مع صنع التسلسل الهرمي (أتذكر بمجرد وجود أخطاء مع وحدات تحكم ملقاة في وحدات). إكسير - على العكس ، كل شيء في وحدات. في السكة الحديدية ، يمكنك تخمين الغرض من الكائن من قبل الفئة الرئيسية ، وفي الإكسير ، بالاسم الكامل للفئة / الوحدة النمطية.
التوافق
من ناحية ، هذا ما افتقرت إليه في بعض الأحيان في السكك الحديدية. نظرًا لأنه يمكنك العثور على نصف جيد من الأخطاء عند التجميع ، وليس في وقت التشغيل عند الإنتاج. من ناحية أخرى ، يستغرق التجميع وقتًا. لكن من ناحية أخرى ، هناك حاجة صغيرة ، ولم أر حتى الآن مشاريع كبيرة على إكسير (وليس من خلال مفاهيم إيرلانغ كتابة متراصة كبيرة). علاوة على ذلك ، قام رجال الإكسير بعمل رائع في إعادة تحميل الشفرة والصفحة ديناميكيًا. وحتى الآن ، فإن سرعة العمل ، إلى جانب عدم وجود zeus / الربيع الملحد ، يسخن روحي.
وبالطبع ، فإن هذا يؤدي أيضًا إلى سلبيات ، لكنها تخرج في وقت لاحق. في مكان ما في مجال بيئة الإنتاج والنشر. المزيد عن هذا أدناه.
إليك نقطة مثيرة للاهتمام والتي لا يمكن أن تحدث جسديًا على السكة الحديدية: الهجرات وأشياء أخرى تتطلب في القضبان عبر rake
في إكسير تجميع المشروع وقد يحدث شيء من هذا القبيل: نسيت كتابة المسارات ، يشير مساعد المسار في العرض إليها ، لكن الهجرة هبطت. في البداية - غير عادي إلى حد كبير.
التوثيق
يبدو الموقع الذي يحتوي على توثيق الإكسير أكثر قوة من rubidock و apidok. ولكن هنا هو مقدار الوثائق والأمثلة - هذا هو المكان الذي يتقدم فيه الياقوت / القضبان بكثير. يفتقر الإكسير إلى أمثلة على كل شيء أكثر تعقيدًا من البراز. والواقع أن وصف بعض الأساليب لم يتجاوز التوقيع. كان الأمر صعبًا بالنسبة لي ، حيث اعتدت على الاحتكاك بوفرة من الأمثلة والأوصاف ، مع بعض طرق الإكسير. في بعض الأحيان كان علي أن أتجول وأختبر لفترة طويلة لفهم كيفية استخدام هذه الطريقة أو تلك ، لأنني لا أعرف اللغة جيدًا حتى أتمكن من قراءة الرموز المصدر للحزم بحرية.
استقلالية موقع الملف عن محتوياته
كما يقولون "بقوة عظيمة تأتي مسؤولية كبيرة". من ناحية ، يمكنك صنع الباشانيا وتحلل الأشياء بحيث لا يمر العدو بالتأكيد. ومن ناحية أخرى ، يمكنك تسمية المسارات بشكل أكثر منطقية ووضوحًا ، مع إضافة مستويات منطقية من الدلائل غير الموجودة في التسلسل الهرمي للفئة. على وجه الخصوص ، يمكننا أن نتذكر الرائد وما شابه مع فكرة الجمع بين كل ما يتعلق بالعمل في مكان واحد. في الإكسير ، يمكن القيام بذلك بدون مكتبات خارجية أو أكوام من الفئات ببساطة عن طريق نقل الملفات الموجودة بشكل صحيح.
مسار طلب شفاف
إذا كان السؤال حول الرف في Rails هو سمة لا غنى عنها في أي مقابلة ، لأن السكة هي قمة جبل الجليد ومن وقت لآخر تريد أن تجعل الوسيطة الخاصة بك. هذا في إكسير هذه الرغبة لا ينشأ على الإطلاق (على الرغم من أنني ربما لا أزال صغيرة وكل شيء أمامنا). هناك مجموعة واضحة من خطوط الأنابيب يمر من خلالها الطلب. وهناك يمكنك أن ترى بوضوح مكان جلب الجلسة ، وحيث تتم معالجة رسائل الفلاش ، وحيث يتم التحقق من csrf ويمكن التحكم في كل هذا كما تريد في مكان واحد. في السكك الحديدية ، يتم تثبيت هذه المزرعة بأكملها جزئيًا وتناثرها جزئيًا في أماكن مختلفة.
طرق الداخل للخارج
في Rails ، الحالة التي يمكن فيها استجابة إجراء واحد بعدة تنسيقات هي القاعدة. هناك حتى (.:format)
وضعها مباشرة في المسارات. في الإكسير ، بسبب الخاصية المذكورة أعلاه مع خط الأنابيب ، لا تظهر فكرة تنسيق تناظري على الإطلاق. تنسيقات مختلفة على خط أنابيب مختلف ولها عناوين URL مختلفة. إنها صحية بالنسبة لي.
دارة في النموذج
هذه قصة خرافية بشكل عام. كما تصف مجالات النموذج ، سيكون الأمر كذلك. لا يوجد نوع ضمني من الأنواع. بالإضافة إلى ذلك ، لا توجد عكازات لتقييد الوصول إلى الحقل ، الموجود في قاعدة البيانات ، ولكن لسبب ما لا يمكن استخدامه في تطبيق ويب.
عمليات التحقق والرد
لا توجد استدعاءات في الإكسير. هناك كل شيء أكثر وضوحا. وأعتقد أنني أحبها.
بدلاً من مسار السكة في مجموعة الإكسير ، التي تجمع بين المعلمات القوية والتحقق وبعض الاسترجاعات. والباقي من عمليات الاستدعاء تمر عبر Multi ، مما يجعل من الممكن جمع مجموعة من العمليات ، وتنفيذها بمعاملة ومعالجة النتيجة.
باختصار ، كل شيء مختلف. في البداية هذا غير عادي. ثم في الأماكن التي تثير غضبي بشدة ، لأنه لا يمكنك فقط لصق رد اتصال آخر لكل شيء وعدم التفكير في حالات العمل المختلفة. ثم تبدأ بملاحظة "سحر لا يمكن تفسيره" ، لأنه يجب عليك القيام به بشكل صحيح ، وليس كما اعتدت.
العمل مع DB
بدلاً من ActiveRecord ، ظهر بعض Ecto.Repo و Ecto.Query والعديد من إخوانهم. لمعرفة كل الاختلافات هي مقالة منفصلة. لذلك ، سأقول الأحاسيس الذاتية الرئيسية.
في التصحيح أكثر ملاءمة من AR. نظرًا لوجود نطاق عام ، يتم تحميل الثوابت من مسار التحميل عند الوصول إليها ويمكنك ببساطة فتح rails c
، اكتب User.where(email: 'Kane@nod.tb').order(:id).first
واحصل على النتيجة.
في Elixir ، وحدة التحكم ليست كافية. يجب القيام بعدد من الإجراءات:
- استيراد طريقة لبناء استعلام SQL:
import Ecto.Query, only: [from: 2]
؛ - أضف فئات لتجنب تهجئة أسمائها الكاملة:
alias MyLongApplicationName.User
- لكتابة User
بدلاً من MyLongApplicationName.User
؛alias MyLongApplicationName.Repo
- وبالمثل للوصول إلى فئة يمكنها تنفيذ sql وإرجاع النتائج ؛
- والآن فقط يمكنك الكتابة
from(u in User, where: u.email == "Kane@nod.tb") |> Repo.one
من ناحية أخرى ، في رمز التطبيق ، تعطي هذه "الشكليات" رمزًا أكثر قابلية للقراءة ، بالإضافة إلى وجود شعور بأنك تتحكم في ما يحدث ، وليس أنك تعيش حياتها الخاصة. أي أنك تختار الطرق والنماذج والكائنات الأخرى التي تحتاج إلى العمل ، وتحملها بشكل صريح وتستخدمها.
اسم التطبيق
في صورة وشكل ريلز ، افترضت أن اسم التطبيق مستخدم في زوج من التكوينات وهذا كل شيء. لذلك ، لم أكن منتبهاً لطول الاسم. ولكن عبثا. في Elixir ، الوحدة النمطية التي تحمل اسم التطبيق هي المستوى الأعلى في التسلسل الهرمي لوحدات تطبيق الويب وستظهر في كل مكان.
اتصلت برقم الرمل الخاص بي. والآن أعاني قليلاً ، لأن هذا اسم طويل إلى حد ما وتحتاج إلى كتابته باستمرار. سواء في ملفات الفصل أو في وحدة التحكم عند استدعاء أي شيء. بالمناسبة ، نعم ، من يهتم ، إليك صندوق الرمل على GitHub .
N + 1
في ريلز ، لدينا خارج الصندوق ، ولكن في إكسير خارج الصندوق لا توجد مشكلة من هذا القبيل. هناك ، في مرحلة تجميع الطلب ، يمكنك تحديد العلاقات المطلوبة وسيتم تحميلها أثناء تنفيذ هذا الطلب بالذات. لم يتم تحميله؟ لن تتمكن من الوصول إلى هذه العلائقية. كل شيء بسيط وجميل.
طلب معالجة والاستجابة
باختصار: في طائر الفينيق ، كل شيء أكثر وضوحا من السكك الحديدية.
conn في كل مكان
نظرًا لعدم تخزين الحالة في كومة من الكائنات المختلفة ، يجب سحبها في كائن واحد. يذكر request
من ActionController
، فقط أكثر شمولاً. يتم استدعاؤه في connection
فينيكس. يحتوي على كل شيء: request
flash
session
وكل شيء. يظهر في مكالمة لكل ما يتعلق بمعالجة الطلب الذي وصل.
هنا وسلبيات ، لأن الأول هو كسول للغاية للنحت conn
كل مكان ولا يفهم لماذا تماما. السكك الحديدية في هذا الصدد تفسد. تكتب التقديم أو الفلاش ولا توجد أفكار بأن هذا الإجراء ذو صلة. وفي Phoenix conn
يذكرك باستمرار بالعمل مع اتصال أو مقبس معين ، وليس فقط الطرق تسمى ويحدث السحر في الداخل.
جزئي & القالب
في فينيكس ، لا يوجد فصل بين الجزئي والقالب. وظيفة كاملة في نهاية المطاف. هناك سحر آخر هنا: السكة ، حتى في بيئة الإنتاج ، تزحف باستمرار خلف المشاهدات على القرص وتولد IO بالإضافة إلى النفقات العامة لتحويلها من erb / haml / etc إلى html. وفي Elixir كل شيء هو وظيفة ، بما في ذلك المشاهدات. جمعت طريقة العرض مرة واحدة وكل شيء: يحصل على الحجج ، يبصق HTML ، لا يذهب إلى القرص.
المشاهدات
في ريلز ، تُفهم طريقة العرض على أنها جزئية وقوالب ، بينما في فينيكس تكمن في القوالب ، وفي طرق العرض ، تقريبًا ، هناك طرق مختلفة لتقديم البيانات. على وجه الخصوص ، هناك تجاوزات تجسيد.
أي ، بشكل افتراضي ، لا تقدم وحدة التحكم أي شيء. كل شيء يسمى صراحة. وإذا لم يكن لديك جزء جزئي ولا تحتاج إليه حقًا (على سبيل المثال ، في حالة json ، عندما يتم بناؤه بسهولة بواسطة فئة الخدمة) ، فأنت تعيد تعريف العرض بطريقة أو بأخرى على النحو التالي:
def render("show.json", %{groups: groups}) do %{ groups: groups } end
ولم يعد هناك حاجة إلى الجزئي.
هبلرز
لا يوجد شيء في فينيكس. وهذا رائع! بالنسبة للمساعدين في السكك الحديدية ، عادة ما يتم جمع كل القمامة ، والتي كانت إما كسولة ليتم دفعها في الزوايا ، أو تحتاج فقط لملء شيء بسرعة.
ومع ذلك ، فإن الأساليب في وحدة التحكم ، وجهات النظر ، وما إلى ذلك. يمكنك الإضافة. يتم ذلك في مكان خاص web/web.ex
ويبدو لائقًا جدًا.
الاستاتيكا
في التطوير ، كل شيء على النحو المعتاد ، باستثناء أنه في طائر الفينيق لا يزالون يثقلون إعادة التحميل المباشر ، أول من يطلق عليه "Wow!" تأثير. هذا عندما قمت بتغيير Css ، وعادت إلى المتصفح ، وهناك تم تحميل التغييرات نفسها بالفعل.
في الإنتاج في فينيكس ، يختلف سلوك الإحصائيات قليلاً قليلاً عن سلوك القضبان. بشكل افتراضي ، يتم تسجيل الأماكن التي يمكنك فيها سحب الإحصائيات بشكل صريح ولا يمكنك فقط إضافة ملفات إلى الأصول لتوزيعها. لا يزال هناك تخطيط للأصول الافتراضية ، بحيث لا تتجول حول FS مرة أخرى ، ولكن تأخذ الملف المطلوب على الفور وتتخلص منه.
الأصول
خارج منطقة الجزاء في فينيكس - غداء . يمكنك استبداله بحزمة الويب . ولكن هناك نكتة صادقة جدًا حول حقيقة أن العديد من المشاريع عازمة في مرحلة إعداد حزمة الويب.
باختصار ، يتم جمع js و css بشكل أو بآخر ، ولكن مع بقية الثبات في وجبة الإفطار ليس كذلك. قم بنسخه بيديك مباشرة إلى المشروع من node_modules (لا أحب هذا الخيار على الإطلاق) ، أو اكتب الخطافات على الباش. على سبيل المثال ، هكذا .
العمل مع SSL
خارج الصندوق في فينيكس هو خادم http صغير يسمى رعاة البقر . يبدو كوغار روبي. لديهم حتى نفس عدد النجوم على جيثب. ولكن بطريقة ما لم أحصل على إعدادات طبقة المقابس الآمنة في أي مما سبق. خاصة مع Let's Encrypt ، ملف تكوين خادم ويب إضافي وتجديد الشهادة المنتظم. لذا كخادم http - حسنًا ، ولكن بالنسبة لـ SSL ، أقوم باستخدام وكيل إلى localhost عبر apache / nginx.
انشر
وهي تختلف بشكل عام مقارنة بالسكك الحديدية. في ريلز ، في الحد الأدنى من الإصدار ، قاد اللفت إلى الخادم ، ورقص مع الدف للحزم ، والتكوينات ، والأصول ، وأطلق التطبيق. والإكسير يجمع و حفر في الترام لإقناع اللفت لن يركب. تحتاج إلى جمع الحزمة. ويبدأ هنا:
- سوف تكتشف سبب الحاجة إلى التطبيقات في
mix.exs
، لأنه بدون الإشارة إليها بشكل صحيح في أخطاء mix.exs
، رائعة ؛ - تتعلم أن متغيرات البيئة يتم تجميعها في وقت بناء الحزمة ، وليس في وقت إطلاقها ، وهذه هي المرة الأولى مفاجأة بليغة ؛ ثم تتعلم عن relx مع
RELX_REPLACE_OS_VARS=true
يذهب قليلاً ؛ - تتفاجأ من أنه في الحزمة المجمعة للإنتاج لا يوجد شيء مشابه للمكشطة ، على وجه الخصوص لا توجد عمليات ترحيل وتحتاج إلى تشغيلها بطريقة أو بأخرى بشكل منفصل ، على سبيل المثال ، من بيئة التطوير من خلال إعادة توجيه المنفذ إلى قاعدة البيانات (أو عبر eDeliver ، والتي ستفعل نفس الشيء) .
وبعد ذلك ، بينما تتعامل مع ما سبق ، يبدأ المحترفون:
- يمكنك جعل الحزمة مكتفية ذاتيًا ولا تضع أي شيء من التبعيات على مركبة القتال ؛ فقط قم بفك ضغط ملف tarball وتشغيل المحتويات ؛ ما لم يكن هناك حاجة إلى إرلانج ليتم طرحه ، لأن نسخته المتقاطعة غير بسيطة في التجميع ؛
- يمكنك القيام بإصدار ترقية للنشر دون توقف.
ديباج
يحتوي الإكسير على Pry ويعمل تمامًا مثل الياقوت. حتى أن هناك نظيرًا rails c
يشبه iex -S mix
.
ولكن في الإنتاج ، يجب عليك استخدام وحدة التحكم بشكل مختلف ، نظرًا لأن الحزمة مبنية وليس mix
فيها. يجب عليك الاتصال بعملية عمل. هذا يختلف جذريًا عن القضبان ، وفي البداية تقضي الكثير من الوقت في البحث عن طريقة لإطلاق وحدة تحكم الإكسير في الإنتاج ، لأنك تبحث عن شيء مشابه للسكك الحديدية. ونتيجة لذلك ، فأنت تدرك أنك بحاجة إلى القيام بكل شيء بشكل مختلف والاتصال بشيء مثل: iex --name trace@127.0.0.1 --cookie 'from_env' --remsh 'my_app_name@127.0.0.1'
.
يتبع ...
فوه ، لقد نسيت شيئا بأي شكل من الأشكال. حسنًا. من الأفضل أن تخبرنا بما فاجأك في Elixir ، مقارنة باللغات الأخرى.