تا چه زمانی می توان از شرط های تو در تو استفاده کرد مانند case در الکسیر

همیشه یادم هست که از گذشته تا به الان می گفتند وقتی دارید زیاد داخل css از margin منفی استفاده می کنید یعنی شما کامل مسیر رو اشتباه رفتید . این یک مثالی بود برای مقدمه چیزی که می خوام بیان کنم . به قطعه کد زیر توجه فرمایید :

      "token" => _token, "ptoken" => ptoken} = allreq) do
         case user_acl_check(allreq) do
            {:ok, %{acl: "admin", info: info}} ->
               IO.puts "+++++++++++++++++++"
               conn
               |> put_status(200)
               |> json(info)
            _ -> 
               conn
               |> put_status(400)
               |> json(%{message: "400 "})
         end
   end

   defp user_acl_check(allreq) do
      user_acl_checks = case check_acl_of_post(allreq) do
         {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->  
            a = Jason.decode!(body)
            {:ok, %{acl: a["user_info"]["user_acl"], info: a}}
         _ ->
            {:error, :token_invalid}
      end
      user_acl_checks
   end

   def check_acl_of_post(token) do
     TrangellApiGateway.User.Login.user_info_user_sender(token)
   end

اگر توجه کرده باشید من دو سه فانکشن رو در یک فانکشن فراخوانی کردم که هر فانکشن ممکن هست داخل خودش یک case داشته باشد . و ممکن است این قطعه کد حتی چند فانکشن دیگر را نیز فراخوانی کند که با هم داخلشان case وجود دارد .

به صورت تقریبی شمردم من دارم در یک فانکشن ۵ الی ۷ case تو در تو ولی در یک فانکشن استفاده می کنم. حالا سوال اصلی اینجاست؟

  • من تا کجا می تونم این روند رو ادامه بدم ؟
  • آیا فلسفه مثلا elixir با این کار مخالفه ؟
  • چه زمانی شما به این فکر می افتید که دارید اشتباه می کنید ؟
2 پسندیده

جواب کوتاه اینه که از nested control flow حالا میخواد شرط باشه یا مثل نمونه شما switch، بدلیل سخت شدن و پیچیده شدن کد نباید زیاد استفاده کرد، من سعی میکنم بیشتر از یک یا در شرایط خیلی خاص بیشتر از دو جریان کنترلی تو در تو نداشته باشم.
فانکشن ها یا متد هایی که جریان های کنترلی تودرتو رو مثل نمونه شما از هم جدا میکنند بدلیل جدا کردن و در کپسول قرار دادن جریان های داخلی تا حدی به خوانا بودن کد کمک میکنند و دیگه چندان تو در تو بحساب نمیان، مگر اینکه خیلی کار خیلی گیر پیدا کرده باشه :hugs:. در کل بنظر من وقتی عمق این نوع جریان ها زیاد میشه یعنی احتمالا اشکالی طراحی وجود داره و ممکنه راه بهتری هم باشه. در پایان مثال شما خوب و بدون خوانا بنظر میاد و مشکلی خاصی نداره.

1 پسندیده

شما ک فانکشنال مینویسی دیگ چرا : ))
من سعی میکنم تو کدام خیلی کم تو در تو بنویسم … چون برای اصلاحات بعدی ممکنه زمانبرش کنه …
سعی کن استیت هاتو جدا کنی… و گاها استیت لسش کنی …

مثلا هر فانکشن میتونه یه break یا raise err داشته باشه ک جریان رو قطع میکنه … و نیاز نیست که یه چکر هم سر فانکشن بزاری ببین true / false برمیگردونه یا نه .

یا اینکه جایی ک قراره ۱فانکشن چند کار بکنه … با if … بهتره ک قسمت های مشترک رو بنویسی… و ارث ببری… یا اینکه قسمت مشترک رو فانکشن جدا کنی… و فراخوانی… و اسکوپ هرکدوم رو جدا کنی…

اما گاهی اوقات این پیچیدگی ها اجتناب ناپذیرن …
بنابری تو مرحله طراحی تا میتونی فکر کن و اصول رو طراحی کن… و تو مرحله اجرا کمتر کار انجام بده …

1 پسندیده

گاهی اوقات تو طراحی وب اپ … middleware های کاستوم هم خیلی مفیدن…
میشه پروسه های تکراری یا ارور هارو بهش سپرد …

2 پسندیده

