Powershell: اقتراح: تنفيذ الشروط الثلاثية

تم إنشاؤها على ٢ مارس ٢٠١٧  ·  52تعليقات  ·  مصدر: PowerShell/PowerShell

ستكون الشروط الثلاثية على النمط C إضافة مفيدة للغة.

على سبيل المثال ، بدلاً من الكتابة:

if ((get-date).tostring("ss") % 2) { 'odd'  } else  { 'even' }

يمكن للمرء أن يكتب:

(get-date).tostring("ss") % 2   ?   'odd'   :    'even'

كما أنه سيخفف من خيبة الأمل الطويلة الأمد:

في Microsoft ، "الشحن هو الاختيار". أحد الأشياء التي شعرنا بخيبة أمل كبيرة لعدم قدرتنا على الشحن في V1.0 هو مشغل ثلاثي.

من منشور مدونة فريق PowerShell بتاريخ 29 ديسمبر 2006.


ذات صلة: تنفيذ الاندماج الفارغ والتعيينات الشرطية الصفرية والتخصيصات الشرطية الخالية

Committee-Reviewed Issue-Enhancement WG-Language

التعليق الأكثر فائدة

RichardSiddaway : إذا نظرنا إلى Stack Overflow في الأسئلة التي تحمل علامات PowerShell _ التي تم طرحها منذ عام 2014_ ، فإننا نحصل على (حتى كتابة هذه السطور):

$PSItem في الإصدار 3 في سبتمبر 2012 ، لذلك اخترت 2014 كتاريخ بدء الاستعلام.

في حين أن هذا ليس مقياسًا دقيقًا ، - لا يسمح لك الموقع بالبحث عن $_ أو _ ، للأسف ، وأنا متأكد من أن هناك أسئلة تحتوي على _ oneither_ $_ ولا $PSItem ، ولا يزال يتم طرح أسئلة ما قبل الإصدار الثالث - ما زلت أعتقد أنه من الآمن استنتاج أن $_ يستخدم بشكل متكرر أكثر من $PSItem .

ومع ذلك ، فإن النقطة الأكبر هي أنه لا داعي للاختيار:

مثلما يتعايش $PSItem و $_ لحسن الحظ ، كذلك يتعايش ForEach-Object و % و Where-Object و ? ، .. .:

يمكن أن يتعايش $a ? $b : $c مع if ($a) { $b } else { $c } / $(if ($a) { $b } else { $c })

بالنسبة لتلخيص الأسباب الإيجابية لتقديم $a ? $b : $c

  • أكثر إيجازًا ، وأقل تشوشًا بصريًا ، باستخدام بناء الجملة المألوف لدى معظم المبرمجين.

  • أكثر كفاءة ، لأنه لا توجد حاجة لـ $(...) ، والتي تحتاجها كشوفات if للسماح باستخدامها كجزء من تعبير أكبر (وهو أكثر ضوضاء ، وأقل كفاءة ، ويمكن أن يكون له جانب غير مقصود تأثيرات)

أما عن الغموض:

يمكن أن يُفترض أن شخصًا ما يكتب _expressions_ (على عكس مجرد _استحضار الأوامر _ مع وسيطات (بسيطة)) لديه بعض خبرة المطور ، وإحساسي (القصصية) هو أن معظم المطورين على الأقل _recognize_ $a ? $b : $c كمكثف if بيان

حتى لو لم يفعلوا ذلك ، يمكن تفسير ذلك بسهولة ، وبغض النظر عن استخدام _ الرموز_ غير الواضحة ، فإن التعقيد المفاهيمي هو نفسه تعقيد if ($a) { $b } else { $c } ، وحتى أقل من
$(if ($a) { $b } else { $c })

بافتراض أنه يتم التعرف عليه بمجرد تقديمه - بالتأكيد ، تُظهر هذه المناقشة أن هناك طلبًا عليها - فإن مواجهتها بشكل متكرر ستجعلها لغة مألوفة ويمكن التعرف عليها بسهولة (وهذا أكثر إيجازًا ، وأسهل في الكتابة ، وعلى الأقل بالنسبة لي وعدد قليل من الآخرين هنا ، أكثر قابلية للقراءة) - تمامًا كما يبدو أن معظم الناس يفضلون $_ على $PSItem .

ال 52 كومينتر

لاحظ أنه مع التغيير للسماح بالتخصيصات من البيانات ، تقل الحاجة إلى عامل التشغيل الثلاثي. يمكنك ببساطة أن تفعل
$var = if ($x) { $x } else { $y }
إنها ليست موجزة مثل العامل الثلاثي ولكن يمكن القول إنها أكثر قابلية للقراءة.

نعم ، على الرغم من أنه لا يزال يتعين عليك استخدام $(...) _in بالإضافة إلى إذا كان الشرط جزءًا من تعبير أكبر:

'The current sec. is ' + $(if ((get-date).tostring("ss") % 2) { 'odd'  } else  { 'even' })

ضد.

powershell 'The current sec. is ' + ((get-date).tostring("ss") % 2 ? 'odd' : 'even')

أعلم أن قابلية القراءة في عين ... آه ... القارئ ، لكنني شخصيًا أجد أن هذا الأخير أسهل في التحليل البصري ، والاضطرار إلى كتابة أقل هو دائمًا مكافأة.

مع هذه الميزة المستخدمة بشكل متكرر ، أعتقد أن تذكر بناء الجملة الثلاثية الأكثر تجريدًا لن يكون مشكلة (وبالطبع ، يمكن للأشخاص الاستمرار في استخدام if ، إذا كانوا يفضلون).

