عملگر گراز دریایی در PHP

در اکتبر ۲۰۱۹، پایتون ۳.۸ عملگر Walrus () را معرفی کرد.:=) از طریق پی ای پی ۵۷۲ – و بدین ترتیب یکی از بزرگترین جنجال‌ها در تاریخ زبان برنامه‌نویسی را برانگیخت. این بحث آنقدر تلخ بود که مخترع پایتون گویدو فان روسوم در ژوئیه ۲۰۱۸ - حتی قبل از آزادی - سمت او به عنوان BDFL (دیکتاتور خیرخواه مادام العمراز ابتدای سال ۲۰۱۹، پایتون توسط یک شورای راهبری منتخب اداره می‌شود.


if (n := len(items)) > 10:
    print(f"List is too long ({n} elements)")

اختلاف بر سر مدیریت بلافاصله پس از بحث والروس (Walrus) به وجود آمد - مورد نادری که در آن یک ویژگی زبانی پیامدهای ساختاری داشت. ون راسوم در بیانیه خود توضیح داد: «آخرین ضربه، یک پیشنهاد بسیار بحث‌برانگیز برای بهبود پایتون بود. بعد از اینکه من آن را پذیرفتم، مردم به رسانه‌های اجتماعی مانند توییتر رفتند و چیزهایی گفتند که شخصاً مرا آزرد.»

او ادامه داد: «حالا که PEP 572 تمام شده، دیگر هرگز نمی‌خواهم مجبور باشم اینقدر سخت برای PEP بجنگم و ببینم که خیلی‌ها از تصمیمات من متنفرند. می‌خواهم خودم را کاملاً از فرآیند تصمیم‌گیری کنار بکشم.» این انتقاد نه تنها از سوی جامعه‌ی وسیع‌تر، بلکه از سوی توسعه‌دهندگان اصلی نیز مطرح شد.

آنها استدلال کردند که این عملگر با اصول بنیادی پایتون از مکتب ذن پایتون - به ویژه ترجیح سادگی بر پیچیدگی - در تضاد است. پس از نزدیک به سه دهه به عنوان طراح بلامنازع زبان، این پایان یک دوره بود. اما در حالی که پایتون مجبور شد یک عملگر جدید Walrus را معرفی کند و در این فرآیند جامعه خود را تقسیم کند، این سؤال مطرح می‌شود: زبان‌های دیگر چگونه مفاهیم مشابه را مدیریت می‌کنند؟

عملگر پایتون := (عبارت انتساب با نام مستعار "Walrus") در PHP وجود ندارد - زیرا نیازی به آن نیست. در PHP، عملگر انتساب = همیشه بیان و اظهار نظر همزمان: یک انتساب، مقدار اختصاص داده شده را برمی‌گرداند. دقیقاً به همین دلیل است که الگوهای اصطلاحی مانند «انتساب و آزمایش» در ... کار می‌کنند. if-شرایطی که فاقد ویژگی زبانی خاص خود هستند.

function get_some_field() {
    return 'foo';
}
if ($a = get_some_field()) {
    echo $a; // foo
}
// Hinweis: $a ist *gesetzt*, selbst wenn die Bedingung falsy wäre.

$a = get_some_field() به سمت راست اختصاص داده و ارزیابی می‌کند. اگر این «درست» باشد، شما وارد می‌کنید if-بلوک. پیشینه: در پایتون، := (PEP 572) زیرا انتساب‌های ساده، عبارات نیستند. در PHP، این همیشه متفاوت بوده است، بنابراین نیازی به معادل آن وجود ندارد. دو چیز اغلب منجر به اشکالات می‌شوند.: = (انتساب) نسبت به اکثر عملگرهای رابطه‌ای اولویت پایین‌تری دارد؛ پرانتزها ارزیابی را تعیین می‌کنند.

در عبارات پیچیده‌تر، همیشه باید از پرانتز برای افزایش خوانایی و وضوح استفاده کنید. ?? اولویت خاص خود را دارد، اما نسبتاً کم اهمیت است. این موضوع شگفتی‌های موجود در عباراتی مانند $x ?? null === null. بدون پرانتز، ابتدا null === null ارزیابی شده است. بهتر است همیشه به طور صریح در براکت قرار گیرد: ($x ?? null) === null. $a در خارج نیز وجود دارد if-بلوک‌ها - احتمالاً با یک مقدار نادرست.

function get_some_field() {
    return 'bar';
}
if ( ($a = get_some_field()) === 'bar' ) {
    echo $a; // bar
}

پس واضح است که === 'bar' به مقدار اختصاص داده شده اعمال می‌شود. براکت‌ها در اینجا برای خوانایی و اولویت مهم هستند. در عمل، این الگو با ذخیره نتیجه پرس و جو و سپس بررسی آن، از فراخوانی‌های تکراری غیرضروری (مثلاً از سازنده پرس و جو) جلوگیری می‌کند. در برنامه‌های کاربردی تولیدی، مانند پروژه‌های مبتنی بر لاراول، الگوی زیر را می‌توان بیشتر مشاهده کرد.:

if ( ($foo = Foo::where('foo', 'bar')) && $foo->count() > 0 ) {
    dd($foo->get());
}

&& اتصال کوتاه است: بخش سمت راست فقط در صورتی ارزیابی می‌شود که بخش سمت چپ درست باشد. با اختصاص دادن دستور به بالادست، از اختصاص دادن دستور خارج از دستور if جلوگیری می‌کنید. اینکه آیا این روش خوبی است یا خیر، به کد و ابزارهای تحلیل تیم شما بستگی دارد؛ از نظر معنایی، درست است. حداقل، اگر در عمل با کد مواجه شوید، باید بدانید که چه کاری انجام می‌دهد.

PHP به "عملگر Walrus" نیازی ندارد زیرا انتساب‌ها از قبل عباراتی هستند. این امر الگوهای اصطلاحی مانند "assign-and-test" را ممکن می‌سازد - کارآمد و مختصر. در عین حال، الزامات مربوط به نظم و انضباط افزایش می‌یابد: پرانتز، مقایسه‌های دقیق، آگاهی از درستی/نادرستی و قراردادهای واضح تیمی الزامی هستند. کسانی که از این دستورالعمل‌ها پیروی می‌کنند، بدون نیاز به ویژگی زبانی اضافی، از مزایای ایده Walrus بهره‌مند می‌شوند.

بازگشت