بله راه حل های متفاوتی وجود داره که بعضی ها رو شما فرمودین.

اما دو تا موضوع مهم اینجا هست،
1- کلا early retun یا همون break ایده چندان جالبی نیست و اصلا همچین چیزی در الیکسر وجود نداره. اما raise کردن استثنا میتونه گاهی خیلی به کار بیاد(let it crash).
2- در مورد stateless بودن هم اصلا همچین مشکلی در برنامه نویسی فانکشنال بخصوص در اکوسیستم ارلنگ وجو نداره چون همه چیز stateless هست و بر خلاف oop اصلا با state سر و کار نداریم.

2 پسندیده

درست میفرمایید … ولی حین منطق نوشتن . برنامه نویس هست ک میتونه استیت ایجاد کنه یا استیت لس ادامه بده …

مثلا حفظ حالت اجرا توی لایف تایم یه فانکشن یه استیته ک خیلی سخته رفع کردنش. و میتونه همون شرطای تو در تو ایجاد کنه … درحالی ک هرکدوم اگه شکونده بشه ب قسمت های کوچیک تر … یا بررسی ضرورت کیس و استیت ها و تبدیلشون به ۲ استیت کلی … خیلی اوقات کمک میکنه . …

از نظر من استیت لس بودن وجود نداره …فقط ما انقد کوچیکش میکنیم ک دیگه به چشم نمیاد و اجزای داخلی میتونن مستقل کار کنن و باهم ارتباط بگیرن …

1 پسندیده

من از الیکسیر زیاد سر در نمیارم … ولی چرا باید داخل هر فانکشن چک بشه توکن و auth? و یا درست نبودن فرمت ارسالی … درحالی ک براحتی با میدل ویر میشه از تکرارش جلوگیری کرد …

1 پسندیده

ممم، اگر بخوایم اینطوری فکر کنیم یکمی مفاهیم گنگ میشه،
در الیکسر همه چیز با recursion و pattern matching انجام میشه و اصلا حتی loop به صورت چیزی که در زبان های دیگه هست وجود نداره چون state وجود نداره.
برای نگه داشتن state باید از پروسه ها استفاده کرد چون دیتا غیر قابل تغییره و در واقع statless هست، استفاده از پروسه هایی که با هم پیام رد و بدل میکنند.

1 پسندیده

هیچ وقت از pattern matching خوشم نیومد. پیچیدگی الکی اضافه می کنه به نرم افزار و در مقابل Expression Problem هم جوابی نداره. در سطح کد هم scalable نیست متاسفانه.

1 پسندیده

یعنی اصلا mutation امکان پذیر نیست توی elixir ?

بستگی داره دقیقا منظور از pattern matching چی باشه

یعنی اصلا mutation امکان پذیر نیست توی elixir ?

خیر, به هیچ وجه

بله البته درست می فرمائید. pattern matching به این روشی که در این پست بحث شده و روال عادی فانکشن های erlang و haskell منظور بود.

1 پسندیده

خیلی سخت میکنه کارو اینجوری …
جاهای زیادی تو برنامه هستن ک mutation کمک میکنه .بدون اینکه خطا رخ بده یا ریس دیتا ایجاد بشه…

تو هر فانکشن چک نمی شه . در فانکشن اول چک می شه . ولی در هر اکشن چک می شهبخاطر اینکه اولی رمزگزاری سایت به api هست و دومی توکن وب سرویس یوزر به api البته بخشیشو کمتر کردم با نوشتن پلاگین ولی کمی موفق نبودم یعنی راه حلم باید ویرایش بشه که پلاگین تمیزی بنویسم کار های تکراری حذف بشه

مخالف نیستم, اما خب کی دقیقا؟

منظرو شما از این کلمه یعنی از وسط تابع استپ بخوره و بره سر کار دیگه ای ؟ اگر اون هست بجاش می شه ارور برگردوند . و چک کرد

مثلا با فرض اینکه نشه header رو تغییر داد یا بهش چیز کاستومی اضافه کرد … تا بصورت inner استفادش کرد … وحشتناکه: ) عملا بیچاره ها نمیتونن از middleware استفاده کنن :sweat_smile:

نه یعنی دیتا تغییر کنه

1 پسندیده

من فقط تغییر دیتا منظورم نبود . تغییر استیت خروجی بود .که میتونه دیتا باشه یا خود ارور کد

1 پسندیده