@ mklement0 يجب أن أوافق لاحقًا على حمل إدراكي أقل.

هذا بالتأكيد على قائمتي العليا ل.
BrucePay ، هل هناك أي أسباب تجعل هذه فكرة سيئة؟ أم أن الأمر يتعلق فقط بـ "الشحن هو الاختيار"؟

في الماضي ، تم رفض طلب الميزة هذا باعتباره من الصعب فهمه على المبرمجين الأقل خبرة ، وأن شكل تعبير عبارة if كان أوضح ، على الرغم من أنه بديل أكثر تفصيلاً.

وجهة نظري الشخصية: إذا كانت اللغة مخصصة لي فقط ، فربما كنت قد أضفتها منذ وقت طويل. لكن ... أجد أن العديد من المطورين لا يستخدمونه ، مما يشير في الواقع إلى أن هناك بعض الحقيقة في الفرضية القائلة بأن الأشخاص الأقل خبرة سيواجهون مشكلة مع المشغل الثلاثي.

lzybkr :

يجدر التمييز بين الاستخدام النشط للميزة مقابل القدرة على التعرف عليها وفهمها.

من الواضح أن على الجميع أن يختاروا استخدام مثل هذه الميزة ، ولكن هل تقول إن "مشكلة مع" تعني أن الأشخاص الأقل خبرة لن يفهموها عندما يرونها في كود الآخرين؟

@ mklement0 - قدمنا $psitem كاسم مستعار لـ $_ بسبب التعليقات الكافية بأن $_ كان مشفرًا ومربكًا ، لذلك أعتقد أن المشغل الثلاثي سيكون صعبًا لبعض أقل الأشخاص ذوي الخبرة لفهم.

من ناحية أخرى ، هناك العديد من العناصر في PowerShell مربكة للمبتدئين ، أو حتى للمطورين ذوي الخبرة.

كما هو الحال مع أي لغة أخرى ، يتطلب الأمر بعض الجهد لتعلم بناء الجملة ومعنى تراكيب اللغة.
لا أعرف ما إذا كنت أعتقد أن العامل الثلاثي يصعب فهمه بشكل خاص.

هل لديك بيانات تشير إلى ذلك؟

أعتقد أن البيانات الوحيدة هي قصصية ، لكن النقد ينطبق على أي لغة مشفرة - باش ، بيرل ، إلخ.

ولكي أكون واضحًا ، كنت أقدم السياق التاريخي. ربما يكون PowerShell موجودًا في كل مكان الآن بما يكفي لأن المزيد من بناء الجملة المشفر لن يؤثر على التبني.

ضع في اعتبارك أيضًا - لا تزال بعض اللغات المقتضبة تستخدم if / ثم كمعامل ثلاثي ، على سبيل المثال F #.

بعد قولي هذا ، ربما يكون من الممكن استخدام عدد أقل من الأحرف وألا تكون غامضًا جدًا:

if ($x) { $y } else { $z }
$x -then $y -else $z
$x ? $y : $z

-then/-else يتلاءم جيدًا مع بناء جملة PowerShell - ولكن ، عامل التشغيل (أو المشغلين إذا كان من المربك جدًا التفكير في عامل تشغيل واحد) ، يمكنك الاستفادة من عدم الحاجة إلى أقواس وأقواس.

ثم مرة أخرى ، هذا يطلب مشكلة مشابهة لـ foreach مقابل foreach-object . لكن ربما ليس الأمر بهذا السوء ، لا أعرف.

lzybkr :

الجرعات الخفية في المعالجة المثلية صحية:

لا يُستحسن أن يكون PowerShell خفيًا بشكل عام ، ولكن في بعض الحالات يقدم بناء جملة مشفر باعتباره صيغة مختصرة _ بديلة _ (لا يزال بإمكانك الإسهاب إذا رغبت في ذلك) للتركيبات المستخدمة بشكل متكرر ، ولا سيما ? مقابل Where-Object و % مقابل ForEach-Object .

تقديم $x ? $y : $z كبديل موجز لـ if ($x) then { $y } else { $z } بالنسبة لي هو بنفس الروح.

يتم تحسين الجانب الخفي من خلال ? الذي يذكرنا بـ _السؤال_ وبالتالي اقتراح شرطي (على الرغم من _السابق_ ? في هذه الحالة) ، والأهم من ذلك - كونه بناء مألوف من عدة لغات أخرى _ ، مع نفس الدلالات الأساسية.

لا تحصل على نفس الميزة مع $x -then $y -else $z : هذا ليس مألوفًا.

أيضًا ، في حين أن العديد من مشغلي PS لديهم أسماء رمزية ، فإن العديد منهم ليس لديهم: * / + % ...
هذه أيضًا غامضة بطبيعتها ، لكننا لم نعد ندركها بهذه الطريقة بعد الآن ، لأنها مألوفة للغاية ومنتشرة في كل مكان.

إحساسي هو أن $x ? $y : $z هو أيضًا مألوف لدى الكثيرين ، وسيصبح أكثر من ذلك بمجرد إدخاله في اللغة ، نظرًا للحاجة المتكررة لشروط شرطية موجزة.

لاحظ أنك ستكون محدودًا جدًا فيما يمكنك تحديده باستخدام هذا المشغل. على وجه الخصوص ، لن تتمكن من استخدام الأوامر إلا إذا قمت بلفها بين قوسين:

(test-path foo.txt) ? (get-content foo.txt) : (get-content bar.txt)

مقارنة مع

if (test-path foo.txt) {get-content foo.txt} else {get-content bar.txt}

أو

