Powershell: لا تطلب {...} حول أسماء المتغيرات من أجل وصول عضو مشروط فارغ

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

متابعة من # 3240.

تم تنفيذ الوصول غير المشروط للعضو ( ?. ) وسيكون متاحًا كميزة _experimental_ في 7.0

ومع ذلك ، من أجل التوافق مع الإصدارات السابقة ، يتطلب التنفيذ حاليًا تضمين اسم المتغير في {...} ، لأن ? من الناحية الفنية هو حرف قانوني في اسم متغير يستخدم بشكل مفاجئ _ لا يتطلب_ {...} .

أي ، إذا كنت تريد تجاهل محاولة استدعاء $obj.Method() إذا كان $obj هو $null (أو غير محدد) ، فستتوقع ما يلي ، مشابه لـ C #:

# Does NOT work as intended.
# 'obj?' as a whole is interpreted as the variable name.
$obj?.Method()

بدلاً من ذلك ، يجب عليك حاليًا استخدام:

# !! Must enclose 'obj' in {...} to signal that '?' is a syntactic element as part of '?.'
${obj}?.Method()

_Update_: الاندماج الفارغ - $var??='default و $a??$b - والعامل الثلاثي - $var?1:0 - يتأثر بالمثل (على الرغم من استخدام المسافة البيضاء قبل ? يحل المشكلة).

هذا المطلب (أ) غير متوقع و (ب) مرهق:

  • لن يتوقع المستخدمون الجدد الحاجة إلى {...} ولن يعلموا بالضرورة أن _it_ هو المطلوب عند فشل التالي (ربما _ غير مكتشف_ ، ما لم يكن Set-StrictMode -Version 2 أو أعلى ساريًا): $o = [pscustomobject] @{ one = 1 }; $o?.one

  • حتى بمجرد أن يعرف المستخدمون _do_ بالحاجة إلى {...} :

    • سوف ينسون استخدامه في بعض الأحيان ، بسبب الحاجة غير البديهية إليه.
    • عندما يتذكرون ، سيكون هذا المطلب المصطنع على ما يبدو مصدرًا مستمرًا للإحباط ، خاصة وأن كتابة {...} يصعب كتابتها.

لا ينبغي أن يكون استخدام {...} ضروريًا ، وبينما لا يتطلب الأمر تغييرًا فاصلاً ، يمكن القول إنه يقع في المجموعة 3: المنطقة الرمادية غير المحتملة .


لماذا يجب اعتبار هذا التغيير مقبولاً:

ملاحظة: يناقش rjmholt سبب كون تغيير بنية PowerShell إشكالية للغاية _ بشكل عام_ في هذا التعليق ، ولكن للأسباب المعروضة أدناه ، أعتقد أنه من المفيد إجراء استثناء هنا.

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

نعم ، قد يتعطل تفسير $var?.foo في البرامج النصية القديمة التي تستخدم $var? كاسم متغير ، ولكن:

  • لم يكن مسموحًا أبدًا بالسماح لـ ? كجزء من المعرف _ بدون تضمينه في {...} _.

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

    • حتى Ruby لا تسمح إلا بـ ?! ) عند _ نهاية_ المعرفات ، وهناك فقط معرفات _method_ ، وأظن أن معظم مستخدمي Ruby يدركون أنه يجب _لا يفترضوا أن اللغات الأخرى تدعم نفس الشيء.

إذن ، من الناحية البراغماتية:

  • لن تتأثر الغالبية العظمى من الكود الحالي - لن يتم العثور على رمز مثل $var?.foo ببساطة.

  • إذا كتبت $var?.foo مع الدلالات الجديدة ، فعندئذ نعم ، قد يؤدي تشغيل ذلك في الإصدارات الأقدم إلى سلوك مختلف (بدلاً من الانهيار بطريقة واضحة) ، اعتمادًا على ماهية الوضع المتشدد - ولكن _ يجب عليك دائمًا فرض الحد الأدنى من الإصدار المطلوب لتشغيل التعليمات البرمجية على النحو المنشود على أي حال_ ( #requires -Version ، module-manifest keys).

بشكل عام ، هذه حالة واضحة لتغيير دلو 3: تغيير تقني يكسر القليل جدًا من التعليمات البرمجية الحالية مع تقديم فوائد حقيقية (أو ، على العكس من ذلك ، تجنب الصداع الدائم بسبب السلوك غير المتوقع).

Committee-Reviewed Issue-Enhancement WG-Language

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

rjmholt ، بينما أعتقد أنه يمكننا جميعًا تقدير مدى صعوبة تغيير مثل هذا _ من حيث المبدأ_ ، في هذه الحالة بالذات لا يهم _ في الممارسة_ ، ولا أعتقد أن هناك حاجة حتى لقاعدة PSSA:

  • أظهر تحليل أنه - إذا اعتقدنا أن المجموعة تمثل جميع أكواد PowerShell الموجودة هناك - فلا أحد يستخدم تقريبًا متغيرات بأسماء تنتهي بـ ? _.

  • إذا كنت سأخمن ، فإن معظم الناس لن يفكروا حتى في استخدام مثل هذه الأسماء المتغيرة ، لأنهم لن يتوقعوا منهم أن يعملوا (بما في ذلك أنا) ، وربما لا يلاحظون حتى الاستثناء المتمثل في $? التلقائي المتغير bash ).

    • في الواقع ، عند النظر عن كثب إلى تحليل ThomasNieto يكشف أنه من بين الملفات 8 المدرجة:

      • 5 فقط على _إيجابيات خاطئة_ ، وهي استخدامات المتغيرات داخل _ سلاسل_ مثل "Are you sure you want to kill $vParam?" - في الواقع ، هذه الاستخدامات هي _broken_ ، وتكشف أن مؤلفي النص _ لا_ يتوقعون ? ليكون كذلك جزء من اسم المتغير.

      • 2 من هذه الملفات متاحة للجمهور.

      • فقط _1_ منها هو استخدام حسن النية لمتغيرات ? -ending - كمتغيرات منطقية (على سبيل المثال ، $key1? ) ، والتي ، على سبيل المثال ، لا يتم دمجها مع عامل وصول الأعضاء ، . / ccstevenayers.

بناءً على ما سبق ، يبدو لي هذا بمثابة كتاب مدرسي دلو 3: تغيير

_ التوثيق_ يجب أن يكون التغيير في السلوك (مع وجود مبرر) كافياً.

بالطبع:

  1. هذا يعتمد على (أ) التحليل صحيح و (ب) المجموعة المتاحة للجمهور تمثيلية.

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

انطلاقًا من افتراض أن 1. صحيح (لم نسمع أي شيء يدعمه 2.) ، لدينا خياران:

  • انزع أداة المساعدة اللاصقة وامنع ? في أسماء المتغيرات من الآن فصاعدًا ، ما لم تكن مضمنة في {...} (مع استثناء واضح وهو $? ) - سيؤدي هذا إلى كسر الصغر المتلاشي نسبة النصوص التي تعتمد على ذلك حاليًا.

    • أي شيء مثل $key1? لا يتبعه . ولا آخر ? ( $key1??'else' ) ولا تعبير ثلاثي ( $key1?1:0 ) قد يتسبب في خطأ _parser_.

      • كما تظهر أمثلة عامل التوحيد الصفري والثالث ، فإنها ستستفيد أيضًا من هذا التغيير - حاليًا ، تحتاج إما إلى _space_ - $key1 ?1:0 / $key1 ??'else' - أو {...} - ${key1}?1:0 / ${key1}??'else'

    • داخل _ السلاسل القابلة للتوسيع_ ، لن يتم اعتبار ? بعد ذلك جزءًا من اسم متغير (non- {...} -enclosed) ، لذلك سنقوم بالفعل _fix_ بالبرامج النصية الحالية التي استخدمت سلاسل مثل "Are you sure you want to kill $vParam?" بالخطأ
  • إذا شعرنا حقًا أننا بحاجة إلى تجنب كسر النسبة الصغيرة المتلاشية من البرامج النصية الحالية ، فيمكننا أن نفكر في المنطق الذي اقترحه @ ExE-Boss ، لكنني لا أعتقد أننا نريد تقديم هذا التعقيد المفاهيمي - ناهيك عن تعقيد التنفيذ (الذي أنا لا أستطيع التحدث إلى).

ال 53 كومينتر

للتوضيح ، فإن المعلم يعني فقط أنه شيء يجب على الفريق مناقشته بناءً على التعليقات ، وليس أننا ملتزمون بإجراء هذا التغيير.