get-content ((test-path foo.txt) ? "foo.txt" : "bar.txt")

ضد

get-content $(if (test-path foo.txt) {"foo.txt"} else {"bar.txt"})

في رأيي ، هناك فائدة قليلة من حيث الإيجاز وعيوب واضحة في قابلية القراءة. يكون العامل الثلاثي أقل إثارة للاهتمام عندما يكون لديك لغة موجهة للتعبير. عندما بدأت تعلم اللغة منذ 16 عامًا ، بدت إضافة عامل التشغيل الثلاثي واضحًا قادمًا من خلفية C. الآن أنا سعيد لأننا لم نضفها أبدًا. إنها مجرد فوضى.

على وجه الخصوص ، لن تتمكن من استخدام الأوامر إلا إذا قمت بلفها بين قوسين:

ينطبق ذلك على مشغل _any_ PowerShell.

لا تتضمن جميع عبارات PowerShell أوامر ، وعندما تفعل ذلك ، يعرف المستخدمون بالفعل أن (...) هو سعر قبول الأوامر (في معظم الحالات).

في المثال الخاص بك ، بالنسبة لي ((test-path foo.txt) ? "foo.txt" : "bar.txt") يتفوق على $(if (test-path foo.txt) {"foo.txt"} else {"bar.txt"}) ، كلاهما بسبب غموض الحاجة إلى $(...) والضوضاء التي تسببها الأقواس المتعرجة.

ربما أنا فقط ولكني أجد هذا:

get-content ((test-path foo.txt) ? "foo.txt" : "bar.txt")

طريقة أسهل للمسح / التحليل البصري من هذا:

get-content $(if (test-path foo.txt) {"foo.txt"} else {"bar.txt"})

شكواي الوحيدة حول هذه المشكلة هي أنه إذا كنت ستقوم بعمل ثلاثي ?: فيجب عليك أيضًا إجراء دمج فارغ ?? :

$logDir = $env:LogDir ?? "$PSScriptRoot\Log"

لقد رأيت عددًا من تطبيقات Invoke-Ternary و Invoke-NullCoalescing في البرية (على سبيل المثال https://github.com/dahlbyk/posh-git/blob/master/src/Utils.ps1#L12). يشير هذا النوع من الإشارات إلى وجود رغبة عامة لمثل هذه الميزة المخبوزة في اللغة.

@ rkeithhill : أوافق ؛ إعادة الاندماج الصفري: توجد مشكلة بالفعل ، والتي تغطي أيضًا النقع الفارغة: # 3240

لذا فإن حجة المبرمجين الأقل خبرة لن تكون قادرة بسهولة على استخدام جملة خالية من التوليف أو الكود الثلاثي أعتقد أنها قصيرة النظر إلى حد ما. ليس هناك أي شرط لاستخدام هذه الميزات "المتقدمة" وإذا لم يتمكن المبرمج من قراءة الكود لأنه يفتقر إلى الخبرة ، فهذا يعني شخصيًا أنني بحاجة إلى تعلم شيء جديد سريع حقًا.
عندما رأيت لأول مرة ثلاثية في C # كنت مثل WTF هل تم تقديم هذا الجحيم الجديد MS ، حتى استغرقت بضع دقائق لقراءة هذا ، ثم كنت مدمن مخدرات.

مثال عملي في POSH ، لدي هذا السطر:
$mc_object = ($Message.fields | where Name -Match appname).Content
وهو أمر جيد ومدهش إلا في حالة عدم احتواء كائن الرسالة $ على خاصية ملف لها اسم "اسم التطبيق" ، وبما أنني لا أتحكم في البيانات المنسقة التي تأتي من JSON ، يجب أن أحدد ما يجب فعله.

لذلك مع عمليات الاندماج الخالية ، كل ما علي فعله هو إضافة ?? "" في النهاية للتأكد من أن $ mc_object كان دائمًا عبارة عن سلسلة صالحة ، حتى لو كانت أداة الضبط الأصلية خالية. خلاف ذلك ، سأضطر إلى القيام ببعض الأساليب المختلفة لإنجاز ما يمكن أن تفعله 4 ضغطات مفاتيح ، مثل
$mc_object = if(-not ($Message.fields | where Name -Match appname).Content)){""}else{($Message.fields | where Name -Match appname).Content}
هذا غير قابل للقراءة بالنسبة لي ، ولكن بعد ذلك يمكنني تنظيف هذا قليلاً عن طريق القيام بشيء كهذا ، وهو ما أفعله.
$mc_object = ($Message.fields | where Name -Match appname).Content if(-not $mc_object){$mc_object = ""}

على الرغم من أنه ليس فظيعًا ، إلا أنه يتم الضغط على أكثر من 4 مفاتيح حتى يتم الضغط على null-coelasce.

على أي حال ، أنا بالتأكيد أصوت لـ ternary و null-coelasce في Powershell ، فهي تضيف بعض الميزات المتقدمة جدًا وتجعل Powershell أكثر إلحاحًا للاستخدام في النموذج "الأساسي" على أي نظام.

lzybkr لم أرى أي شخص يتبنى $PSItem . أعمل على فريق كبير لائق من الأشخاص الذين يكتبون نصوصًا وما زالوا جميعًا يستخدمون $_ ، حتى مستخدمي PowerShell الأقل خبرة.

tibmeister أو ....

if (-not ($mc_object = $Message.fields.where{$_.Name -match 'appname'}.Content)) {
    $mc_object = ''
}

التخصيصات كتعبيرات سوف تمر ، لكنها غير قابلة للقراءة بشكل لا يصدق.

أستخدم psitem $ بانتظام

على مدى عدد من السنوات من التحكيم ، تم استخدام Scripting Games $ psitem كثيرًا في الإجابات

RichardSiddaway : إذا نظرنا إلى Stack Overflow في الأسئلة التي تحمل علامات PowerShell _ التي تم طرحها منذ عام 2014_ ، فإننا نحصل على (حتى كتابة هذه السطور):

$PSItem في الإصدار 3 في سبتمبر 2012 ، لذلك اخترت 2014 كتاريخ بدء الاستعلام.

في حين أن هذا ليس مقياسًا دقيقًا ، - لا يسمح لك الموقع بالبحث عن $_ أو _ ، للأسف ، وأنا متأكد من أن هناك أسئلة تحتوي على _ oneither_ $_ ولا $PSItem ، ولا يزال يتم طرح أسئلة ما قبل الإصدار الثالث - ما زلت أعتقد أنه من الآمن استنتاج أن $_ يستخدم بشكل متكرر أكثر من $PSItem .

ومع ذلك ، فإن النقطة الأكبر هي أنه لا داعي للاختيار:

مثلما يتعايش $PSItem و $_ لحسن الحظ ، كذلك يتعايش ForEach-Object و % و Where-Object و ? ، .. .:

يمكن أن يتعايش $a ? $b : $c مع if ($a) { $b } else { $c } / $(if ($a) { $b } else { $c })

بالنسبة لتلخيص الأسباب الإيجابية لتقديم $a ? $b : $c

  • أكثر إيجازًا ، وأقل تشوشًا بصريًا ، باستخدام بناء الجملة المألوف لدى معظم المبرمجين.

  • أكثر كفاءة ، لأنه لا توجد حاجة لـ $(...) ، والتي تحتاجها كشوفات if للسماح باستخدامها كجزء من تعبير أكبر (وهو أكثر ضوضاء ، وأقل كفاءة ، ويمكن أن يكون له جانب غير مقصود تأثيرات)

أما عن الغموض:

يمكن أن يُفترض أن شخصًا ما يكتب _expressions_ (على عكس مجرد _استحضار الأوامر _ مع وسيطات (بسيطة)) لديه بعض خبرة المطور ، وإحساسي (القصصية) هو أن معظم المطورين على الأقل _recognize_ $a ? $b : $c كمكثف if بيان

حتى لو لم يفعلوا ذلك ، يمكن تفسير ذلك بسهولة ، وبغض النظر عن استخدام _ الرموز_ غير الواضحة ، فإن التعقيد المفاهيمي هو نفسه تعقيد if ($a) { $b } else { $c } ، وحتى أقل من
$(if ($a) { $b } else { $c })

بافتراض أنه يتم التعرف عليه بمجرد تقديمه - بالتأكيد ، تُظهر هذه المناقشة أن هناك طلبًا عليها - فإن مواجهتها بشكل متكرر ستجعلها لغة مألوفة ويمكن التعرف عليها بسهولة (وهذا أكثر إيجازًا ، وأسهل في الكتابة ، وعلى الأقل بالنسبة لي وعدد قليل من الآخرين هنا ، أكثر قابلية للقراءة) - تمامًا كما يبدو أن معظم الناس يفضلون $_ على $PSItem .

mklement0 ، لديك مثال رائع جدًا وأعتقد أنه يوضح النقطة بوضوح ، شكرًا لك.

من خلال إعادة قراءة هذا وإعادة النظر فيه والنظر في بعض الأسئلة ، أجد نفسي أكثر ميلًا نحو صياغة الجمل المطولة المقترحة:

$value = $a -eq $b -then $trueVal -else $falseval

أو ، للحصول على صيغة أكثر قابلية للقراءة من الناحية المعنوية:

$value = $trueVal -if $a -eq $b -else $falseVal

@ vexx32 بينما لا

نعم، أعتقد أنني أميل إلى الاتفاق، ولكنها لا تقرأ أكثر قليلا ... على نحو سلس. لكنني ما زلت أميل إلى الذهاب إلى الأول.

نظرًا لأن المقصود من PowerShell أن تكون لغة "على الطريق المنحدر" إلى C # ، أعتقد أن استخدام ? : هو السبيل للذهاب. حتى JavaScript يستخدم هذا النحو وهي واحدة من أكثر اللغات شيوعًا هذه الأيام. :-)

متفق عليه ، rkeithhill ، من أجل الإلمام بالبناء من عدة لغات أخرى _ و_ الرغبة في الحصول أيضًا على والامتصاص الصفري ، الخالية ، والتي تستند في C # إلى ? أيضًا.

الأخيرين - على سبيل المثال $foo?.bar و $var ?= 'default val' - ليس ممكنًا حقًا بدون تمثيل قائم على الرمز ، وحتى بالنسبة للاندماج الصفري $a ?? 'value-if-null' يبدو أفضل من شيء مثل $a -elseifnull 'value-if-null' .

تذكر أن ? ، كاسم مستعار مستخدم بشكل متكرر لـ Where-Object ، هو بالفعل راسخ بقوة على أنه يمثل _conditional_ ، لذا فإن نقل تلك المعرفة إلى أشكال مختلفة من استخدامها يبدو منطقيًا.

هل PowerShell حقًا على الطريق المنحدر إلى C #؟ أعلم أن هذا كان نية معلنة منذ 10-12 عامًا ولكن هل هذا يحدث بالفعل؟ شكوكي هو أنه بالنسبة لغالبية مستخدمي PowerShell ، فإن C # ليس مكانًا يريدون الذهاب إليه.