ههههههههههه

؟ لم يكن مسموحًا به أبدًا كجزء من معرّف بدون تضمينه في {...}.

Ummm - كانت اللغة الأساسية الأولية لـ PowerShell هي Posix Shell التي تستخدم $؟ لرمز الخروج qed "؟" مسموح به في أسماء المتغيرات غير المقتبسة.

لا يمكن (بشكل هادف) العمل على الإصدارات الأقدم

بالتأكيد يمكنه:

PS>  $abc?=@{a=1; b=2; c=3}
PS>  $abc?.b                                                                                        1
PS>  2                      

بالتأكيد يمكنه:

لا يمكن أن يعمل بشكل هادف _ مع الدلالات الجديدة_ (وصول مشروط فارغ) - هذا كل ما قصدت قوله.

نعم ، يعمل المثال الخاص بك حاليًا ، ولكن _ مع دلالات مختلفة_ ( abc? _ بما في ذلك ? _ يعتبر اسمًا متغيرًا) - ولكن للأسباب المذكورة ، فإن حالة الركن هذه تستحق التخلي عنها من أجل صنعها ?. كما هو متوقع.

كانت اللغة الأساسية الأولية لـ PowerShell هي Posix Shell التي تستخدم $? لكود الخروج

$? هو _استثناء_ في قذائف تشبه POSIX ؛ لا يمكنك القيام بما يلي:

# bash, ksh, zsh, dash (all common /bin/sh implementations)
foo?='bar' # BOOM! E.g. "bash: foo?=bar: command not found"

(ومن الواضح أن لا أحد يطلب إلغاء $? في PowerShell.)

وبطبيعة الحال ، يجب الإشارة إلى أن _ جميع المتغيرات التلقائية الأخرى في نفس المساحة مثل $? (على سبيل المثال ، $^ و $$ ) خاصة بشكل صريح- مغلف في الرمز المميز. وفي واقع الأمر ، كذلك هو $? ، على الرغم من أنه (حاليًا) لا يلزم أن يكون كذلك.

يبدو واضحًا بالنسبة لي أنه كان متوقعًا في الوقت الذي تمت فيه كتابة هذا الرمز أن ? لن يكون حرفًا معرفًا صالحًا.

أعرف فقط شخصًا واحدًا استخدم ? في نهاية أسماء المتغيرات في نصوصه ، وهذا هوStartAutomating. نظرًا لأنه استخدم بالفعل هذا النحو ، فقد اعتقدت أنه من المفيد لفت انتباهه إلى هذه المناقشة.

أيضًا @ vexx32 ، السبب في أن $? هو غلاف خاص في الرمز المميز لأنه لا يمكنك إنشاء متغير باسم يبدأ بـ ? . على سبيل المثال ، لن يتم تحليل $??? = 'foo' . يجب أن تبدأ أسماء المتغيرات بأحرف أبجدية رقمية أو شرطة سفلية ، ويمكن أن تحتوي حاليًا على أحرف أبجدية رقمية أو شرطات سفلية أو علامات استفهام. أنا أوافق على أنه يجب تحليل ?. كمعامل وصول للعضو الخالي ، لكنني أردت توضيح سبب وجود غلاف خاص في الرمز المميز ? .

شكرا لجذب انتباهي لهذه الدردشة.

لما يستحق ، لدي بعض الأفكار:

  1. في حين أن هذه المتغيرات نادرة ، لا أحد يريد أن يلعب لعبة whack-a-mole عندما يكسر المتوافق الخلفي نصوصه
  2. بغض النظر عن الأشخاص العبقري غريب الأطوار ، أتوقع أن $ {obj} ؟. الطريقة () أو $ obj؟. الطريقة () ستزداد قليلاً. هناك عقد من الإرشادات على الويب حول كيفية إدارة القيم الخالية هناك ، ولا أرى الكثير من الأشخاص يتحولون من if ($ obj) {$ obj.Method ()} _ فقط للحصول على عربة الإصدار 7_
  3. بالإضافة إلى ذلك ، يتعلم معظم الأشخاص الذين يواجهون مشكلات مع أسماء المتغيرات غير المتوقعة بناء الجملة $ {} (كنت تضغط عليها بالفعل بشكل طبيعي بشرطة سفلية). أتوقع أن يكون تداخل مخطط Venn لـ "الأشخاص الذين يريدون استخدام هذه الميزة" مع "الأشخاص الذين يعرفون بنية $ {} بالفعل" قريبًا من 100٪
  4. نظرًا لأن بناء الجملة المذكور ليس قويًا مثل التعبير الجزئي الكامل ، وتعمل التعبيرات الجزئية الكاملة في الجوهر وليس كذلك ، أتوقع أن يستمر معظم الناس في استخدام هذا في المستقبل.

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

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

أقترح القيام بذلك حتى يعمل $obj?.Method() كـ $<var i="6">obj</var> ?. <var i="9">Method</var>() بشكل افتراضي ، ويعود فقط إلى $<var i="11">obj?</var> . <var i="14">Method</var>() عندما لا يكون $obj موجودًا في النطاق ، لكن $obj? موجود و #requires ‑Version ليس الإصدار 7 +.

@ ExE-Boss ، يبدو أن هناك الكثير من الاستثناءات لعمل هذه القاعدة بالذات.

أكرر سؤالي عن قيمة هذه القاعدة بالذات.

بعد ذلك ، كان السؤال هو "ما الذي لا نعرفه أيضًا عن التركيب المتغير الذي يمكننا كسره؟"

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

بما أننا نعيد الصياغة هنا:
"المنطق يفرض بوضوح أن احتياجات الكثيرين تفوق احتياجات القلة". - سبوك

لذا ، عند إجراء العمليات الحسابية ، هناك عدة أسباب ملموسة - عدم - للقيام بذلك ، وسبب واحد غامض للقيام بذلك (قد يكون أسهل ، بالنسبة لبعض المستخدمين).

StartAutomating : هناك عدة أسباب ، وهي ملموسة وليست غامضة. أيضًا ، أحد أهداف هذا هو بساطة الكود. الحاجة إلى التفاف الأسماء المتغيرة بـ {} تعمل مباشرة ضد هذا الهدف.

أنا مع @ mklement0 و KirkMunro في هذا الشأن. أنا شخصياً أجد أن بناء الجملة ${...}? معقد غير طبيعي وغير ضروري. لقد أجرينا تغييرات خاطفة بالفعل وفي هذه الحالة يكون الثمن زهيدًا مقابل الوضوح.

تضمين التغريدة

  1. بالإضافة إلى ذلك ، يتعلم معظم الأشخاص الذين يواجهون مشكلات مع أسماء المتغيرات غير المتوقعة بناء الجملة $ {} ( كنت تضغط عليها بالفعل بشكل طبيعي بشرطة سفلية ). أتوقع أن يكون تداخل مخطط Venn لـ "الأشخاص الذين يريدون استخدام هذه الميزة" مع "الأشخاص الذين يعرفون بنية $ {} بالفعل" قريبًا من 100٪

هذا لا يصمد. الشرطات السفلية هي أحرف صالحة في أسماء المتغيرات.

ههههههههههه

يبدو واضحًا لي أنه كان متوقعًا في وقت كتابة هذا الرمز

لا.

تبديل الأحرف حولها؟ $foo.?Property غير متعارض ، لأن أسماء الخصائص التي تبدأ بعلامات الأسئلة تحتاج إلى الاقتباس بالفعل:

PS C:\> $foo = [pscustomobject]@{'?'=1; '?name'=2}
PS C:\> $foo.?name
At line:1 char:6
+ $foo.?name
+      ~
Missing property name after reference operator.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingPropertyName
PS C:\> $foo.'?name'
2

HumanEquivalentUnit ، لسوء الحظ ، قد يؤدي ذلك إلى ارتباك القديم ?. المستخدم في C # والعديد من اللغات الأخرى (أيضًا ، ستحتاج إلى العثور على نموذج بديل للمفهرس ( ${arr}?[0] ) أيضًا ، وشيء مثل $arr[0]? قد يدعو إلى الارتباك مع عامل التشغيل الثلاثي)