إذا كانت الشروط الثلاثية ستحدث ، فأنا أفضل أن أرى شيئًا مثل
$ value = $ trueVal -if $ a -eq $ b -else $ falseVal

كما ذكر @ vexx32

يكون أكثر منطقية بالنسبة لمستخدم PowerShell العادي.

@ mklement0 استندت تعليقاتي حول $ psitem إلى تجربتي الشخصية. إذا كانت لديك تجربة مختلفة ، فهذا لا يبطل تجربتي

أعلم أن هذا كان نية معلنة منذ 10-12 عامًا

نعم ، في قمم MVP المبكرة من بين أماكن أخرى لجيفري. لم أسمع أي شيء مختلف منذ ذلك الحين.

أيضًا ، تقريبًا جميع التركيبات الشرطية / الحلقية تأخذ من C # (وسلالة C) ، if {} ، while {} ، do {} while ، التبديل {} , مقابل {} , foreach {} , حاول {} التقاط {} أخيرًا {} `. من المنطقي بالنسبة لي أن هذا البناء الشرطي سيكون كذلك.

هذه كلمات رئيسية للغة ، مع ذلك ،rkeithhill. المشغلون مختلفون تمامًا.

أعتقد أنك ستجد أن الغالبية العظمى من المشغلين المُستخدمين في PowerShell مختلفون تمامًا عن نظرائهم في C #. من الواضح جدًا أن فريق PS اختار بناء جملة أكثر وصفيًا لغالبية المشغلين.

أود أن أعتبر أن السلوك الثلاثي يجب أن يأخذ أيضًا بعد المزيد من خيارات النحو المطول المتاحة. ربما تم تصميم PowerShell على أنه "on-ramp" لـ C # ، لكن هذا لا يعني أنه يجب أن يرث تركيبته الأكثر رمزية. في الواقع ، هناك العديد من الأماكن التي تم فيها تجنب ذلك بشق الأنفس.

ضع في اعتبارك ، إذا كنت ترغب في ذلك ، أن حججك الخاصة بالصياغة الرمزية متجذرة في كيفية تمثيل يكن PowerShell شخصًا يسلك هذا المسار في المنشور ، وبدلاً من ذلك يفضل العمل باستخدام بناء جملة وصفي يمكن جعله منطقيًا. فقط لأن أولئك الذين لديهم خبرة بالفعل في C # على دراية بهذا النحو ليس بالتأكيد سببًا لاستخدامه.

إذا كانت PowerShell لغة "على الطريق المنحدر" إلى C # أو أي لغة أخرى (والتي أعتقد أنها تعمل بشكل جيد إلى حد ما في هذا الحد الآن) ، فنحن بحاجة إلى التفكير في القاسم المشترك الأدنى هنا والتفكير فيما سيجده الأشخاص الأقل خبرة معقول وبديهي .

أنا لا أقول إن الحلول التي قدمتها هي كذلك ، لكنني أعتقد أنها ربما تتجه في اتجاه أكثر منطقية من هذا المنظور.

ههههههههههه
ماذا عن هؤلاء المشغلين؟

.
=
[]
,
+ - * / %
++ --
+=  -=  *=  /= %=

بشكل عام ، أوافق على أن اتباع قيادة C # ليس مناسبًا دائمًا ، وأن الحفاظ على روح PowerShell يجب أن يكون له الأسبقية.

بالمقابل ، أنصح بعدم الانحراف عن C # في الحالات التي يبدو فيها نفس التركيب مناسبًا بشكل معقول ، وبالنسبة لي ، فإن الاقتراح المطروح - إلى جانب # 3240 - هو مثال على ذلك.

إذا تركنا لغات أخرى جانباً:

  • تمتد دلالات الدلالات الحالية لـ ? بشكل معقول إلى عوامل التشغيل المقترحة.

  • إذا رأيت قيمة في عوامل التشغيل _ المرتبطة_ التي يتم اقتراحها - نقع فارغ ( ?. ) ، ودمج فارغ ( ?? ) والتعيين الشرطي الفارغ ( ?= ) - ثم الاختيار لنموذج ثلاثي مطول مثل -then / -else ليس خيارًا ، إذا كنت تريد أن تعكس كل هذه العوامل ذات الصلة قواسم مشتركة (والتي من الواضح أنها تمتلكها من الناحية المفاهيمية).

كلما كانت الميزة أكثر غرابة ، زادت أهمية الإسهاب.

كلما زادت استخدام الميزة بشكل متكرر ، زادت أهمية الإيجاز. ولم يعد تجريد التمثيل القائم على الرمز مشكلة من خلال التعرض المتكرر للصيغة - تمامًا كما هو الحال مع * ، على سبيل المثال.

جميع المشغلين الذين تمت مناقشتهم لي يندرجون في الفئة الأخيرة.


RichardSiddaway @ :

استندت تعليقاتي حول $ psitem إلى تجربتي الشخصية. إذا كانت لديك تجربة مختلفة ، فهذا لا يبطل تجربتي

نعم ، استندت تعليقاتك إلى تجربة _ شخصية_.
اعتمد المنجم على "تحليل البيانات" من موقع Stack Overflow الشهير للأسئلة والأجوبة ، لاستنتاج أنماط الاستخدام العامة (ضمن القيود المذكورة) - وهو أمر لا علاقة له بتجربتي الشخصية.

السبب الوحيد الذي يجعلك تنظر إلى تعليقاتي على أنها تبطل تعليقاتك إذا كنت تعتقد أن ملاحظاتك الشخصية تعكس حقيقة "ما وراء الشخصية" - وهو ادعاء لم تقدمه على هذا النحو في تعليقاتك. هل قصدت أن تفعل ذلك؟ إذا كان الأمر كذلك ، فنحن بحاجة لمناقشة _that_.

جميع هؤلاء المشغلين تقريبًا هم عوامل حسابية ذات معنى مفهوم نسبيًا ، @ mklement0 😄

عامل التشغيل الثلاثي هو عامل شرطي ، و _ جميع_ عوامل التشغيل المنطقية / الشرطية الخاصة بـ PS هي من الصيغة الأكثر تفصيلاً: -and ، -or ، -eq ، -ne ، -contains ، إلخ.

أوافق على أن هذا الاختصار قد يكون منطقيًا نظرًا للحاجة إلى الميزات المحيطة والمشغلين ذوي الصلة. لكنني أعتقد أن بناء الجملة الثلاثي "القياسي" ليس بديهيًا بشكل خاص لأولئك منا الذين لم يتعرضوا لها بشكل متكرر بالفعل.

العوامل هي عوامل حسابية

من بين هؤلاء المدرجين ، فقط + - * / % له معنى رياضي (بحت) ، لكن الجانب المفهوم بوضوح ينطبق على الآخرين أيضًا (باستثناء = ، نظرًا لأنه غالبًا ما يتم الخلط بينه وبين اختبار المساواة ).

البناء الأفضل لمقارنة <condition> ? <if-true> : <else> به هو if _statement_ ، وليس عوامل التشغيل الأخرى. في حين أن if هو بالتأكيد أكثر إسهابًا ، إلا أن هذا الجانب هو بالضبط الذي تهدف العملية الثلاثية إلى معالجته (بالإضافة إلى كونه تعبيرًا حقيقيًا وقابلًا للإنشاء ، على عكس if ).

هناك طيف من الإيجاز ، بالتأكيد ، ولكن ، كما تقول ، لاستيعاب جميع العوامل ذات الصلة التي يتم اقتراحها بطريقة متسقة ، فإن بناء الجملة القائم على الرمز أمر منطقي.

لأولئك منا الذين لم يتعرضوا لها بشكل متكرر بالفعل.

حسنًا ، نأمل أن يتغير ذلك قريبًا. 😁
تم أخذ النقطة ، ولكن (أ) يمكن شرح بناء الجملة بسهولة وله نفس التعقيد المفاهيمي مثل عبارة if ، و (ب) يجب أن يساعد التعرض المتكرر في الاحتفاظ بالذاكرة.

@ mklement0 كيف تقترح معالجة ? أنه حرف اسم صالح؟ كسر التغيير؟ أنا أعتبر الأشخاص في باورشيل الأساسية على دراية جيدة بباويرشيل كما هي وأن بناء الجملة الإضافي (الذي كان موجودًا في لغات أخرى لما يقرب من 50 عامًا) لن يكون عائقًا. يمكنهم دائمًا استخدام if/else إذا كانوا يريدون المزيد من الإسهاب.

? ليس سوى اسم مستعار صالح في وضع الأوامر ؛ في جميع المتغيرات من وضع التعبير هو ببساطة حرف غير صالح في الوقت الحاضر. لا يوجد تصادم.

إذا حاولت إدخال هذا الرمز ، فسيظهر الخطأ ببساطة:

$Value = $true
$Value ? "Hello!" : "Goodbye!"

نتيجة:

At line:1 char:8
+ $Value ? "Hello!" : "Goodbye!"
+        ~
Unexpected token '?' in expression or statement.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken

ههههههههههه

$what? # <- example of a valid variable name

في مثاله المتبلور: $var?.maybenull() لا يهتم بوجود علامة استفهام هناك وإذا كان شخص ما يحاول الإفراط في التكثيف ، فسوف ينكسر الثلاثي.

عذرًا ، تمت مناقشة هذا الأمر بشكل أساسي في القضية الأخرى بشأن ذلك ، لذلك لم أكن أعتقد أنك كنت تشير إلى ذلك.

ما إذا كان بإمكاننا منع ذلك من كونه حرف اسم متغير صالحًا أم لا يعود لفريق PS ، لكنني أميل إلى الرأي القائل بأن منع اعتباره حرفًا متغيرًا بشكل افتراضي لن يكسر كثيرًا. لا أعتقد أنني رأيت أي شخص يستخدم ? كجزء من اسم متغير.

@ vexx32 نعم ، يجب أن أتحدث عن ذلك هناك. يمكن أن يكون لهذا تأثيرات إضافية إذا لم يكن حريصًا في تحديد النطاق أيضًا (على الرغم من أن هذا قد تم رؤيته بالفعل في توسعات السلسلة ، لذا يجب أن يكون الناس على دراية بها إلى حد ما):

$var = $test?$thing1:$thing2

لكنني قد أقوم بتقسيم الشعر كثيرًا على الحالات الحادة لأولئك منا الذين يعيشون في الصدفة.

مصحح:

$var = ${test}?${thing1}:$thing2

@ mklement0 - لا أتفق بالضرورة مع:

أفضل بناء للمقارنة؟:to هي عبارة if ، وليس عوامل التشغيل الأخرى. في حين أنه إذا كان بالتأكيد أكثر تفصيلاً ، فإن هذا هو بالضبط الجانب الذي تهدف العملية الثلاثية إلى معالجته (بالإضافة إلى كونه تعبيرًا حقيقيًا وقابلًا للإنشاء ، على عكس if).

على وجه التحديد ، يوجد عامل التشغيل الثلاثي لأن C / C # هي لغات موجهة للجمل ولكنها تحتاج إلى تعبيرات شرطية.