لا يوجد حل أنيق.

  1. يستخدم عدد غير معروف من الناس؟ في نهاية أسماء المتغيرات. في حين أنها ميزة اختيارية ، يمكن للمرء أن يقول "لا تقم بتشغيلها إذا قمت بتشغيل تلك البرامج النصية" ولكن يجب على الشخص الذي يديرها التحقق من البرامج النصية الحالية والمستقبلية التي يحصل عليها من أي مصدر.
  2. بناء الجملة البديل ليس خيارًا رائعًا لأنه يستورد شيئًا ليس شديد القوة من C #
  3. لا يعمل تغيير السلوك بناءً على #requires خارج البرنامج النصي المحفوظ ، وسيفشل بمجرد قيام شخص ما بنسخ بعض التعليمات البرمجية من برنامج نصي طويل دون تعيين العلامة.
    4. يوضح (dir *.ps2)?.count و (dir *.ps1)?.count أن المعامل لا يحتاج إلى أن يكون متغيرًا.
    يزيل ($Host)?.toString() / ($null)?.toString() الحاجة إلى وضع الأقواس حول الاسم. لا يزال الأمر عبارة عن ضغطات إضافية على المفاتيح ، لكنها أكثر منطقية وأقل بشاعة.
  1. لا يعمل تغيير السلوك بناءً على #requires خارج البرنامج النصي المحفوظ ، وسيفشل بمجرد قيام شخص ما بنسخ بعض التعليمات البرمجية من برنامج نصي طويل دون تعيين العلامة.

ينطبق هذا على أي رمز يستخدم ميزات غير مدعومة في الإصدارات السابقة.
إذا كان هذا هو الشغل الشاغل ، فلن يتم تقديم أي ميزة لغة جديدة أو معلمة cmdlet / cmdlet جديدة.

(نأمل أن يكون لديك في الكود الأقدم ما لا يقل عن Set-StrictMode -Version 1 ساري المفعول ، وفي هذه الحالة سيفشل $var?.foo بصوت عالٍ ، بسبب عدم وجود متغير اسمه var? موجود).

  1. يزيل الحاجة إلى وضع الأقواس حول الاسم.

استبدال (...) بـ {...} هو تحسن هامشي فقط.

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

  1. لا يعمل تغيير السلوك بناءً على #requires خارج البرنامج النصي المحفوظ ، وسيفشل بمجرد قيام شخص ما بنسخ بعض التعليمات البرمجية من برنامج نصي طويل دون تعيين العلامة.

ينطبق هذا على أي رمز يستخدم ميزات غير مدعومة في الإصدارات السابقة.
إذا كان هذا هو الشغل الشاغل ، فلن يتم تقديم أي ميزة لغة جديدة أو معلمة cmdlet / cmdlet جديدة.

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

(نأمل أن يكون لديك في الكود الأقدم ما لا يقل عن Set-StrictMode -Version 1 ساري المفعول ، وفي هذه الحالة سيفشل $var?.foo بصوت عالٍ ، بسبب عدم وجود متغير اسمه var? موجود).

في تجربتي لا يستخدم الكثير من وضع Strictmode. لأن (أ) هناك افتراض بأن التقصير بدونه يكون "صحيحًا" و (ب) تكرار استخدام الأشياء التي تعتمد على إيقاف تشغيله مرتفع للغاية. إنه استخدام شائع لهؤلاء المشغلين. على أي حال فإن المشكلة تكمن في الكود الأقدم حيث $ var؟ موجود ولديه خاصية foo ، ولكن الآن الكود يبحث عن $ var ... من المحتمل أن تتسبب المعالجة الجديدة في حدوث خطأ إذا تم تعيين وضع صارم لأن $ var غير موجود ....

  1. يزيل الحاجة إلى وضع الأقواس حول الاسم.

استبدال (...) بـ {...} هو تحسن هامشي فقط.

نعم فعلا. ($ x) أفضل قليلاً من $ {x} ولكن بشكل طفيف فقط. ( Get-user "Bob")?.disable() أفضل من

$u = get-user "bob" 
($u)?.disable

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

نعم فعلا.
$var. foo مع أعمال المساحات البيضاء. ${foo} ?.bar() ليس بسبب؟ مسموح به في وظيفة أو اسم مستعار (؟. قانوني لكليهما). ربط أجزاء من بناء جملة C # في قواعد بناء الجملة الحالية دون كسر الأشياء ليس عمليًا دائمًا في بعض الأحيان ، "هذا متاح في C # ..." يستحق حقًا الإجابة "نعم. أنت تعرف مكان C # إذا كنت تريد ذلك".
:-)

للحفاظ على توافق SemVer ، يجب القيام بذلك في إصدار رئيسي (يفضل 7.0.0 ).

انظر أيضًا اقتراحي أعلاه ( https://github.com/PowerShell/PowerShell/issues/11379#issuecomment-566756120 ).

@ ExE-Boss نعم ، كان تعليقك الذي كنت أشير إليه عندما قلت أن اعتمادًا على #requires قد لا يكون الفكرة الجيدة التي يبدو عليها في البداية.
ونعم ، إذا كان على المرء كسر أي نصوص موجودة ، فإن وقت القيام بذلك هو عندما يتغير الإصدار الرئيسي ، لذلك يجب القيام بذلك بسرعة أو انتظار V8

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

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

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

StartAutomating قال:

بغض النظر عن الأشخاص العبقري غريب الأطوار ، أتوقع أن $ {obj} ؟. الطريقة () أو $ obj؟. الطريقة () ستزداد قليلاً. هناك عقد من الإرشادات على الويب حول كيفية إدارة القيم الخالية هناك ، ولا أرى الكثير من الأشخاص يتحولون من if ($ obj) {$ obj.Method ()} فقط للانضمام إلى الإصدار 7 من عربة

أنا فقط n = 1 ، لكن بصفتي مطورًا غير PowerShell ، فأنا أعارض بشدة. الجديد ؟ بناء الجملة هو شيء أود أن أكتشف عنه بسرعة كبيرة حتى كشخص يلمس PowerShell ربما مرة كل بضعة أشهر ، ومن المؤكد أنه سيزيد من احتمالات استخدام PowerShell في المستقبل بدلاً من البدائل. إذا رأيت بعد ذلك أن بعض البنية المجنونة {} مطلوبة للتوافق مع الإصدارات السابقة ، فسأحرك عيني وأعود إلى ما كنت أستخدمه بالفعل.

لا أفهم هنا التركيز على التوافق مع الإصدارات السابقة. قام PowerShell Core بالفعل بكسر معظم البرامج النصية الحالية الخاصة بي لأنها استخدمت أجزاء من .NET ليست في .NET Core. (أنا لا أشكو من ذلك - إن .NET Core رائع ، ولكن إذا كنت ستفكك التوافق مع الإصدارات السابقة ، فهذه فرصتك الآن.)

أولاً ، أعتقد أن ملاحظاتي الأولية قد أحدثت خلافًا في سوء الفهم.

كان من المفترض أن $ {} لن يكون _ هذا غريبًا بالنسبة لمطوري PowerShell_ ، لأنهم سيضطرون بالفعل إلى معرفة صيغة بناء الجملة هذه إذا قاموا بتضمين متغير مع؟ أو وشرطة سفلية في سلسلة.

نشكرك على التذكيرات العديدة بأن بناء الجملة هذا قد يكون محرجًا لمطوري غير PowerShell.

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

يبدو أن الجزء الثالث من ملاحظاتي قد تم تضخيمه بشكل مبالغ فيه. يتحدث كأحد الأشخاص الذين استخدموا أحيانًا متغيرات تسمى $ IsThisRight؟ = Test-Something ، كان رد فعلي الأول على سماع الأخبار المحتملة حول هذا التقييد المتغير هو "حسنًا ، أعتقد أنه سيتعين علي إعادة تسمية بعض المتغيرات ، لم أحصل على الكثير من أجل ذلك على أي حال."

لذلك ، لمحاولة إعادة صياغة الموضوع وإنهائه:

  1. ربما لن تكون IMHO ، $ {} غريبة من بناء الجملة لمطوري PowerShell _existing_
  2. نرحب بك للاعتقاد بأن هذه الميزة رائعة ؛ بالنسبة لي ، إنه دواء بوابة الإلمام باللغة ، وأنا أوصي بشدة أن يقرأ كل شخص هذا الموضوع ويتعلم كيفية تخصيص ifs / foreaches / whiles وما إلى ذلك.
  3. كواحد من المؤلفين المتأثرين ، لا أحصل على شيء مهم جدًا من a؟ في نهاية المتغيرات الخاصة بي التي سأعارض تغيير الكود الخاص بي.

أو لأكون قصيرًا للغاية:

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

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

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

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

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

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

يبدو أن الجزء الثالث من ملاحظاتي قد تم تضخيمه بشكل مبالغ فيه. يتحدث كأحد الأشخاص الذين استخدموا أحيانًا متغيرات تسمى $ IsThisRight؟ = Test-Something ، كان رد فعلي الأول على سماع الأخبار المحتملة حول هذا التقييد المتغير هو "حسنًا ، أعتقد أنه سيتعين علي إعادة تسمية بعض المتغيرات ، لم أحصل على الكثير من أجل ذلك على أي حال."

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

في سيناريو تحاول فيه استهداف مجموعة سكانية جديدة بالكامل - أي مطورين لا يركزون على Windows - قد يكون من الضروري إجراء بعض التغييرات العاجلة للتنافس مع ما هو موجود بالفعل.

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

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

شخصيًا ، يعد السكر النحوي مشكلة كبيرة بالنسبة لي عندما أختار لغة لأقوم بمهمة معينة

إذن فقد وصلت إلى اللغة الصحيحة! يعتبر PowerShell عبارة عن كيس مقدس إيجابي مع السكر النحوي.

لتثقيف أولئك الذين لا يعرفون ، يمكنك "null Coalese" بعدة طرق في PowerShell:
~$ ListWhereNotNull = $ null، 1، 2، $ null، 3 -ne $ null # سيتحقق هذا من أن كل عنصر ليس فارغًا ويعيد قائمة من 1،2،3$ FirstNonNull = @ ($ null، 1، $ null، 2 -ne $ null) [0] # سيؤدي هذا إلى إرجاع أول قيمة غير خالية$ lastNonNull = @ ($ null، 1، 2، $ null -ne $ null) [- 1] # هذا سيعيد آخر غير فارغ ، باستخدام فهرس سالب$ TheObjectPipelineWay = $ فارغ ، 1 ، $ فارغ ، 2 | حدد الكائن - أولاً 1$ TheAssigningForeachWay = foreach ($ item in $ null، 1، 2، $ null، 3، 4) {إذا ($ item -ne $ null) {$ item؛



هذا كافٍ في الوقت الحالي ، لكن يجب أن يثبت النقطة المتعلقة بمرونة كبيرة في بناء جملة اللغة. ستعمل كل هذه العروض التوضيحية على طول الطريق إلى PowerShell 1.0

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

في هذا أنت غير صحيح. يحتوي Core في الواقع على عدد قليل جدًا من التغييرات في بناء الجملة ، والمزيد من الوحدات النمطية أكثر مما تعتقد أنها تعمل بشكل جيد على النواة (+ - بعض المشكلات مع Linux vs Windows pathing / newlines). من الناحية العملية ، من غير المرجح أن تعمل الوحدة النمطية الخاصة بك على Core إذا كان لديك نوع من التبعية الخاصة بواجهة برمجة التطبيقات (API) الخاصة بمنصة Windows (على سبيل المثال ، لن أحبس أنفاسي لتشغيل أغلفة WPF الخاصة بي على Linux).

ما زلت على ما يرام في كلتا الحالتين مع تغيير بناء الجملة: لقد شعرت للتو أن اثنين من التأكيدات في الرد الأخير بحاجة إلى المعالجة والاستدعاء.

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

StartAutomating : هل تقول إنني لا أستطيع التصوير؟ لأنه لا يزال هناك مكان لمزيد من السكر على ما أعتقد

لتثقيف أولئك الذين لا يعرفون ، يمكنك "null Coalese" بعدة طرق في PowerShell:

لقد اكتشفت ذلك (هذا هو جوابي الخاص الذي كتبته) ، لكنه شعرت وكأنه خدعة. إنها فكرة رائعة مع الكثير من الإمكانات ، ولكن كما أشار أحد المعلقين على إجابة Stack Overflow ، فإن التقييم لا يقصر. يعني عامل التشغيل ?. أن هذا لم يعد مشكلة في العادة عند تسلسل المكالمات / الخصائص. مرة أخرى في عام 2013 ، على الرغم من ذلك ، لم يكن متاحًا - وحتى ذلك الحين ، هناك الكثير مما يحدث في هذه الأمثلة ، ويمكنك أن ترى في التعليقات كيف وجد الناس ذلك محيرًا. كان عليّ أن أفصل بالضبط ما تفعله هذه الأمثلة رمزًا برمز.

في هذا أنت غير صحيح. يحتوي Core في الواقع على عدد قليل جدًا من التغييرات في بناء الجملة ، والمزيد من الوحدات النمطية أكثر مما تعتقد أنها تعمل بشكل جيد على النواة (+ - بعض المشكلات مع Linux vs Windows pathing / newlines). من الناحية العملية ، من غير المرجح أن تعمل الوحدة النمطية الخاصة بك على Core إذا كان لديك نوع من التبعية الخاصة بواجهة برمجة التطبيقات (API) الخاصة بمنصة Windows (على سبيل المثال ، لن أحبس أنفاسي لتشغيل أغلفة WPF الخاصة بي على Linux).

أنا أتحدث فقط من تجربة في هذا الصدد ، بدلاً من المرور وجمع الإحصائيات المناسبة. على سبيل المثال ، ما قبل النواة ، يمكنني إنشاء كلمة مرور باستخدام [System.Web.Security.Membership]::GeneratePassword(32, 6) ، لكن System.Web غير متوفر في Core. (أعلم أنه يمكنني على الأرجح تحميل ملف System.Web.dll القديم ، لكنني أفضل عدم القيام بذلك إذا لم أضطر إلى ذلك.) من الأسهل بالنسبة لي في الواقع حل التغييرات النحوية من واجهات برمجة التطبيقات المفقودة. يبدو إنشاء مجموعة من أسرار Docker لـ devkit مكانًا رائعًا لاستخدام نص سريع ، ولكن من المدهش أن يكون مطولًا في PowerShell Core أكثر من bash. بالطبع ، غالبًا ما تبدو حلول bash قبيحة جدًا.

رد: السكر النحوي ، عقلي الساخر يقتبس فيلم "Snatch": "أنا بالفعل حلو بما فيه الكفاية"

هذا يعتمد. أشعر أحيانًا أن PowerShell ممتع للغاية. يعد التعامل مع null أحد المجالات الرئيسية التي لا أشعر فيها عادةً بهذه الطريقة - على الرغم من أنني أقول الشيء نفسه بالنسبة للعديد من اللغات. أجد أيضًا عبارة PowerShell if-else التقليدية المضمنة مرهقة مقارنةً بالمعامل الثلاثي أو سلسلة bash && و || . نظرًا لأن هذه إحدى المشكلات الرئيسية التي تسببت في الابتعاد عن PowerShell منذ سنوات ، فقد اعتقدت أنها تستحق الذكر.

من ناحية أخرى ، أتعامل مع مجموعة متنوعة من اللغات على أساس يومي ، وبغض النظر عما أكتبه ، أفكر دائمًا ، "سيكون هذا أسهل كثيرًا في اللغة X!" - وبعد ذلك متى أنا أستخدم اللغة X ، كما أفكر ، "سيكون هذا أسهل بكثير في اللغة Y!" لكن مهلا ، إذا سنحت لي الفرصة لأقول ذلك بصوت عالٍ وربما أثر في اتجاه اللغة ، فسأستفيد منه.

لست مهتمًا حقًا بتغيير أي طريقة تفكير هنا ، فقط إضافة منظور آخر.

StartAutomating : هل تقول

أنا دائما أحب لي بعض السكر النحوي الجديد! أختار لغات البرمجة مثل طفل يذهب خدعة أو علاج في عيد الهالوين.

Zenexer : أنا حقا أحب Powershell ، أفعل. أنا محظوظ بما يكفي لأمارس الرياضة ${...}? بالنسبة لي.

نقاط جيدة ، ولكن اسمحوا لي أن أوضح بعض الأشياء.

للأفضل أو للأسوأ ، لم يستخدم PowerShell حتى الآن الإصدار الدلالي.
نسخة رئيسية جديدة جلبت فقط ميزات جديدة ، مع التزام صارم بالتوافق مع الإصدارات السابقة.
بدأت التغييرات المتقطعة تتسلل إلى Core ، في جزء من الضرورة بسبب الانتقال عبر الأنظمة الأساسية.
تم اختيار الإصدار الرئيسي v7.0 للإشارة إلى _ زيادة_ في التوافق مع الإصدارات السابقة: محاولة لتوفير بديل عملي لـ Windows PowerShell.

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

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

لماذا هو نادر؟

نظرًا لأن استخدام ? في أسماء المتغيرات لا يحدث لمعظم الناس تمامًا ، وإذا حدث ذلك ، فلا يجب أن يتوقعوا أن يعمل _ بدون {...} _: إذا كان كل ما يلي يعمل فقط مع {...} ، لماذا نتوقع أن يكون مختلفًا عن ? ؟: . , ; (لا يمكن استخدام : على الإطلاق ، لأنه يتم تفسيره دائمًا على أنه فاصل محرك)

السماح لأسماء مثل $var? أو $va?r دون الحاجة أيضًا إلى {...} كان بمثابة السماح بالمتاعب ، وقد وصلت المشكلة: لقد كان عقبة في طريق تطور اللغة ، كما في هذه الحالة.

هناك 3 ميزات جديدة ذات صلة (مرتبطة على الأقل في شكل نحوي) مستوحاة من C #:

  • الشروط الثلاثية - ستكون ميزة حسنة النية في الإصدار 7.0

    • (Get-Date).Second % 2 ? 'odd' : 'even'

  • عامل الاندماج الفارغ - سيكون ميزة حسنة النية في الإصدار 7.0

    • $var ?? 'default' و $var ??= 'default'

  • عامل التشغيل الشرطي الفارغ - المشكلة المطروحة - سيكون ميزة _تجربة_ في الإصدار 7.0

    • $possiblyNull?.ToString()

كل منهم لديه ? كجزء من تركيبهم ، وجميعهم يتأثرون بعبء التحليل القديم $var? ، على الرغم من ?. الأكثر وضوحًا:

  • بينما يمكنك القول بأن شيئًا مثل $var?1:0 لا يهم سوى لاعبي الغولف ، فإنه سيعمل بشكل جيد إذا كان ? يحتوي على وظيفة نحوية - حاليًا يجب عليك استخدام _space_ قبل ?

  • على النقيض من ذلك ، يبدو لي أنه من المعقول أن يحاول شخص ما $var??='bar' (ربما أقل من $baz = $foo??$bar ) ، والتي تتطلب حاليًا مساحة أيضًا.

بمعنى ، إذا التزمنا بالتحليل الحالي لـ $var? ، فإننا نشغل _ ثلاث_ ميزات جديدة (وإن كانت بدرجات متفاوتة) ، اثنتان منها متاحتان بشكل عام بالفعل (غير تجريبية).

المشكلة مع طلب {...} _لا_ مجرد إزعاج من الكتابة: إنها تتعلق بنفس القدر من _لا تتوقع الحاجة إليها _ في المقام الأول ، ولاحقًا _ نسيان الحاجة إليها _ (مع وجود عطل خفي محتمل) - لأن إنه غير بديهي للغاية.

@ ExE-Boss ، أتفق مع jhoneill على أن تنفيذ السلوك المشروط للإصدار سيكون مشكلة. لا أعتقد أن هناك حاجة لإثقال المحرك بغلاف خاص متوافق مع الإصدارات السابقة في هذه الحالة.

@ mklement0 : إنه غير طبيعي / غير بديهي / سمها ما شئت. الأقواس صلبة ، والأقواس المتعرجة أصعب. ليست هناك حاجة لهم في هذه الحالة.

@ mklement0 منذ أن يبدو أن الاتفاق في

لم أفوز حتى الآن تمامًا بإضافة تركيبات C # إلى PowerShell. لدينا بالفعل مشكلات في العديد من الأماكن حيث لا توجد رموز كافية على لوحة المفاتيح. هل ">" "أكبر من" أم "إعادة التوجيه إلى"؟ هو "=" مهمة أو اختبار مساواة (استخدام لغات مختلفة: = للتعيين أو == للمساواة). سوف ينسى الأشخاص الذين يقفزون بين اللغات استخدام -eq أو -gt ونحن عالقون في ذلك ... هل + إضافة حسابية ، أو سلسلة / سلسلة متسلسلة. * عبارة عن عملية ضرب وحرف شامل. ٪ هو Modulo واسم مستعار لـ forEach-object.

مسكين ؟ هو الاسم المستعار لـ Where-Object. وهو اسم متغير آلي. لكن حاول القيام بعمل Get-Alias ? أو Get-Variable ? ... وبعد ذلك يقوم بعمل حرف البدل.

افعل Get-PSdrive وسترى "متغير" وما إلى ذلك ليس لديك ":" في نهاية الاسم ، إضافة واحد: في الاسم يؤدي إلى معاملته كمحرك أقراص. ما لم تكن قد أشرت بالطبع إلى كتابة "$drive="C" وتتبعها بـ "$drive:temp" أي شخص جديد في PowerShell (وبعض الأيدي القديمة ، عندما لا يفكرون في ذلك) سيكون محيرًا لمعرفة أنهم ' لقد اخترع للتو نطاق مسمى "محرك".

مقابل ذلك ... قد يقول المرء "إنشاء بناء جملة جديد مع استخدامات أخرى لـ": "و"؟ " هل أنت مجنون؟'
IIRC ، على تويتر BrucePay وصفت عامل التشغيل الثلاثي بأنه "Not very PowerShelly" وأنا أميل إلى الموافقة. لكن أصوات "اجعلها أشبه بـ C #" فازت باليوم ...

يكتب معظم الناس $PSEdition.length -gt 2
لكن $PSEdition. length-gt2 يعمل أيضًا (يمكنك حتى أن يكون لديك فاصل أسطر بين النصفين.) "." هو أيضًا مثقل بالعمل كـ "دليل حالي" و "تشغيل في هذا النطاق" و "عضو" ولكن في PS V1-V5 لا يمكنني التفكير في أي مشغل يتطلب مساحة رائدة ؛ "." هو غريب في الانكسار إذا كان واحدًا _is_ موجودًا. ولكن ، من أجل التحليل ، يحتاج العامل الثلاثي _might_ إلى مسافة بادئة
$host.debuggerEnabled?0:1 مناسب لأن "؟" يفترض _ لا_ أن يكون جزءًا من الممتلكات
$IsCoreCLR?0:1 بسبب "؟" يفترض أن يكون جزءًا من اسم المتغير.

وينطبق الشيء نفسه على عوامل الاندماج الصفرية
$null?? "default" يحتاج إلى مساحة $true.length?? "default" لا يحتاج.

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

أعتقد أن هناك فترة زمنية قصيرة لوضع ميزة تجريبية تتطلب؟ ليتم دعمها في الأسماء ، وإذا كانت هذه الميزة قيد التشغيل - ما الذي يجب أن يكون الافتراضي - فكل ما هو جديد؟ يجب على المشغلين تحليل وفقًا لذلك. فقط إذا كانت هذه الميزة متوقفة عن التشغيل ، فسيتطلب المحلل اللغوي مسافات أو أقواس معقوفة مع هذه العوامل .. وهذا تغيير فاصل ، سيتم كسر بعض البرامج النصية (رقم صغير غير قابل للقياس الكمي) ما لم يتم تعيين أحد الخيارات (ومن المفترض أن يؤدي عدم السماح باسم المتغير إلى منع $ IsIt ؟ .tostring () هو الخطأ الأول في البرنامج النصي ، لذلك يجب أن تفشل البرامج النصية ، ولا تعمل بشكل خطير). ومن الناحية المثالية ، لا ينبغي أن يحدث ذلك مع إصدار نقطة (أنت محق بشأن عدم استخدام PowerShell حقًا لـ sem-ver ، لكنه لا يزال مبدأً جيدًا)

إن مشكلة طلب {...} ليست مجرد إزعاج للكتابة: إنها تتعلق بنفس القدر بعدم توقع الحاجة إليها في المقام الأول ، ثم نسيان الحاجة إليها لاحقًا (مع وجود عطل خفي محتمل) - لأنها غير بديهي للغاية.

هذه نقطة جيدة وهي إلى حد كبير ما قد يزعجني حول ${...?} في الممارسة العملية. حتى لو كنت أعلم استخدام {} ، فهناك فرصة قوية لأنني سأنسى في النهاية ، وقد ينتج عن ذلك أخطاء خفية لم تكن واضحة في البداية ، حيث من المحتمل أن تظل صالحة من الناحية التركيبية. $var??='bar' مثالًا جيدًا على ذلك ، على الرغم من أنني عادة ما أكون حريصًا جدًا بشأن التباعد.

شكرًا ، @ jhoneill ، هذا توضيح لطيف لعدد الرموز التي تقوم بالكثير من المهام المزدوجة (الثلاثية ، ...) في PowerShell.
بالنسبة للجزء الأكبر ، بمجرد أن تكون على دراية بجميع الاستخدامات ، فهذه ليست مشكلة ، للأسباب التالية:

  • سياقات مختلفة (على سبيل المثال ، * كمعامل مقابل * كحرف بدل.)

    • السياقات المختلفة لـ ? لها شيء مشترك بالفعل ، عند مستوى معين من التجريد: يمكنك تصور ? في Get-ChildItem | ? Target ، $var?.Target ، $? ، $var ?? 'none' حيث أن جميعها تتضمن نوعًا من _السؤال_ وبالتالي _ الاختبار_ أو _ السلوك المشروط_.

  • سلوك متعدد الأشكال معقول (على سبيل المثال ، + أداء تسلسل مع سلسلة).

المثال الإشكالي هو & (عامل تشغيل المكالمة مقابل عامل تشغيل الخلفية) ، والذي يتم استخدامه في نفس السياق بدلالات مختلفة ، اعتمادًا فقط على _وضعه_.

سيتم إصلاحه إذا كانت أسماء المتغيرات تحتوي على "؟" تحتاج إلى دعم مثل الأسماء التي تحتوي على "." أو "+" أو ":"

في الواقع ، وهذا أمر يستحق التكرار: القدرة على استخدام ? في أسماء المتغيرات لن تختفي - لكن عليك استخدام {...} فصاعدًا: ${var?} = @{ foo=1 }; ${var?}?.foo

كما أوضحت ، في مرجع متغير _unbraced_ ، ?. و ?? و ? : جعلت اللغة (ظرفية) حساسة للمسافات البيضاء لهؤلاء المشغلين ، والتي أعرف أن الفريق يريد تجنبها - لأسباب وجيهة ، نظرًا لأن PowerShell بشكل عام ليس حساسًا للمسافات البيضاء (على الأقل ليس سطرًا واحدًا ، . لمصادر النقطة هو الاستثناء المبرر ؛ ? مثل Where-Object قد يكون الاسم المستعار gci|?target لا يعمل) ، لكن أسماء الأوامر _do_ تحتاج إلى فصلها عن وسيطاتها بمسافة بيضاء).

القدرة على وضع مسافة بيضاء بين . واسم العضو ( $obj. foo ) أمر منطقي بشكل أساسي في العبارات متعددة الأسطر ، على الرغم من أن النموذج الأكثر قابلية للقراءة - المألوف من اللغات الأخرى - هو (أيضًا) السماح بالمسافة البيضاء _before_ . :

# This does NOT work - the . must be *immediately after* the expression / member
(Get-Date)
  .ToUniversalTime()  
  .TimeOfDay

أن تكون قادرًا على القيام بذلك سيعكس القدرة المضافة مؤخرًا لوضع | على السطر _next_:

 # Already works in PS Core
Get-Date
  | % ToUniversalTime
  | % TimeOfDay

ومع ذلك ، فإن هذا من شأنه أن يؤدي إلى غموض لا يمكن حله مع . كعامل تحديد مصادر النقطة وأسماء الأوامر التي تبدأ بـ . - ولكن من غير المحتمل. (على سبيل المثال ، يمكن أن يكون . foo في سطر جديد وصولاً إلى خاصية أو أمرًا يقوم بنقاط مصدر دالة أو نص برمجي باسم foo (والذي يجب أن يكون في $env:PATH ) ؛ .foo يمكن أن يكون اسم _ أمر_).

استمرار RFC متعدد الخطوط لـ KirkMunro ، مع التركيز على السماح لـ _commands_ بتمديد أسطر متعددة ، سيعطينا الحل الأفضل التالي - راجع https://github.com/PowerShell/PowerShell-RFC/pull/179#issuecomment -498734875.

أما بالنسبة للميزة تجريبية يجري على افتراضيا: لحسن الحظ، _preview_ الإصدارات - ولكن ليس الافراج عن المرشحين - أنتقل الآن _all_ الميزات التجريبية بشكل افتراضي. ومع ذلك ، لاحظ أنه يتم تجاوز هذا باستمرار إذا قمت بتشغيل Enable-ExperimentalFeature إما _ بدون _ -Scope أو مع -Scope CurrentUser مع أي ميزات قمت بتمكينها هناك.

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

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

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

@ PowerShell / بوويرشيل-جنة ناقشنا هذا ، قمنا بتحليل مجموعة نصوص PowerShell وكان هناك قدر كبير من استخدام أسماء المتغيرات التي تنتهي بعلامة الاستفهام. على هذا النحو ، لا يمكننا كسر هؤلاء الأشخاص والأقواس حول أسماء متغيرات PowerShell هي ميزة لغة موجودة لتمييز اسم المتغير عن الأحرف الأخرى (مثل داخل سلسلة).

لقد حللنا مجموعة نصوص PowerShell وكان هناك قدر كبير من استخدام أسماء المتغيرات التي تنتهي بعلامة الاستفهام

شكرًا ، @ SteveL-MSFT - هل يمكنك مشاركة نتائج هذا التحليل من فضلك؟

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

أود أيضًا أن أرى النتائج والطريقة المستخدمة. لقد أجريت تحليلي الخاص لمجموعة PowerShell Corpus الليلة الماضية باستخدام AST الذي استغرق ما يقرب من 6 ساعات لإكماله على جهازي. كان هناك عدد قليل من الملفات التي يتعذر تحليلها بسبب قيام Windows Defender بعزل الملف.

لقد وجدت 11 اسمًا متغيرًا فريدًا عبر 8 ملفات تنتهي بعلامة استفهام (باستثناء $؟ والتي ظهرت 8846 مرة). كان هناك ما مجموعه 1،895،983 ، متغيرات فريدة عبر 408،423 ملفًا. هذا يعني أن 0.0006٪ من جميع متغيرات PowerShell الفريدة في المجموعة لها اسم متغير ينتهي بعلامة استفهام.

فيما يلي الملفات الثمانية و 11 متغيرًا فريدًا:

File                 : C:\Temp\PowerShellCorpus\Github\alanrenouf_PowerActions\Kill-VM.ps1
QuestionMarkVars     : vParam?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\Github\anthonywlee_PowerShell\Send_Notification.ps1
QuestionMarkVars     : To?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\Github\aspear_My-PowerCLI-scripts\my-labotomize-vms.ps1
QuestionMarkVars     : vParam?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\Github\jlundstrom_Scripts\Powershell\7Zip SFX Creator\Build.ps1
QuestionMarkVars     : Title?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\Github\pslaughter_Working\Setup-Host.ps1
QuestionMarkVars     : HostIp?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\Github\stevenayers_PowerShell-Scripts\Random Functions\Add-OutlookConferenceRegionNumber.ps1
QuestionMarkVars     : {key1?, key2?, key3?, key4?}
QuestionMarkVarCount : 4

File                 : C:\Temp\PowerShellCorpus\Github\unixboy_powershell-stufff\stopvm.ps1
QuestionMarkVars     : vParam?
QuestionMarkVarCount : 1

File                 : C:\Temp\PowerShellCorpus\PowerShellGallery\PsHg\0.6.2\PsHg.psm1
QuestionMarkVars     : PsHg?
QuestionMarkVarCount : 1

هذا هو النص المستخدم لإنشاء التقرير:

Get-ChildItem -Path C:\Temp\PowerShellCorpus -Include *.ps1, *.psm1 -File -Recurse | ForEach-Object -Parallel {
    try {
        $content = $PSItem | Get-Content

        $ast = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref]$null, [ref]$null)
        $variables = $ast.FindAll({$args[0] -is [System.Management.Automation.Language.VariableExpressionAst ]}, $true)

        # First query because I forgot to exclude $? variables
        # $nonQuestionMark = $variables | Where-Object VariablePath -notmatch '\?$' | Select-Object -Unique
        # $QuestionMark = $variables | Where-Object VariablePath -match '\?$' | Select-Object -Unique

        $nonQuestionMark = $variables |
        Where-Object VariablePath -notmatch '\?$' |
        ForEach-Object { $_.VariablePath.UserPath.ToString() } |
        Select-Object -Unique

        $QuestionMark = $variables |
        Where-Object { $_.VariablePath -match '\?$' -and $_.VariablePath.UserPath -ne '?' } |
        ForEach-Object { $_.VariablePath.UserPath.ToString() } |
        Select-Object -Unique

        $output = [pscustomobject]@{
            File = $PSItem
            QuestionMarkVars = $QuestionMark
            QuestionMarkVarCount = $QuestionMark.Count
            NonQuestionMarkVars = $nonQuestionMark
            NonQuestionMarkVarCount = $nonQuestionMark.Count
        }

        $output
    }
    catch {
        throw
    }
}

يُرجى إعلامي إذا كانت هناك أي مشكلة في الطريقة المستخدمة لإنشاء هذا التقرير. فيما يلي مثال على البرنامج النصي المستخدم لاختبار التدقيق.

$abc = 'test'
$isAwesome? = $true
$?

$test = {
    $?
    $isabc? = { $adce? = 'test' }
    ${def?} = 123
    ${is a bad var name?} = $isabc?
}

النتائج في:

File                    : C:\temp\variable.ps1
QuestionMarkVars        : {isAwesome?, isabc?, adce?, def?, is a bad var name?}
QuestionMarkVarCount    : 5
NonQuestionMarkVars     : {abc, true, test}
NonQuestionMarkVarCount : 3

كما يقولون في فصل الرياضيات "من فضلك اعرض عملك"

تجسس ممتاز ،

أعتقد أنه يمكنك استبعاد المزيد من الحالات ، نظرًا لأن النموذج ${...} سيستمر في العمل مع التغيير المقترح - على سبيل المثال ، إنه $isAwesome? نحتاج إلى القلق بشأنه ، وليس ${isAwesome?}

مع ملف المثال الخاص بك:

$variables.Extent.Text.Where({ $_ -match '(?<!\$)\?$' }) | Select-Object -Unique

نحصل فقط على:

$isAwesome?
$isabc?
$adce?

وهذا يعني أن ${def?} و ${is a bad var name?} لا يجب أن يؤخذ في الاعتبار.

ملاحظة: من الأفضل أيضًا استخدام $PSItem | Get-Content -Raw لقراءة النص بأكمله كسلسلة واحدة.

@ mklement0 هذا صحيح ، لقد أضفت تلك الحالات مباشرة قبل النشر للتأكد من أن البرنامج النصي لا يستبعد المتغيرات ذات التدوين المتعرج معًا.

بعد تحديث البرنامج النصي بتوصياتك ، ينتج ملف الاختبار المخرجات التالية كما نتوقع.

File                    : C:\temp\variable.ps1
QuestionMarkVars        : {isAwesome?, isabc?, adce?}
QuestionMarkVarCount    : 3
NonQuestionMarkVars     : {abc, true, test}
NonQuestionMarkVarCount : 3

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

البرنامج النصي المحدث:

Get-ChildItem -Path C:\Temp\PowerShellCorpus -Include *.ps1, *.psm1 -File -Recurse | ForEach-Object -Parallel {
    try {
        $content = $PSItem | Get-Content -Raw

        $ast = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref]$null, [ref]$null)
        $variables = $ast.FindAll({$args[0] -is [System.Management.Automation.Language.VariableExpressionAst ]}, $true)

        $nonQuestionMark = $variables |
        Where-Object VariablePath -notmatch '\?$' |
        ForEach-Object { $_.VariablePath.UserPath.ToString() } |
        Select-Object -Unique

        $QuestionMark = $variables |
        Where-Object { $_.VariablePath -match '\?$' -and $_.VariablePath.UserPath -ne '?' -and $_.Extent.Text -match '(?<!\$)\?$' } |
        ForEach-Object { $_.VariablePath.UserPath.ToString() } |
        Select-Object -Unique

        $output = [pscustomobject]@{
            File = $PSItem
            QuestionMarkVars = $QuestionMark
            QuestionMarkVarCount = $QuestionMark.Count
            NonQuestionMarkVars = $nonQuestionMark
            NonQuestionMarkVarCount = $nonQuestionMark.Count
        }

        $output
    }
    catch {
        throw
    }
}

شكرًا ، ThomasNieto - كنت آمل أن نتمكن من خفض النسبة إلى 0.0005٪ ... (أمزح فقط).

لذا يجب أن تكون اللجنة قد استخدمت نوعًا مختلفًا - خاص؟ - جسم.

لذا ، بالإضافة إلى البت في القضية المطروحة ، يطرح السؤال التالي: هل تحتاج مجموعة المواد المتاحة للجمهور إلى تحديث؟ هل يتم صيانته رسميًا (حاليًا بتاريخ 26 يوليو 2017)؟

@ SteveL-MSFT ، هل يمكنك التوضيح؟

لقد قمت بالتقريب إلى @ mklement0 ، لذا إذا كنت تريد أن تشعر بتحسن قليل ، فهو في الواقع 0.00058٪ 😄

في https://github.com/PowerShell/PowerShell-RFC/pull/223#discussion_r318340339 ، أجرىadityapatwardhan تحليلًا باستخدام نفس المجموعة العامة التي استخدمتها وخرجت بنسبة 62 ٪ بمتغيرات تنتهي بعلامة استفهام. لم أجد ردًا على كيفية توصله إلى هذه النسبة المئوية. هل استخدمت لجنة PS هذا التحليل لتحديد هذا الطلب؟

بالنظر إلى التعليق المرتبط ، أعتقد أن adityapatwardhan يقول أن _ من بين جميع المتغيرات التي تحتوي على ? في اسمها_ 62٪ لها ? كحرف _last_ للاسم.

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

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

ThomasNieto وبالمثل قمت بإجراء تحليل في مكان ما حول هذه القضايا لنتائجك .

mburszley شكرا

أسمعك يا mburszley ، لكن رد:

اللجنة تقول فقط "لا نريد"

إذا كان هذا حقًا قرارًا _ fiat_ - قرارًا لا يستند إلى تحليل الاستخدام في العالم الحقيقي - فلن يبشر بالخير للمجتمع ككل ، لا سيما بالنظر إلى أن السبب _المعلن _ كان أساسًا لمثل هذا التحليل.

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

ماذا عن اقتراحي في https://github.com/PowerShell/PowerShell/issues/11379#issuecomment-566756120 ؟

أقترح القيام بذلك حتى يعمل $obj?.Method() كـ $<var i="9">obj</var> ?. <var i="12">Method</var>() بشكل افتراضي ، ويعود فقط إلى $<var i="14">obj?</var> . <var i="17">Method</var>() عندما لا يكون $<var i="19">obj</var> موجودًا في النطاق ، لكن $<var i="21">obj?</var> موجود و #requires ‑Version ليس الإصدار 7 +.

أتوقع أنه سيعالج معظم مخاوف التوافق مع الإصدارات السابقة.

تضمين التغريدة

@ mklement0 صحيح ، لقد بين المتغيرات التي تستخدم ? ، استخدمها 62٪ في النهاية.

من النتائج الموضحة في التعليق هنا يبدو أن جميع المتغيرات التي تستخدم ? تستخدمه في النهاية. ومن هنا جاء اقتراح إجراء تغيير غير منقطع.

إذا تمت إزالة طلب {..} فسيظل النص البرمجي يحلل ولكن الدلالات ستكون مختلفة ، وهذا في رأيي أمر خطير للغاية.

بالتأكيد ... لكن التحليل يظهر حرفيًا أنه لا أحد يستخدمها تقريبًا.

مثل أي تغيير كسر آخر ، يمكن الإعلان عنه ، وتقديمه كميزة تجريبية لبعض الوقت ، ثم توثيقه وجعله مستقرًا.

لا أرى أي سبب للتوصية ببنية مقصورة على فئة معينة عندما لا يتم استخدام ? كحرف معرف بالفعل في عدد كبير من الحالات عن بعد.

إذا تمت إزالة مطلب {..} ، فسيظل النص قيد التحليل ولكن الدلالات ستكون مختلفة ، وهذا في رأيي خطير للغاية.

ألست قلقًا أيضًا بشأن الأشخاص الذين يستخدمون ?. بالطريقة التي يستخدمونها في C / C ++ / C # والحصول على النتيجة الخاطئة دون أي إشارة إلى أنهم فعلوا أي خطأ؟ على سبيل المثال:

PS> $res = "My length is 15"
PS> $res?.Length
0

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

ربما يحتاج PowerShell إلى ما يعادل Enable-ExperimentalFeature أطلق عليه Enable-PSFeature ، للميزات التي لم تعد في الحالة التجريبية ولكنها ليست جاهزة للتشغيل افتراضيًا . بالنسبة إلى البرامج النصية التي يتم تنفيذها باستخدام رمز مثل $?.GetType() يمكنك البدء في إرسال تحذيرات تفيد بأن هذا سيتوقف في المستقبل وأنه يجب عليك استخدام ${?}.GetType() بدلاً من ذلك. يمكن للنصوص الفردية تمكين الميزة بـ #requires -version 7.1 -feature PSNullConditionalOperators . ثم ربما عندما تصل PS 8 ، يمكن تمكين الميزة افتراضيًا.

يذهب مثال rkeithhill مباشرة إلى النقطة.
انسَ للحظة ما تعرفه عن كيفية عمل PowerShell اليوم. عندما ترى

PS> $res?.Length

يبدو مثل _name ، المشغل ، name_ - أيهما بالطبع.
أيهما أكثر منطقية: _ "؟" هو جزء من عامل التشغيل_ ، أو _ "؟" هو جزء من الاسم الأول element_؟
إذا كانت هناك حاجة إلى هؤلاء المشغلين (وأعتقد أنهم "ليسوا PowerShelly") ، فإن الاختيار بين شيء سيتم استخدامه بشكل غير صحيح وكمية صغيرة من الكسر.

أود أن أبدأ في وضع القواعد في psScriptAnalyzer _now_ لأقول إنه أسلوب سيء لاستخدام بعض الأحرف [القانونية] في أسماء المتغيرات.

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

سأبدأ في وضع القواعد في psScriptAnalyzer الآن لأقول إنه أسلوب سيء لاستخدام أحرف [قانونية] معينة في أسماء المتغيرات.

ها هي المشكلة: إذا قمت بتغيير طريقة ترميز PowerShell للمتغيرات ، فسوف يراها PSScriptAnalyzer بشكل مختلف أيضًا. إذا كان لديك متغير مثل $res? ، فابحث عن شيء مثل هذا:

{
$res?.Length
}.Ast.EndBlock.Statements[0].PipelineElements[0].Expression.Expression.VariablePath.UserPath

يعطيك

res?

ولكن ، إذا قمت بتغيير طريقة تحليل PowerShell ، على سبيل المثال ، 7.2 ، فستحصل على


الآن لا يستطيع PSScriptAnalyzer رؤية ? ، لأنه لم يعد جزءًا من اسم المتغير (حسب التعريف ، لأنه التغيير الذي نحاول اختباره). هذا لأن PSScriptAnalyzer هو وحدة PowerShell ويعيد استخدام نفس المحلل اللغوي الذي يتم شحنه في PowerShell. (وسيكون من غير الممكن الحفاظ عليه تمامًا ووصفة لكارثة إذا حاولت إعادة تنفيذه).

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

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

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

rjmholt ، بينما أعتقد أنه يمكننا جميعًا تقدير مدى صعوبة تغيير مثل هذا _ من حيث المبدأ_ ، في هذه الحالة بالذات لا يهم _ في الممارسة_ ، ولا أعتقد أن هناك حاجة حتى لقاعدة PSSA:

  • أظهر تحليل أنه - إذا اعتقدنا أن المجموعة تمثل جميع أكواد PowerShell الموجودة هناك - فلا أحد يستخدم تقريبًا متغيرات بأسماء تنتهي بـ ? _.

  • إذا كنت سأخمن ، فإن معظم الناس لن يفكروا حتى في استخدام مثل هذه الأسماء المتغيرة ، لأنهم لن يتوقعوا منهم أن يعملوا (بما في ذلك أنا) ، وربما لا يلاحظون حتى الاستثناء المتمثل في $? التلقائي المتغير bash ).

    • في الواقع ، عند النظر عن كثب إلى تحليل ThomasNieto يكشف أنه من بين الملفات 8 المدرجة:

      • 5 فقط على _إيجابيات خاطئة_ ، وهي استخدامات المتغيرات داخل _ سلاسل_ مثل "Are you sure you want to kill $vParam?" - في الواقع ، هذه الاستخدامات هي _broken_ ، وتكشف أن مؤلفي النص _ لا_ يتوقعون ? ليكون كذلك جزء من اسم المتغير.

      • 2 من هذه الملفات متاحة للجمهور.

      • فقط _1_ منها هو استخدام حسن النية لمتغيرات ? -ending - كمتغيرات منطقية (على سبيل المثال ، $key1? ) ، والتي ، على سبيل المثال ، لا يتم دمجها مع عامل وصول الأعضاء ، . / ccstevenayers.

بناءً على ما سبق ، يبدو لي هذا بمثابة كتاب مدرسي دلو 3: تغيير

_ التوثيق_ يجب أن يكون التغيير في السلوك (مع وجود مبرر) كافياً.

بالطبع:

  1. هذا يعتمد على (أ) التحليل صحيح و (ب) المجموعة المتاحة للجمهور تمثيلية.

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

انطلاقًا من افتراض أن 1. صحيح (لم نسمع أي شيء يدعمه 2.) ، لدينا خياران:

  • انزع أداة المساعدة اللاصقة وامنع ? في أسماء المتغيرات من الآن فصاعدًا ، ما لم تكن مضمنة في {...} (مع استثناء واضح وهو $? ) - سيؤدي هذا إلى كسر الصغر المتلاشي نسبة النصوص التي تعتمد على ذلك حاليًا.

    • أي شيء مثل $key1? لا يتبعه . ولا آخر ? ( $key1??'else' ) ولا تعبير ثلاثي ( $key1?1:0 ) قد يتسبب في خطأ _parser_.

      • كما تظهر أمثلة عامل التوحيد الصفري والثالث ، فإنها ستستفيد أيضًا من هذا التغيير - حاليًا ، تحتاج إما إلى _space_ - $key1 ?1:0 / $key1 ??'else' - أو {...} - ${key1}?1:0 / ${key1}??'else'

    • داخل _ السلاسل القابلة للتوسيع_ ، لن يتم اعتبار ? بعد ذلك جزءًا من اسم متغير (non- {...} -enclosed) ، لذلك سنقوم بالفعل _fix_ بالبرامج النصية الحالية التي استخدمت سلاسل مثل "Are you sure you want to kill $vParam?" بالخطأ
  • إذا شعرنا حقًا أننا بحاجة إلى تجنب كسر النسبة الصغيرة المتلاشية من البرامج النصية الحالية ، فيمكننا أن نفكر في المنطق الذي اقترحه @ ExE-Boss ، لكنني لا أعتقد أننا نريد تقديم هذا التعقيد المفاهيمي - ناهيك عن تعقيد التنفيذ (الذي أنا لا أستطيع التحدث إلى).

@ SteveL-MSFT

نشكرك على مناقشة هذه المشكلة في مكالمة المجتمع لشهر سبتمبر (https://aka.ms/PSCommunityCall ؛ حتى كتابة هذه السطور ، لم يتم نشر تسجيل مكالمة سبتمبر هناك ، ولكن يمكن الوصول إليه على https://aka.ms/JoinPSCall ، حتى المكالمة التالية) ، بدءًا من الساعة 46:00 ، بناءً على اقتراحThomasNieto في الالتماس المسبق لموضوعات المناقشة على https://github.com/PowerShell/PowerShell-RFC/issues/260 :

(كنت آمل أن أقدم رابطًا مباشرًا للجزء ذي الصلة من التسجيل ، ولكن سيتعين على ذلك الانتظار حتى يتم نشره على YouTube وربطه على https://aka.ms/PSCommunityCall.)

بناءً على ملاحظاتك في التسجيل:

  • نظرًا لأنك أشرت إلى رغبتك في إعادة النظر في هذا ، يرجى إعادة فتح هذه المشكلة وإعادة وضع علامة عليها كـ Review - Committee .

  • بالنسبة لملاحظاتك ، فإن تضمين أسماء المتغيرات في أقواس معقوفة هي ميزة موجودة مسبقًا وأن الناس يعترضون على استخدامها في هذه الحالة لأسباب _ جمالية_:

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

أنا قلق من أن هذه المشكلة - التي تبدو الآن في حالة مغلقة إلى أجل غير مسمى - ستسقط من الشقوق ، لذلك فتحت رقم 14025 كتذكير لإعادة النظر فيه ، وأدعو كل من يهمه الأمر لإظهار دعمهم هناك.

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