في اللغات الموجهة للتعبير (مثل F # أو Rust) ، لا توجد صياغة مقتضبة لأنها تعتبر غير ضرورية. أعتقد أن هذه المناقشة القديمة حول إزالة Rust للعامل الثلاثي مثيرة للاهتمام.

أحد الأشياء التي أحبه حقًا في Rust هو استخدام عامل التشغيل ? لمعالجة الأخطاء. ليس لدي اقتراح محدد لاستخدام ? في PowerShell ، ولكن يبدو أنه يمكن استخدام ? لمعالجة الأخطاء بشكل أفضل من استخدام التعبير الشرطي.

@ TheIncorreful1 ، @ vexx32 : نعم ، النقع بالقيم سيكون تقنيًا تغيير جذري ، ولكن نأمل أن يكون من النوع 3 (في الواقع ، دعنا نواصل المناقشة هناك) ؛ للعملية الثلاثية ، يبدو أن الاستخدام المقترح لـ {...} / مسافة بيضاء قبل ? لإزالة الغموض يحل هذه المشكلة.

lzybkr :

على وجه التحديد ، يوجد عامل التشغيل الثلاثي لأن C / C # هي لغات موجهة للجمل ولكنها تحتاج إلى تعبيرات شرطية.

حسنًا ، في عبارات التحكم في التدفق في PowerShell مثل if هي تعبيرات _half_؛ في تعبيرات _simple_ ، ستكون العملية الثلاثية المقترحة مكافئة ؛ في _تداخل_ ، لن:

$foo = $True  ?     1   :      0    # proposed ternary
$foo = if ($True) { 1 } else { 0 }  # equivalent `if` statement
$foo = 1 + ($True  ?     1   :      0)   # nesting OK; note that + would have higher precedence
$foo = 1 + if ($True) { 1 } else { 0 }  # !! doesn't work
$foo = 1 + (if ($True) { 1 } else { 0 })  # !! doesn't work, even with parentheses
$foo = 1 + $(if ($True) { 1 } else { 0 })  # only $(...) (and situationally @(...)) work

الحاجة إلى $() / @() هي أكثر من مجرد إزعاج في بناء الجملة: فهي تنطوي على آثار سلوكية وأداء.

ومع ذلك ، أتمنى أن تكون عبارات مثل if و foreach تعبيرات حسنة النية (مثالان آخران للأشياء التي فشلت حاليًا: foreach ($i in 1..5) { $i } | Write-Output أو foreach ($i in 1..5) { $i } > out.txt ).
لا أعرف ما يكفي للحكم على ما إذا كانوا _ لا يمكن أن يكونوا _ ، ومع ذلك و / أو ما إذا كان هناك مخاوف تتعلق بالتوافق مع الإصدارات السابقة.
أنظر أيضا: # 6817


إذا أصبح if تعبيرًا كاملاً في PowerShell ، فيمكنك حينئذٍ تقديم الحجة التي أدت إلى إزالة الشرط الثلاثي من Rust: إذًا لم يعد _ ضروريًا_.

ومع ذلك ، فإن حافزي لهذا الاقتراح لم يكن أبدًا _الضرورة_ - إنه يتعلق بالإيجاز والراحة وسهولة القراءة (الفوضى المرئية).


ليس لدي اقتراح محدد لاستخدامه؟ في PowerShell ، ولكن يبدو؟ يمكن استخدامها بشكل أفضل لمعالجة الأخطاء من التعبير الشرطي.

أعتقد أن تقديم ? بدلالات مختلفة اختلافًا جذريًا عن C # سيكون مصدر ارتباك دائم.

بشكل منفصل ، التحسينات في معالجة أخطاء PowerShell تستحق المناقشة.

إذا كنا نبحث عن بديل موجز ولكن غير بديهي لـ If / Then / Else ، فلدينا بالفعل بديل.

( 'False', 'True' )[( Test-Condition )]

وهي تعمل في التعبيرات.

"This statement is " + ( 'False', 'True' )[( Test-Condition )]

TimCurwick : هذا موجز (وأكثر غموضًا) ، لكنه ليس مكافئًا: سيكون الشرط الثلاثي المقترح _ short-circing_ (تمامًا مثل عبارة if ) ، بينما تقوم البنية بتقييم _ كلاهما _ بشكل ثابت.

ومع ذلك ، فإن بناء الجملة الخاص بك هو بالتأكيد ثاني أفضل شيء متاح حاليًا ، بافتراض أن المرء يدرك القيد المذكور.

فيما يتعلق بمناقشة كيفية عرض الخيارات الثلاثية في PowerShell ، هل فكر أي شخص في خيار بنفس التنسيق المستخدم بواسطة -replace / .replace() ؟

$a -eq $b -ternary $a,$c
$true -ternary 1,0

أو

($a -eq $b).ternary($a,$c)
($true).ternary(1,0)

هذا من شأنه أن يوضح أن المشغل يقوم بعمل ثلاثي من خلال تسميته حرفياً بالثالث . إنه مطول ، لكنه لا يزال قصيرًا للكتابة ، ويستفيد من السلوك الشائع الحالي -operator $first,$second ، لذلك يجب أن يكون مألوفًا لمستخدمي powerhell عبر جميع نطاقات الخبرة

🤔 قد ينجح ، لكنه سيكون أكثر صعوبة من أي من البدائل المقترحة. -replace بهذه الطريقة لأنه يقبل فقط مصفوفة فعلية من الوسائط. .Replace() غير مُدار بواسطة فريق PS - إنها طريقة في فئة .NET System.String .

إذا حاولنا استخدام أيٍّ من هذه التركيبات ، فذلك يعني إما طريقة ETS (وهو أمر جيد ، ولكنه يميل إلى إضافة القليل من الأداء إلى إنشاء الكائنات التي يجب إرفاقها بها) أو ، مع إصدار المشغل تقترح ، لن نتمكن من الحصول على مصفوفة كوسيطة بسهولة.

بدون غلاف خاص مثل هذا المشغل في المحلل اللغوي ، لن نتمكن من قصر الدائرة. توجد الصيغ الثلاثية في اللغات الأخرى عمومًا لأنك _ لا تريد_ تقييم كلا الخيارين فعليًا ؛ يكون وقت الحوسبة أسرع إذا احتاج فقط الفرع الصحيح إلى التقييم ، بدلاً من الاضطرار إلى التقييم الكامل لكلا الخيارين (والذي قد يأتي مع بعض الآثار الجانبية الهامة).

ونظرًا لأن هذا سيتطلب غلافًا خاصًا بالفعل ، فسيكون من الأكثر فاعلية إدخال صياغة جديدة له ، لتقليل الارتباك (سيكون من المضلل بعض الشيء أن يكون لديك شيء يشبه المصفوفة ولكن لا يمكن استخدامه مثل واحد ؛ لن يدعم إنشاء "المصفوفة" مسبقًا وتمريرها كمتغير ، على سبيل المثال). حقيقة أن وسيطات الأسلوب تتعارض بالفعل قليلاً مع بناء جملة المصفوفات مضللة بالفعل. لا أعتقد أنني أرغب في إضافة سلوك متغير ثالث للفاصلات إلى المزيج.

@ PowerShell / بوويرشيل-جنة ناقشت هذا مطولاً ، نحن لا نتفق جميعًا ، لكن الأغلبية توافق على أن هناك قيمة في وجود هذا المشغل وللتوافق مع بناء جملة C # مع الحفاظ على ?: كما هو متوقع هو أن معظم الاستخدام سوف تكون من مطوري C #. ستكون هذه الميزة بمثابة تعليقات تجريبية معلقة للاستخدام الحقيقي.

@ SteveL-MSFT وهذا يعني أن الميزة تمضي قدما ل 7.0؟ هل ستؤدي إلى كسر التوافق على المتغيرات لتكون قادرة على استخدام ? في رمزها؟

@ TheIncorreful1 نعم ، هذه الميزة تمضي قدمًا في PS7. يجب ألا يكسر التوافق مع استخدام الاسم المستعار ? . هناك قلق بشأن حدة البصر عند ? عند إلقاء نظرة خاطفة على نص يحاول التفريق بين Where-Object و ternary ، لكننا سنرى ملاحظات المستخدم على هذا. بشكل عام ، لا نتوقع أن يستخدم معظم المستخدمين هذا المشغل ولكن هذا لا ينبغي أن يمنعه من المضي قدمًا.

@ SteveL-MSFT أعني متغيرات باسم $isValid? أو ما شابه. هذه رموز صالحة في التكرار الحالي لـ PS.

@ TheIncorreful1 :

يؤدي طلب مسافة بيضاء بين المعامل الأول و ? حل هذه المشكلة ، كما اقترح سابقًا ، وهو بالنسبة لي حل معقول تمامًا:

  • يتطلب : _also_ مسافة بيضاء حوله ، لأن شيئًا مثل $true ? $number:42 لن يعمل ، نظرًا لأن $number:42 _ ككل_ سيتم تفسيره كمرجع متغير واحد.

  • بينما تسمح C # _does_ true?number:42 ، لا أعتقد أننا بحاجة إلى - أو ، في الواقع ، يمكن - القلق بشأن التوافق عند هذا المستوى. أنا شخصيا أقدر الإيجاز ، ولكن ليس على حساب سهولة القراءة ؛ حتى لو كنت أستطيع أن أكتب $true?$number:42 ، فلن أفعل.

(سيكون التوافق مع الإصدارات السابقة مشكلة بالفعل عندما (تلميح ، تلميح) ننفذ وصولًا مشروطًا . إن سماح PowerShell فيما يتعلق بأسماء المعرفات يمثل مشكلة بشكل عام ، كما جادلKirkMunro مؤخرًا ، لكن تلك السفينة أبحرت )

نعم ، أعتقد أن ترك متطلب المسافة البيضاء أمر منطقي. إنه مقتضب بما فيه الكفاية ، بعد كل شيء. 😁

حاول النموذج الأولي بجد تحليل الأرقام باستخدام ? و : فيها بشكل مختلف في سياق المشغل الثلاثي (حيث نعلم أننا نتوقع تعبيرًا). لذا يمكنك كتابة أشياء مثل ${isWindows}?12:47 .
يتم ترميز الأرقام مثل 123? أو 1:23 كرمز عام اليوم ، وهو أمر غير مفيد على الإطلاق في الحالة التي نعلم أننا نتوقع فيها تعبيرًا.

بالنسبة للمتغيرات ، لا يوجد تغيير على الإطلاق لكيفية استخدام ? أو : لاسم المتغير ، نظرًا لأن المتغير هو تعبير.

نقطة جيدة ، @ daxian-dbw ؛ لقد نسيت أنه يمكن استخدام {...} لحل أي غموض في حدود الأسماء المتغيرة ، لذلك أعتقد أن لاعبي الغولف يمكنهم استخدام شيء مثل ${isWindows}?${number}:47

هل يمكننا إغلاق هذا الآن؟

أغلق عبر # 10367

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات