Powershell: Tidak memerlukan { ... } di sekitar nama variabel untuk akses anggota bersyarat nol

Dibuat pada 17 Des 2019  ·  53Komentar  ·  Sumber: PowerShell/PowerShell

Tindak lanjut dari #3240.

Akses anggota bersyarat nol ( ?. ) telah diterapkan dan akan tersedia sebagai fitur _experimental_ di 7.0

Namun, untuk kepentingan kompatibilitas ke belakang , implementasi saat ini mengharuskan nama variabel diapit {...} , karena ? secara teknis adalah karakter legal dalam nama variabel yang penggunaannya secara mengejutkan _tidak_ memerlukan {...} .

Yaitu, jika Anda ingin mengabaikan upaya untuk memanggil $obj.Method() jika $obj adalah $null (atau tidak terdefinisi), Anda akan mengharapkan yang berikut, analog dengan C#:

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

Sebagai gantinya, saat ini Anda harus menggunakan:

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

_Update_: Null-coalescing - $var??='default dan $a??$b - dan operator ternary - $var?1:0 - sama-sama terpengaruh (meskipun ada penggunaan spasi sebelum ? menyelesaikan masalah).

Persyaratan ini (a) tidak terduga dan (b) rumit:

  • Pengguna baru tidak akan mengharapkan perlunya {...} dan belum tentu tahu bahwa _it_ adalah yang diperlukan ketika yang berikut ini gagal (mungkin _tidak terdeteksi_, kecuali Set-StrictMode -Version 2 atau lebih tinggi berlaku): $o = [pscustomobject] @{ one = 1 }; $o?.one

  • Bahkan setelah pengguna _do_ tahu tentang perlunya {...} :

    • Mereka akan lupa untuk menggunakannya sesekali, karena kebutuhan kontra-intuitif untuk itu.
    • Ketika mereka ingat, persyaratan yang tampaknya dibuat-buat ini akan menjadi sumber frustrasi yang berkelanjutan, terutama karena {...} sulit untuk diketik.

Penggunaan {...} seharusnya tidak diperlukan, dan meskipun tidak memerlukannya sama dengan perubahan _breaking_, itu bisa dibilang termasuk dalam ember 3: Tidak Mungkin Area Abu-abu .


Mengapa perubahan ini harus dianggap dapat diterima:

Catatan: @rjmholt membahas mengapa mengubah sintaks PowerShell sangat bermasalah _secara umum_ dalam komentar ini , tetapi untuk alasan yang disajikan di bawah ini, saya pikir perlu membuat pengecualian di sini.

?. adalah fitur sintaksis _new_; menurut definisi skrip yang menggunakannya _cannot_ (berarti) berjalan pada versi yang lebih lama - kecuali jika Anda secara khusus menambahkan persyaratan yang menyediakan jalur kode yang kompatibel dengan versi lama, tetapi itu tampaknya tidak sepadan - Anda kemudian akan tetap menggunakan fitur warisan.

Ya, interpretasi $var?.foo dalam skrip lama yang menggunakan $var? sebagai nama variabel akan rusak, tetapi:

  • ? seharusnya tidak pernah diizinkan sebagai bagian dari pengenal _tanpa melampirkannya di {...} _.

  • Karena mampu melakukannya tidak terduga dan bahkan mungkin _tidak diketahui_ banyak orang, nama variabel seperti itu sangat jarang di alam liar, berbicara dari pengalaman pribadi, tetapi analisis @mburszley memberikan bukti yang lebih nyata .

    • Bahkan Ruby hanya mengizinkan ? (dan ! ) di _end_ pengenal, dan hanya ada _method_ pengenal, dan saya menduga bahwa sebagian besar pengguna Ruby sadar bahwa mereka harus _tidak_ menganggap bahwa bahasa lain mendukung hal yang sama.

Jadi, secara pragmatis:

  • Sebagian besar kode yang ada tidak akan terpengaruh - token seperti $var?.foo tidak akan ditemukan.

  • Jika Anda menulis $var?.foo dengan semantik baru, maka ya, menjalankannya pada versi yang lebih lama dapat menghasilkan perilaku yang berbeda (daripada melanggar dengan cara yang jelas), tergantung pada mode ketat apa yang berlaku - tetapi _Anda harus selalu tetapkan versi minimum yang diperlukan untuk menjalankan kode Anda sebagaimana dimaksud_ ( #requires -Version , kunci manifes modul).

Secara keseluruhan, bagi saya ini adalah kasus yang jelas dari perubahan ember 3: perubahan yang secara teknis melanggar yang memecah sangat sedikit kode yang ada sambil menawarkan manfaat nyata (atau, sebaliknya, menghindari sakit kepala abadi karena perilaku yang tidak terduga).

Committee-Reviewed Issue-Enhancement WG-Language

Komentar yang paling membantu

@rjmholt , sementara saya pikir kita semua dapat menghargai betapa rumitnya perubahan seperti ini _dalam prinsip_, dalam kasus khusus ini tidak masalah _dalam praktik_, dan saya rasa aturan PSSA bahkan tidak diperlukan:

  • Analisis @ThomasNieto telah menunjukkan bahwa - jika kami percaya korpus mewakili semua kode PowerShell di luar sana - bahwa _hampir tidak ada yang menggunakan variabel dengan nama yang diakhiri dengan ? _.

  • Jika saya menebak, kebanyakan orang bahkan tidak akan _berpikir_ untuk menggunakan nama variabel seperti itu, karena mereka tidak mengharapkannya berfungsi (termasuk saya), dan mungkin bahkan tidak memperhatikan pengecualian bahwa $? variabel merupakan (yang namanya sama-sama merupakan pengecualian dalam shell yang kompatibel dengan POSIX seperti bash ).

    • Faktanya, melihat lebih dekat pada analisis @ThomasNieto mengungkapkan bahwa, di antara file 8 terdaftar:

      • 5 hanya berisi _false positives_, yaitu variabel yang digunakan di dalam _string_ seperti "Are you sure you want to kill $vParam?" - sebenarnya, penggunaan ini _broken_, dan mengungkapkan bahwa penulis skrip _tidak_ mengharapkan ? menjadi bagian dari nama variabel.

      • 2 dari file tersebut tidak lagi tersedia untuk umum.

      • Hanya _1_ dari mereka yang dapat digunakan secara bonafide dari ? -variabel akhir - sebagai variabel _Boolean_ (misalnya, $key1? ), yang, sebagai tambahan, oleh karena itu _not_ digabungkan dengan operator akses anggota , . /cc @stevenayers.

Berdasarkan hal di atas, ini menurut saya sebagai buku teks Bucket 3: Perubahan

_Mendokumentasikan_ perubahan perilaku (dengan alasan) sudah cukup.

Tentu saja:

  1. ini didasarkan pada (a) analisis yang benar dan (b) korpus yang tersedia untuk umum menjadi perwakilan.

  2. itu sangat bertentangan dengan klaim komite bahwa "ada sedikit penggunaan nama variabel yang diakhiri dengan tanda tanya" (yang, tentu saja, hanya akan menjadi masalah jika nama variabel tersebut tidak disertakan dalam {...} ).

Melanjutkan asumsi bahwa 1. benar (kami belum mendengar apa pun untuk mendukung 2.), kami memiliki dua opsi:

  • Lepaskan band-aid dan cukup larang ? dalam nama variabel ke depan, kecuali jika diapit {...} (dengan pengecualian yang jelas dari $? ) - ini akan merusak yang semakin kecil proporsi skrip yang saat ini mengandalkan itu.

    • Yaitu, sesuatu seperti $key1? yang tidak diikuti oleh . atau ? ( $key1??'else' ) atau ekspresi ternary ( $key1?1:0 ) akan menyebabkan _parser error_.

      • Seperti yang ditunjukkan oleh contoh null-coalescing dan operator ternary, mereka juga akan mendapat manfaat dari perubahan ini - saat ini, Anda memerlukan _space_ - $key1 ?1:0 / $key1 ??'else' - atau {...} - ${key1}?1:0 / ${key1}??'else'

    • Di dalam _expandable strings_, ? tidak akan lagi dianggap sebagai bagian dari nama variabel (non- {...} -tertutup), jadi kita sebenarnya akan _memperbaiki_ skrip yang ada yang salah menggunakan string seperti "Are you sure you want to kill $vParam?" . 😁
  • Jika kami benar-benar merasa perlu untuk menghindari pemecahan sebagian kecil dari skrip yang ada, kami _dapat_ mempertimbangkan logika yang diusulkan oleh @ExE-Boss , tetapi saya rasa kami tidak ingin memperkenalkan kompleksitas konseptual ini - apalagi kompleksitas implementasi (yang saya tidak bisa benar-benar berbicara).

Semua 53 komentar

Untuk memperjelas, tonggak hanya berarti itu adalah sesuatu yang tim harus diskusikan berdasarkan umpan balik, bukan karena kami berkomitmen untuk membuat perubahan ini.

@mklement0

? seharusnya tidak pernah diizinkan sebagai bagian dari pengenal tanpa melampirkannya di {...}.

Ummm - bahasa dasar awal untuk PowerShell adalah Posix Shell yang menggunakan $? untuk kode keluar qed '?' diperbolehkan dalam nama variabel yang tidak dikutip.

itu tidak dapat (berarti) berjalan di versi yang lebih lama

Tentu bisa:

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

Tentu bisa:

Itu tidak dapat berjalan secara bermakna _dengan semantik_ baru (akses bersyarat nol) - hanya itu yang ingin saya katakan.

Ya, contoh Anda saat ini berfungsi, tetapi _dengan semantik yang berbeda_ ( abc? _termasuk ? _ dianggap sebagai nama variabel) - tetapi untuk alasan yang dinyatakan kasus sudut ini layak ditinggalkan demi pembuatan ?. bekerja seperti yang diharapkan.

Bahasa dasar awal untuk PowerShell adalah Posix Shell yang menggunakan $? untuk kode keluar

$? adalah _exception_ dalam shell seperti POSIX; Anda dapat _tidak_ melakukan hal berikut:

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

(Dan, jelas, tidak ada yang meminta $? dihapuskan di PowerShell.)

Dan, tentu saja, harus disebutkan, bahwa _semua variabel otomatis lainnya_ dalam ruang yang sama dengan $? (yaitu, $^ dan $$ ) secara eksplisit khusus- dimasukkan ke dalam tokenizer. Dan, faktanya, begitu juga $? , meskipun (saat ini) tidak perlu.

Tampak jelas bagi saya bahwa diharapkan pada saat kode itu ditulis bahwa ? tidak akan menjadi karakter pengenal yang valid.

Saya hanya tahu satu orang yang telah menggunakan ? di akhir nama variabel dalam skrip mereka, dan itu adalah @StartAutomating. Karena dia benar-benar menggunakan sintaks itu, saya pikir itu layak untuk menarik perhatiannya ke diskusi ini.

Juga @vexx32 , alasan $? adalah case khusus di tokenizer adalah karena Anda tidak dapat membuat variabel dengan nama yang dimulai dengan ? . misalnya $??? = 'foo' tidak akan diurai. Nama variabel harus dimulai dengan karakter alfanumerik atau garis bawah, dan saat ini dapat berisi karakter alfanumerik, garis bawah, atau, tanda tanya. Saya setuju bahwa ?. harus diuraikan sebagai operator akses anggota bersyarat nol, tetapi saya ingin mengklarifikasi mengapa ? -case khusus di tokenizer.

Terima kasih telah menarik perhatian saya ke obrolan ini.

Untuk apa nilainya, saya punya beberapa pemikiran:

  1. Meskipun variabel ini jarang terjadi, tidak ada yang mau bermain whack-a-mole ketika back-compat merusak skrip mereka
  2. Selain orang-orang yang sangat culun, saya berharap ${obj}?.Method() atau $obj?.Method() akan mendapatkan sedikit peningkatan. Ada satu dekade panduan di web tentang cara mengelola null di luar sana, dan saya tidak melihat banyak orang beralih dari if ($obj) { $obj.Method() } _hanya untuk ikut-ikutan v7_
  3. Selain itu, kebanyakan orang yang memiliki masalah dengan nama variabel yang tidak diharapkan mempelajari sintaks ${} (Anda sudah melakukannya secara alami dengan garis bawah). Saya berharap diagram venn tumpang tindih dari "orang yang ingin menggunakan fitur ini" menjadi "orang yang sudah mengetahui sintaks ${}" mendekati 100%
  4. Karena sintaks tersebut tidak sekuat subekspresi penuh, dan subekspresi penuh berfungsi baik di inti maupun tidak, saya berharap kebanyakan orang akan terus menggunakan ini ke depan.

Jadi, menjalankan matematika, ada beberapa alasan konkret _tidak_ untuk melakukan ini, dan hanya satu alasan yang tidak jelas untuk melakukan ini (ini _mungkin_ lebih mudah, untuk beberapa pengguna). Mengingat rendahnya prevalensi ? dalam nama variabel, Anda _mungkin_ membantu lebih banyak orang daripada merugikan Anda, tetapi menurut saya itu adalah lemparan koin.

Mengingat potensi keuntungan lempar koin seperti itu, saya akan mengutip Robert McNamara "Jika kita terkutuk jika kita melakukannya dan terkutuk jika tidak, saya akan memilih terkutuk jika kita tidak melakukannya".

Saya sarankan melakukannya agar $obj?.Method() berfungsi sebagai $<var i="6">obj</var> ?. <var i="9">Method</var>() secara default, dan hanya kembali ke $<var i="11">obj?</var> . <var i="14">Method</var>() ketika $obj tidak ada dalam cakupan, tetapi $obj? ada dan #requires ‑Version bukan v7+.

@ExE-Boss, sepertinya banyak pengecualian untuk aturan khusus ini.

Saya ulangi pertanyaan saya tentang nilai aturan khusus ini.

Setelah itu, pertanyaannya adalah "apa lagi yang tidak kita ketahui tentang sintaks variabel yang mungkin kita rusak?"

Jika konsensusnya adalah memaksa sintaks ${...} untuk ini, dukungan untuk OptionalFeatures akan dihargai di sini, sehingga orang-orang seperti saya yang akan menggunakan sintaks ini (saya akan menggunakannya _a lot_) dapat memilih keluar dari kebisingan .

Karena kami memparafrasekan di sini:
"Logika dengan jelas menyatakan bahwa kebutuhan banyak orang lebih besar daripada kebutuhan segelintir orang." - Spock

Jadi, menjalankan matematika, ada beberapa alasan konkret _tidak_ untuk melakukan ini, dan hanya satu alasan yang tidak jelas untuk melakukan ini (ini _mungkin_ lebih mudah, untuk beberapa pengguna).

@StartAutomating : Ada beberapa alasan, dan itu konkret, tidak kabur. Juga, salah satu tujuannya adalah kesederhanaan kode. Harus membungkus nama variabel dengan {} bekerja secara langsung terhadap tujuan itu.

Saya bersama @mklement0 dan @KirkMunro dalam hal ini. Secara pribadi saya menemukan sintaks ${...}? kompleks yang tidak wajar dan tidak perlu. Kami sudah memiliki perubahan yang melanggar dan dalam hal ini adalah harga kecil yang harus dibayar sebagai ganti kejelasan.

@MulaiOtomatis

  1. Selain itu, kebanyakan orang yang memiliki masalah dengan nama variabel yang tidak diharapkan mempelajari sintaks ${} ( Anda sudah melakukannya secara alami dengan garis bawah ). Saya berharap diagram venn tumpang tindih dari "orang yang ingin menggunakan fitur ini" menjadi "orang yang sudah mengetahui sintaks ${}" mendekati 100%

Ini tidak tahan. Garis bawah adalah karakter yang valid dalam nama variabel.

@vexx32

Tampak jelas bagi saya bahwa itu diharapkan pada saat kode itu ditulis

Tidak.

Tukar karakter di sekitar? $foo.?Property terlihat tidak bentrok, karena nama properti yang diawali dengan tanda tanya sudah perlu dikutip:

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 , sayangnya, itu akan mengundang kebingungan abadi dengan sintaks ?. digunakan dalam C# dan beberapa bahasa lain (juga, Anda perlu menemukan bentuk alternatif untuk pengindeks ( ${arr}?[0] ) juga, dan sesuatu seperti $arr[0]? akan mengundang kebingungan dengan operator ternary)

Tidak ada solusi yang rapi.

  1. Jumlah orang yang tidak diketahui menggunakan ? di akhir nama variabel. Meskipun ini adalah fitur opsional, seseorang dapat mengatakan "Jangan nyalakan jika Anda menjalankan skrip itu" tetapi orang yang memutarnya harus memeriksa skrip saat ini dan yang akan datang yang mereka dapatkan dari sumber apa pun.
  2. Sintaks alternatif bukan pilihan yang bagus karena mengimpor sesuatu yang tidak terlalu kuat dari C#
  3. Mengubah perilaku berdasarkan #requires tidak berfungsi di luar skrip yang disimpan, dan akan gagal segera setelah seseorang menyalin beberapa kode dari skrip panjang tanpa menyetel tag.
    4. (dir *.ps2)?.count dan (dir *.ps1)?.count menunjukkan bahwa operan tidak harus berupa variabel.
    ($Host)?.toString() / ($null)?.toString() menghilangkan kebutuhan untuk memasang kurung kurawal di sekitar nama. Ini masih penekanan tombol ekstra, tetapi lebih logis dan kurang jelek.
  1. Mengubah perilaku berdasarkan #requires tidak berfungsi di luar skrip yang disimpan, dan akan gagal segera setelah seseorang menyalin beberapa kode dari skrip panjang tanpa menyetel tag.

Ini berlaku untuk kode _any_ yang menggunakan fitur yang tidak didukung di versi sebelumnya.
Jika ini adalah masalah utama, tidak ada fitur bahasa baru atau parameter cmdlet/cmdlet baru yang akan diperkenalkan.

(Mudah-mudahan, dalam kode yang lebih lama Anda memiliki setidaknya Set-StrictMode -Version 1 berlaku, dalam hal ini $var?.foo akan gagal dengan keras, karena tidak ada variabel bernama var? ada).

  1. menghilangkan kebutuhan untuk memasang kawat gigi di sekitar nama.

Mengganti (...) untuk {...} hanyalah peningkatan kecil.

Apa pun sintaks tambahan yang digunakan, masalahnya di sini adalah _kebutuhan_ untuk sintaks tambahan - untuk sesuatu yang seharusnya berfungsi _apa adanya_ - tidak hanya untuk kenyamanan mengetik tetapi juga untuk memenuhi _harapan yang masuk akal_.

  1. Mengubah perilaku berdasarkan #requires tidak berfungsi di luar skrip yang disimpan, dan akan gagal segera setelah seseorang menyalin beberapa kode dari skrip panjang tanpa menyetel tag.

Ini berlaku untuk kode _any_ yang menggunakan fitur yang tidak didukung di versi sebelumnya.
Jika ini adalah masalah utama, tidak ada fitur bahasa baru atau parameter cmdlet/cmdlet baru yang akan diperkenalkan.

Bukan itu yang saya maksud. Lebih lanjut ada saran bahwa jika #requires ditentukan pwsh 7 maka pemrosesannya mungkin berbeda. Menyalakan perilaku baru hanya jika Anda memasukkan #requirestidak baik.

(Mudah-mudahan, dalam kode yang lebih lama Anda memiliki setidaknya Set-StrictMode -Version 1 berlaku, dalam hal ini $var?.foo akan gagal dengan keras, karena tidak ada variabel bernama var? ada).

Dalam pengalaman saya tidak banyak menggunakan Set-Strictmode. Karena (a) ada anggapan bahwa default tanpanya adalah "benar" dan (b) frekuensi penggunaan barang yang mengandalkannya dimatikan terlalu tinggi. Ini adalah penggunaan umum untuk operator ini. Bagaimanapun masalahnya adalah kode yang lebih lama di mana $var? memang ada dan memiliki properti foo, tetapi sekarang kode mencari $var ... Mungkin pemrosesan baru akan menyebabkan kesalahan JIKA strictmode disetel karena $var tidak ada....

  1. menghilangkan kebutuhan untuk memasang kawat gigi di sekitar nama.

Mengganti (...) untuk {...} hanyalah peningkatan kecil.

Ya. ($x) sedikit lebih baik dari ${x} tetapi hanya sedikit. ( Get-user "Bob")?.disable() lebih baik dari

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

Apa pun sintaks tambahan yang digunakan, masalahnya di sini adalah _kebutuhan_ untuk sintaks tambahan - untuk sesuatu yang seharusnya berfungsi _apa adanya_ - tidak hanya untuk kenyamanan mengetik tetapi juga untuk memenuhi _harapan yang masuk akal_.

Ya.
$var. foo Dengan karya spasi putih. ${foo} ?.bar() tidak karena ? diperbolehkan dalam fungsi atau nama alias (?. legal untuk keduanya). Memutar bit sintaks C# ke dalam aturan sintaks yang ada tanpa melanggar hal-hal tidak selalu praktis Kadang-kadang, "Ini tersedia di C#..." benar-benar layak mendapat jawaban "Ya. Anda tahu di mana C# jika Anda menginginkannya".
:-)

Untuk menjaga kompatibilitas SemVer , ini harus dilakukan dalam rilis utama (sebaiknya 7.0.0 ).

Lihat juga saran saya di atas ( https://github.com/PowerShell/PowerShell/issues/11379#issuecomment-566756120 ).

@ExE-Boss Ya, itu adalah komentar Anda yang saya maksud ketika saya mengatakan tergantung pada #requires mungkin bukan ide yang baik kedengarannya pada awalnya.
Dan ya, jika seseorang ingin memecahkan skrip yang ada, waktu yang harus dilakukan adalah ketika versi utama berubah, jadi ini perlu dilakukan dengan cepat atau menunggu V8

Ini masih merupakan fitur eksperimental dan dinonaktifkan secara default di RC-1 , yang saya asumsikan akan tetap sama untuk produk pengiriman. Itu memungkinkan perilaku yang akan diubah (atau bahkan menjadi fitur kedua percobaan) - itu juga harus memblokir / memperingatkan ketika mencoba untuk membuat sebuah variabel berakhir dengan karakter tertentu. Jika saya mengaktifkannya dan kemudian ingin menggunakan skrip dengan nama variabel yang salah yang menempatkan tanggung jawab pada saya - tentu saja itu berarti skrip yang saya unduh yang melakukan itu hanya terlihat "rusak" yang lebih dapat ditoleransi di bawah spanduk "eksperimental".

Saya bukan pengembang PowerShell yang serius; Saya datang ke sini untuk mencari solusi untuk bug dan kebetulan menemukan masalah ini. Untuk skrip baris perintah, saya kebanyakan menggunakan bash. Saya mungkin berada dalam demografi yang coba diyakinkan oleh Microsoft untuk beralih ke PowerShell Core: pengembang lintas platform yang membutuhkan bahasa skrip cepat yang tidak terlalu merepotkan daripada bash.

Saya sering menemukan banyak keputusan yang terkait dengan sintaks PowerShell tidak intuitif bagi orang-orang yang bukan pengembang PowerShell. Terakhir kali saya menggunakan PowerShell untuk sesuatu yang serius, saya terkejut dengan kurangnya operator penggabungan nol, atau bahkan operator ternary yang bisa saya gunakan -- yang mengakibatkan saya memposting jawaban PowerShell yang populer ini di Stack Overflow . Itu terjadi pada tahun 2013, dan itu dengan mudah menjadi salah satu dari tiga alasan utama saya menghindari PowerShell sejak saat itu. Inti dari bahasa skrip adalah saya menginginkan sesuatu yang cepat dan kotor dengan banyak sintaksis gula, bukan pernyataan if-else yang bertele-tele.

@StartAutomating berkata:

Selain orang-orang yang sangat culun, saya berharap ${obj}?.Method() atau $obj?.Method() akan mendapatkan sedikit peningkatan. Ada satu dekade panduan di web tentang cara mengelola null di luar sana, dan saya tidak melihat banyak orang beralih dari if ($obj) { $obj.Method() } hanya untuk ikut-ikutan v7

Saya hanya n=1, tetapi sebagai pengembang non-PowerShell, saya sangat tidak setuju. Yang baru ? sintaks adalah sesuatu yang akan saya temukan dengan cukup cepat bahkan sebagai seseorang yang menyentuh PowerShell mungkin sekali setiap beberapa bulan, dan itu pasti akan meningkatkan kemungkinan saya menggunakan PowerShell di masa depan sebagai pengganti alternatif. Jika kemudian saya melihat bahwa beberapa sintaks {} gila diperlukan untuk kompatibilitas mundur, saya akan memutar mata dan kembali ke apa pun yang sudah saya gunakan.

Saya tidak mengerti penekanan pada kompatibilitas mundur di sini. PowerShell Core sudah memecahkan sebagian besar skrip saya yang ada karena mereka menggunakan bagian .NET yang tidak ada di .NET Core. (Saya tidak mengeluh tentang itu--.NET Core hebat, tetapi jika Anda akan merusak kompatibilitas, sekarang adalah kesempatan Anda.)

Pertama, saya percaya umpan balik awal saya telah menciptakan keributan kesalahpahaman.

Dugaan saya adalah bahwa ${} tidak akan _yang aneh bagi pengembang PowerShell_ , karena mereka sudah harus mengetahui bentuk sintaks ini jika mereka pernah menyematkan variabel dengan ? atau dan menggarisbawahi dalam sebuah string.

Terima kasih atas banyak pengingat bahwa sintaks ini mungkin canggung bagi pengembang non-PowerShell.

Bagian kedua dari umpan balik saya mungkin telah hilang dalam campuran: Karena alternatif lain untuk penggabungan-nol telah ada lebih lama di PowerShell dan digunakan secara luas, saya tidak tahu seberapa banyak peningkatan fitur ini _dengan pengguna PowerShell yang ada_. Anda ingin masuk dan mengatakan "ini adalah satu-satunya hal yang saya perlukan untuk mulai menggunakan PowerShell", dan saya tidak dapat membantah pendapat Anda (meskipun saya mungkin mengatakan Anda kehilangan hutan fitur keren yang mencari pohon bahasa keakraban).

Bagian ketiga dari umpan balik saya tampaknya telah meledak di luar proporsi. Berbicara sebagai salah satu orang yang kadang-kadang menggunakan variabel bernama $IsThisRight? = Test-Something , reaksi pertama saya mendengar berita potensial tentang pembatasan variabel ini adalah "oh well, kira saya harus mengganti nama beberapa variabel, saya tidak mendapatkan banyak untuk itu."

Jadi, untuk mencoba menyatakan kembali dan mengakhiri utas:

  1. IMHO, ${} mungkin bukan sintaks yang aneh untuk _existing_ developer PowerShell
  2. Anda dipersilakan untuk menganggap fitur ini keren; bagi saya ini adalah obat gerbang keakraban bahasa, dan saya akan sangat menyarankan semua orang yang membaca utas ini mempelajari cara mengayunkan penetapan ifs/foreaches/sementara dll.
  3. Sebagai salah satu penulis yang terkena dampak, saya tidak mendapatkan sesuatu yang sangat penting dari ? di akhir variabel saya bahwa saya akan menentang mengubah kode saya.

Atau, untuk lebih singkatnya:

Lakukan perubahan ini jika Anda mau. Saya memiliki kuda kecil dalam perlombaan ini. Jika Anda memutuskan untuk melakukan ini, harap siarkan perubahan dengan jelas sehingga siapa pun yang menamai variabel dengan ? dapat memperbarui sesuai.

Bagian kedua dari umpan balik saya mungkin hilang dalam campuran: Karena alternatif lain untuk null-coalescing telah ada lebih lama di PowerShell dan digunakan secara luas, saya tidak tahu seberapa banyak peningkatan fitur tersebut dengan pengguna PowerShell yang ada.

Saya sangat setuju dengan itu, dan saya tidak ingin meremehkan pendapat Anda. Selalu sulit untuk membuat perubahan seperti itu, terutama ketika alternatifnya mungkin intuitif bagi orang-orang yang sudah menjadi pengguna berat bahasa tersebut.

Anda ingin masuk dan mengatakan "ini adalah satu-satunya hal yang saya perlukan untuk mulai menggunakan PowerShell", dan saya tidak dapat membantah pendapat Anda (meskipun saya mungkin mengatakan Anda kehilangan hutan fitur keren yang mencari pohon bahasa keakraban).

Yah, saya merasa bahwa sebagian besar pengembang non-PowerShell tidak benar-benar berpartisipasi dalam percakapan ini--ini murni kebetulan bahwa saya kebetulan menemukan ini. Penggunaan PowerShell saya kemungkinan akan sangat berbeda dari orang yang menulis perpustakaan dan alat sumber terbuka. Saya pikir saya hanya akan memberikan perspektif seseorang yang menggunakan PowerShell lebih sedikit sebagai kerangka kerja mewah dan lebih untuk menyelesaikan tugas-tugas aneh secepat mungkin. Ini tidak dimaksudkan untuk meremehkan pendapat lain - itu hanya pendapat lain dari perspektif yang mungkin tidak terlalu sering terlihat di sini.

Penanganan nol yang lebih baik bukanlah satu-satunya hal yang saya perlukan untuk mulai menggunakan PowerShell lebih banyak: ini adalah hal kedua. Yang pertama adalah dukungan lintas platform, dan saya sangat terkesan dengan sejauh mana kemajuannya. Secara pribadi, gula sintaksis adalah masalah besar bagi saya ketika saya memilih bahasa untuk melakukan tugas yang diberikan: Saya ingin sintaks membuat apa yang saya lakukan lebih mudah. Jika saya menulis sesuatu yang perlu dipertahankan oleh banyak orang, saya mungkin ingin lebih bertele-tele; tetapi jika saya sedang menulis skrip cepat untuk tugas administratif atau devops, saya hanya ingin cara cepat untuk menguji hal-hal seperti null.

Bagian ketiga dari umpan balik saya tampaknya telah meledak di luar proporsi. Berbicara sebagai salah satu orang yang kadang-kadang menggunakan variabel bernama $IsThisRight? = Test-Something , reaksi pertama saya mendengar berita potensial tentang pembatasan variabel ini adalah "oh well, kira saya harus mengganti nama beberapa variabel, saya tidak mendapatkan banyak untuk itu."

Mendukung kompatibilitas mundur selalu merupakan argumen yang adil. Namun, dalam kasus khusus ini, sepertinya banyak skrip PowerShell berada di ambang kerusakan karena transisi ke Core. Ketika kompatibilitas mundur rusak secara teratur, itu membuat frustrasi, tetapi saya akan mendukung perubahan apa pun yang terjadi sekaligus, yang berarti ini mungkin saat yang tepat.

Dalam skenario di mana Anda mencoba menargetkan demografis baru--yaitu, pengembang non-Windows-centric--mungkin perlu membuat beberapa perubahan besar untuk bersaing dengan apa yang sudah ada di luar sana.

Jika Anda memutuskan untuk melakukan ini, harap siarkan perubahan dengan jelas sehingga siapa pun yang menamai variabel dengan ? dapat memperbarui sesuai.

Untuk lebih jelasnya, saya baik-baik saja dengan perlu ikut serta dalam fitur--itu tidak akan menghalangi saya untuk menggunakan PowerShell. Saya sudah terbiasa membutuhkan banyak perintah set di bagian atas skrip bash saya. Saya tidak akan menganggapnya ideal, tetapi itu akan berdampak kecil pada keputusan saya untuk menggunakan PowerShell selama itu didokumentasikan dengan baik.

Secara pribadi, gula sintaks adalah masalah besar bagi saya ketika saya memilih bahasa untuk melakukan tugas yang diberikan

Maka Anda telah datang ke bahasa yang tepat! PowerShell adalah sakarin positif dengan gula sintaksis.

Untuk mengedukasi mereka yang tidak tahu, Anda dapat "null coalese" beberapa cara di PowerShell:
~$ListWhereNotNull = $null, 1, 2, $null, 3 -ne $null # Ini akan memeriksa bahwa setiap item bukan null, dan mengembalikan daftar 1,2,3$FirstNonNull = @($null, 1, $null,2 -ne $null)[0] # Ini akan mengembalikan non-null pertama$lastNonNull = @($null, 1, 2, $null -ne $null)[-1] # Ini akan mengembalikan non-null terakhir, menggunakan indeks negatif$TheObjectPipelineWay = $null, 1, $null, 2 | Pilih-Objek -Pertama 1$TheAssigningForeachWay = foreach ($item dalam $null, 1, 2, $null, 3, 4) {if ($item -ne $null) { $item;



Itu sudah cukup untuk saat ini, tetapi itu harus membuktikan titik pada sintaks bahasa yang memiliki banyak fleksibilitas. Semua demo itu akan berfungsi kembali ke PowerShell 1.0

Namun, dalam kasus khusus ini, sepertinya banyak skrip PowerShell berada di ambang kerusakan karena transisi ke Core.

Dalam hal ini Anda salah. Core sebenarnya memiliki sangat sedikit perubahan sintaks, dan lebih banyak modul daripada yang Anda kira berfungsi dengan baik pada inti (+- beberapa masalah dengan jalur/baris baru Linux vs Windows). Dalam istilah yang lebih praktis, modul Anda cenderung tidak berfungsi di Core jika Anda memiliki semacam ketergantungan API khusus platform Windows (misalnya saya tidak akan menahan napas untuk membuat pembungkus WPF saya berfungsi di Linux).

Saya masih baik-baik saja dengan perubahan sintaks: Saya hanya merasa bahwa dua pernyataan dalam balasan terbaru perlu ditangani dan dipanggil.

Re: Gula sintaksis, pikiran sarkastik saya mengutip film "Snatch": "Saya sudah cukup manis"
Re: melanggar potensi perubahan di Core: Kami memiliki sedikit sekarang, dan mari kita tetap seperti itu sebanyak yang kita bisa.

@StartAutomating : Apakah Anda mengatakan saya tidak bisa menembak? karena masih ada tempat untuk gula lagi kurasa

Untuk mengedukasi mereka yang tidak tahu, Anda dapat "null coalese" beberapa cara di PowerShell:

Saya memang memikirkannya (itu jawaban saya sendiri yang saya tulis), tetapi rasanya seperti sampah. Ini adalah ide keren dengan banyak potensi, tetapi seperti yang ditunjukkan oleh salah satu komentator pada jawaban Stack Overflow itu, evaluasi tidak korslet. Operator ?. berarti bahwa ini biasanya tidak lagi menjadi masalah saat merantai panggilan/properti. Kembali pada tahun 2013, meskipun, itu tidak tersedia--dan, bahkan kemudian, ada banyak sekali hal yang terjadi dalam contoh-contoh ini, dan Anda dapat melihat di komentar bagaimana orang-orang menganggapnya membingungkan. Saya harus menguraikan dengan tepat apa yang dilakukan contoh-contoh ini simbol demi simbol.

Dalam hal ini Anda salah. Core sebenarnya memiliki sangat sedikit perubahan sintaks, dan lebih banyak modul daripada yang Anda kira berfungsi dengan baik pada inti (+- beberapa masalah dengan jalur/baris baru Linux vs Windows). Dalam istilah yang lebih praktis, modul Anda cenderung tidak berfungsi di Core jika Anda memiliki semacam ketergantungan API khusus platform Windows (misalnya saya tidak akan menahan napas untuk membuat pembungkus WPF saya berfungsi di Linux).

Saya hanya berbicara dari pengalaman dalam hal ini, daripada benar-benar melalui dan mengumpulkan statistik yang tepat. Misalnya, pra-Core, saya dapat membuat kata sandi dengan [System.Web.Security.Membership]::GeneratePassword(32, 6) , tetapi System.Web tidak tersedia di Core. (Saya tahu saya mungkin dapat memuat System.Web.dll yang lama, tetapi saya lebih suka tidak melakukannya jika tidak perlu.) Perubahan sintaks sebenarnya lebih mudah bagi saya untuk diselesaikan daripada API yang hilang. Menghasilkan banyak rahasia Docker untuk devkit sepertinya tempat yang bagus untuk menggunakan skrip cepat, tetapi ternyata lebih bertele-tele di PowerShell Core daripada bash. Tentu saja, solusi bash sering kali terlihat sangat jelek.

Re: Gula sintaksis, pikiran sarkastik saya mengutip film "Snatch": "Saya sudah cukup manis"

Tergantung. Terkadang saya merasa PowerShell luar biasa menyenangkan. Berurusan dengan null adalah salah satu area utama di mana saya biasanya tidak merasa seperti itu--walaupun saya akan mengatakan hal yang sama untuk banyak bahasa. Saya juga menemukan pernyataan if-else PowerShell inline tradisional menjadi rumit dibandingkan dengan operator ternary atau rantai && dan || bash. Karena ini adalah salah satu masalah utama yang menyebabkan saya menjauh dari PowerShell bertahun-tahun yang lalu, saya pikir itu layak disebutkan.

Di sisi lain, saya berurusan dengan berbagai macam bahasa setiap hari, dan apa pun yang saya tulis, saya selalu berpikir, "ini akan jauh lebih mudah dalam bahasa X!"--dan kemudian kapan Saya menggunakan bahasa X, saya berpikir, "ini akan jauh lebih mudah dalam bahasa Y!" Tapi hei, jika saya mendapat kesempatan untuk mengatakan itu dengan lantang dan mungkin mempengaruhi arah bahasa, saya akan menerimanya.

Saya tidak terlalu tertarik untuk mengubah pikiran di sini, hanya menambahkan perspektif lain.

@StartAutomating : Apakah Anda mengatakan saya tidak bisa menembak? karena masih ada tempat untuk gula lagi kurasa

Saya selalu mencintai saya beberapa gula sintaksis baru! Saya memilih bahasa pemrograman seperti anak-anak yang akan melakukan trik-atau-mengobati di Halloween.

@Zenexer : Saya sangat suka Powershell , saya suka. Saya cukup beruntung untuk melakukan PS secara ekstensif dan setiap hari di tempat kerja. Saya suka fleksibilitas, terutama simbiosis dengan .NET, oh man! Itulah mengapa saya peduli dengan arahnya dan itulah mengapa sintaks ${...}? sangat sulit untuk saya terima.

Poin bagus, tapi izinkan saya mengklarifikasi beberapa hal.

Baik atau buruk, PowerShell hingga saat ini belum menggunakan versi semantik.
Versi utama baru hanya menghadirkan fitur _baru_, dengan komitmen kuat terhadap kompatibilitas mundur.
Perubahan yang melanggar mulai merayap di Core, sebagian dari kebutuhan karena akan lintas platform.
Versi utama v7.0 dipilih untuk menandakan _peningkatan_ dalam kompatibilitas mundur: upaya untuk menyediakan pengganti yang layak untuk Windows PowerShell.

Sementara banyak masalah historis tidak dapat diperbaiki tanpa merusak kode yang ada secara serius dan oleh karena itu hanya dapat ditawarkan sebagai fitur opsional (keikutsertaan),
perubahan pemutusan bucket 3 harus selalu menjadi opsi: lakukan perbaikan/perbaikan yang memiliki _potensi_ untuk memecahkan kode yang ada, tetapi dalam praktiknya tidak mungkin; pada keseimbangan, ada baiknya membuat bahasa menjadi lebih baik.

Seperti yang diperdebatkan dalam OP, kasus yang ada menurut saya sebagai perubahan ember 3; sementara kita tahu bahwa _some_ skrip akan rusak ( @StartAutomating akan tahu cara memperbaiki skripnya), data menunjukkan bahwa kasus seperti itu cukup jarang terjadi.

Kenapa jarang?

Karena menggunakan ? dalam nama variabel tidak terjadi pada kebanyakan orang sama sekali, dan jika ya, mereka seharusnya tidak mengharapkannya berfungsi _tanpa {...} _: Jika semua hal berikut hanya berfungsi dengan {...} , mengapa mengharapkannya berbeda untuk ? ?: . , ; ( : tidak dapat digunakan sama sekali, karena selalu ditafsirkan sebagai pemisah penggerak)

Mengizinkan nama seperti $var? atau $va?r tanpa juga memerlukan {...} adalah permisif yang meminta masalah, dan masalah telah tiba: itu menghalangi evolusi bahasa, seperti dalam kasus ini.

Ada 3 fitur terkait baru (setidaknya terkait dalam bentuk sintaksis) yang terinspirasi oleh C #:

  • Persyaratan ternary - akan menjadi fitur bonafide di 7.0

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

  • Operator penggabungan nol - akan menjadi fitur bonafide di 7.0

    • $var ?? 'default' dan $var ??= 'default'

  • Operator bersyarat nol - masalah yang dihadapi - akan menjadi fitur _eksperimental_ di 7.0

    • $possiblyNull?.ToString()

Semuanya memiliki ? sebagai bagian dari sintaksnya, dan semuanya dipengaruhi oleh beban penguraian $var? lawas, meskipun ?. paling jelas demikian:

  • Meskipun Anda dapat berargumen bahwa sesuatu seperti $var?1:0 hanya menarik bagi pegolf kode, itu akan berfungsi dengan baik jika ? memiliki fungsi sintaksis - saat ini Anda harus menggunakan _spasi_ sebelum ?

  • Sebaliknya, menurut saya masuk akal bagi seseorang untuk mencoba $var??='bar' (mungkin kurang dari $baz = $foo??$bar ), yang saat ini juga membutuhkan ruang.

Artinya, jika kita tetap menggunakan penguraian $var? , kita membebani _tiga_ fitur baru (walaupun pada tingkat yang berbeda), 2 di antaranya sudah tersedia secara umum (bukan eksperimental).

Masalah dengan membutuhkan {...} adalah _bukan_ hanya ketidaknyamanan mengetik: itu sama halnya tentang _tidak mengharapkan kebutuhan untuk itu_ di tempat pertama, dan kemudian _melupakan kebutuhan untuk itu_ (dengan potensi malfungsi yang tidak kentara) - karena itu sangat kontra-intuitif.

@ExE-Boss, saya setuju dengan @jhoneill bahwa menerapkan perilaku bersyarat versi akan bermasalah. Saya tidak berpikir ada kebutuhan untuk membebani mesin dengan casing khusus kompatibilitas mundur dalam kasus ini.

@ mklement0: Ini adalah wajar / kontra-intuitif / Anda-nama-itu. Kurung itu keras, kurung kurawal bahkan lebih keras. Tidak perlu bagi mereka dalam kasus ini.

@mklement0 karena kesepakatan tampaknya akan pecah ... Saya pikir itu ringkasan yang bagus.

Saya belum sepenuhnya menang dengan menambahkan konstruksi C# ke PowerShell. Kami sudah memiliki masalah di banyak tempat yang tidak memiliki cukup simbol pada keyboard. Apakah ">" "Lebih besar dari", atau "mengalihkan ke" ? Apakah "=" tugas atau tes-kesetaraan (bahasa yang berbeda menggunakan := untuk menetapkan atau == untuk kesetaraan). Orang yang melompat antar bahasa akan lupa menggunakan -eq atau -gt dan kita terjebak dengan itu... Apakah + penjumlahan aritmatika, atau rangkaian string/array. * adalah perkalian dan kartu liar. % adalah Modulo dan alias untuk forEach-object.

Miskin ? Apakah alias untuk Where-Object. Dan merupakan nama variabel otomatis. Tetapi coba lakukan Get-Alias ? atau Get-Variable ? ... dan kemudian ia melakukan tugas sebagai wildcard.

Lakukan Get-PSdrive dan Anda melihat "variabel" dll tidak memiliki ":" di akhir nama, menambahkan satu : ke nama menyebabkannya diperlakukan sebagai drive. Kecuali tentu saja Anda merujuk telah menulis "$drive="C" dan mengikutinya dengan "$drive:temp" Siapa pun yang baru mengenal PowerShell (dan beberapa tangan lama, ketika mereka tidak memikirkannya) akan bingung mengetahui bahwa mereka' baru saja menemukan ruang lingkup bernama "drive".

Jadi bertentangan dengan itu ... orang mungkin berkata 'Buat sintaks baru dengan penggunaan lebih lanjut untuk ":" dan "?" kamu gila?'
IIRC, di twitter @BrucePay menggambarkan operator ternary sebagai "Tidak terlalu PowerShelly" dan saya cenderung setuju. Tapi suara "Jadikan lebih seperti C#" memenangkan hari ...

Kebanyakan orang akan menulis $PSEdition.length -gt 2
tetapi $PSEdition. length-gt2 juga berfungsi (Anda bahkan dapat memiliki jeda baris di antara dua bagian.) "." juga kelebihan beban yang berfungsi sebagai "direktori saat ini", "jalankan dalam lingkup ini" dan "anggota" Namun di PS V1-V5 saya tidak dapat memikirkan operator mana pun yang memerlukan spasi; "." ganjil dalam melanggar jika satu _is_ hadir. Tapi, untuk mengurai, operator ternary _might_ membutuhkan spasi
$host.debuggerEnabled?0:1 tidak masalah karena "?" diasumsikan _not_ menjadi bagian dari properti
$IsCoreCLR?0:1 bukan karena "?" diasumsikan sebagai bagian dari nama variabel.

Hal yang sama berlaku untuk operator penggabungan nol
$null?? "default" membutuhkan spasi $true.length?? "default" tidak.

Letakkan kasus penggunaan asli di bagian atas masalah ke satu sisi sejenak. Kasus di atas menunjukkan bahwa ada sesuatu yang tidak berjalan dengan baik. Itu akan diperbaiki jika nama variabel mengandung "?" perlu diberi tanda kurung seperti nama yang mengandung "." atau "+" atau ":" , dan @StartAutomating siapa pengguna utama "?" dalam nama berpikir itu adalah _break yang bisa ditangani_. Bahkan sebelum kita mencapai anggota nol, sepertinya 'sudah temukan cara untuk melakukannya'

Saya pikir ada jendela waktu yang singkat untuk memasukkan fitur eksperimental yang membutuhkan ? untuk dikuatkan dalam nama, dan jika fitur itu AKTIF - yang mana yang harus menjadi default - semua yang baru? operator harus mengurai sesuai. Hanya jika fitur tersebut MATI, maka parser memerlukan spasi atau kurung kurawal dengan operator ini.. Itu adalah perubahan yang melanggar, beberapa skrip (angka kecil yang tidak dapat diukur) akan rusak kecuali jika ada opsi yang ditetapkan (dan pelarangan nama variabel akan mencegah $IsIt ?.tostring() menjadi kesalahan pertama dalam skrip, jadi skrip harus gagal, tidak berjalan berbahaya). dan idealnya itu tidak boleh terjadi dengan rilis poin (Anda benar tentang PowerShell tidak benar-benar menggunakan sem-ver, tapi itu masih prinsip yang bagus)

Masalah dengan membutuhkan {...} bukan hanya ketidaknyamanan mengetik: ini juga tentang tidak mengharapkan kebutuhan untuk itu di tempat pertama, dan kemudian melupakan kebutuhan untuk itu (dengan potensi malfungsi yang halus) - karena itu sangat kontra-intuitif.

Ini adalah poin yang bagus dan sebagian besar yang akan mengganggu saya tentang ${...?} dalam praktiknya. Bahkan jika saya tahu untuk menggunakan {} , ada kemungkinan besar bahwa saya akhirnya akan lupa, dan itu mungkin menghasilkan bug halus yang tidak jelas pada awalnya, karena mungkin masih valid secara sintaksis. $var??='bar' adalah contoh yang bagus untuk itu, meskipun saya biasanya sangat berhati-hati dalam mengatur jarak.

Terima kasih, @jhoneill , itu ilustrasi yang bagus tentang berapa banyak simbol yang melakukan banyak tugas ganda (tiga kali lipat, ...) di PowerShell.
Untuk sebagian besar, setelah Anda mengetahui semua kegunaan, itu bukan masalah, karena alasan berikut:

  • konteks yang berbeda (misalnya, * sebagai operator vs. * sebagai karakter pengganti.)

    • Konteks yang berbeda untuk ? sebenarnya memiliki kesamaan, pada tingkat abstraksi tertentu: Anda dapat membayangkan ? dalam Get-ChildItem | ? Target , $var?.Target , $? , $var ?? 'none' karena semuanya melibatkan semacam _question_ dan karenanya _test_ atau _conditional behavior_.

  • perilaku polimorfik yang masuk akal (misalnya, + melakukan penggabungan dengan string).

Contoh bermasalah adalah & (operator panggilan vs. operator latar belakang), yang digunakan dalam konteks yang sama dengan semantik yang berbeda, hanya bergantung pada _posisi_nya.

Itu akan diperbaiki jika nama variabel mengandung "?" perlu diberi tanda kurung seperti nama yang mengandung "." atau "+" atau ":"

Memang, dan itu perlu diulang: kemampuan untuk menggunakan ? dalam nama variabel tidak akan hilang - tetapi Anda harus menggunakan {...} ke depan: ${var?} = @{ foo=1 }; ${var?}?.foo

Saat Anda mendemonstrasikan, dari sudut pandang seseorang yang _tidak_ mengharapkan ? menjadi karakter yang valid. . untuk sumber titik menjadi pengecualian yang dapat dibenarkan; ? sebagai Where-Object alias membutuhkan spasi setelahnya mungkin mengejutkan (misalnya, gci|?target tidak berfungsi), tetapi nama perintah _do_ perlu dipisahkan dari argumennya dengan spasi putih).

Mampu menempatkan spasi putih antara . dan nama anggota ( $obj. foo ) terutama masuk akal dalam pernyataan multi-baris, meskipun bentuk yang bisa dibilang lebih mudah dibaca - akrab dari bahasa lain - adalah untuk (juga) izinkan spasi _sebelum_ . :

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

Mampu melakukannya akan mencerminkan kemampuan yang baru ditambahkan untuk menempatkan | pada baris _next_:

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

Namun, ini akan menimbulkan ambiguitas yang tidak dapat diselesaikan dengan . sebagai operator sumber titik dan nama perintah yang dimulai dengan . - namun tidak mungkin. (misalnya, . foo pada baris baru dapat berupa akses properti atau perintah yang memberi titik-sumber fungsi atau skrip bernama foo (yang harus dalam $env:PATH ) ; .foo bisa menjadi nama _command_).

RFC kelanjutan multi-baris @ KirkMunro , sementara berfokus pada memungkinkan _commands_ menjangkau beberapa baris, akan memberi kami solusi terbaik berikutnya - lihat https://github.com/PowerShell/PowerShell-RFC/pull/179#issuecomment -498734875.

Adapun fitur eksperimental yang diaktifkan secara default: Untungnya, _preview_ merilis - tetapi tidak merilis kandidat - sekarang aktifkan _semua_ fitur eksperimental secara default; namun, perhatikan bahwa ini terus-menerus diganti jika Anda pernah menjalankan Enable-ExperimentalFeature baik _tanpa_ -Scope atau dengan -Scope CurrentUser dengan fitur apa pun yang Anda aktifkan di sana.

@mklement0 Sementara saya pada dasarnya setuju dengan semua itu, saya khawatir kita mungkin akan sedikit menggagalkan diskusi khusus ini dengan potongan-potongan tambahan yang Anda miliki di sana; jika Anda ingin membahas kelanjutan baris di sekitar operator properti titik, Anda mungkin ingin membuka masalah baru untuk itu jika belum ada. 🙂

Saya setuju bahwa terus mengizinkan ? sebagai karakter nama variabel normal paling membingungkan bagi pengguna, karena penggunaan karakter tiba-tiba membuat hal-hal menjadi sensitif spasi, dan setidaknya secara historis, saya tidak berpikir nama variabel memiliki _ever_ sensitif terhadap spasi di masa lalu.

Memperkenalkan ambiguitas itu, menurut saya, lebih merupakan masalah daripada membuat perubahan yang melanggar dan melarang ? digunakan dalam nama variabel. Dengan perubahan yang melanggar, kita dapat dengan mudah membuat aturan PSSA untuk mengingatkan penulis bahwa sintaks tidak lagi diizinkan. Namun, kebalikannya tidak begitu mudah benar, dan tidak seperti perubahan yang melanggar, itu tidak selalu salah; itu dapat dengan mudah berakhir dengan pengguna yang secara tidak sengaja merujuk variabel yang salah secara diam-diam, tanpa mengetahui apa yang mereka lakukan.

@PowerShell/powershell-committee membahas ini, kami telah menganalisis kumpulan skrip PowerShell dan ada sedikit penggunaan nama variabel yang diakhiri dengan tanda tanya. Dengan demikian, kami tidak dapat mematahkan orang-orang itu dan kurung kurawal di sekitar nama variabel PowerShell adalah fitur bahasa yang ada untuk membedakan nama variabel dari karakter lain (seperti di dalam string).

kami telah menganalisis kumpulan skrip PowerShell dan ada sedikit penggunaan nama variabel yang diakhiri dengan tanda tanya

Terima kasih, @SteveL-MSFT - dapatkah Anda membagikan hasil analisis ini?

Ya, saya akan penasaran untuk melihat beberapa dari itu, karena saya sadar beberapa anggota komunitas melakukan analisis mereka sendiri dan tidak mendapatkan hasil yang mendekati seperti itu.

Saya juga ingin melihat hasil dan metode yang digunakan. Saya melakukan analisis saya sendiri tentang PowerShell Corpus tadi malam menggunakan AST yang membutuhkan waktu hampir 6 jam untuk diselesaikan di mesin saya. Ada sejumlah kecil file yang tidak dapat diuraikan karena Windows Defender mengkarantina file tersebut.

Saya menemukan 11 nama variabel unik di 8 file yang diakhiri dengan tanda tanya (tidak termasuk $? yang muncul 8846 kali). Ada total 1.895.983, variabel unik di 408.423 file. Itu berarti 0,0006% dari semua variabel PowerShell unik dalam korpus memiliki nama variabel yang diakhiri dengan tanda tanya.

Berikut adalah 8 file dan 11 variabel unik:

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

Ini adalah skrip yang digunakan untuk membuat laporan:

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
    }
}

Beri tahu saya jika ada masalah dengan metode yang digunakan untuk membuat laporan ini. Berikut adalah contoh script yang digunakan untuk menguji audit.

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

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

Hasil dalam:

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

Seperti yang mereka katakan di kelas matematika, "tolong tunjukkan pekerjaanmu"

Detektif yang luar biasa ,

Saya pikir Anda berpotensi menghilangkan lebih banyak kasus, mengingat formulir ${...} akan terus bekerja dengan perubahan yang diusulkan - misalnya, hanya $isAwesome? perlu kita khawatirkan, bukan ${isAwesome?}

Dengan file contoh Anda:

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

kami hanya mendapatkan:

$isAwesome?
$isabc?
$adce?

Artinya, ${def?} dan ${is a bad var name?} tidak perlu dipertimbangkan.

PS: Mungkin juga lebih baik menggunakan $PSItem | Get-Content -Raw untuk membaca seluruh skrip sebagai satu string.

@ mklement0 Itu benar, saya menambahkan kasus-kasus itu tepat sebelum memposting untuk memastikan skrip tidak mengecualikan variabel dengan notasi kurung kurawal bersama-sama.

Setelah memperbarui skrip dengan rekomendasi Anda, file pengujian menghasilkan output berikut seperti yang kami harapkan.

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

Saya menjalankan skrip yang diperbarui pada 8 file itu dan tidak ada yang menggunakan notasi kurung kurawal sehingga hasilnya masih 11 variabel unik yang akan terpengaruh dengan perubahan yang diusulkan.

Skrip yang diperbarui:

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
    }
}

Terima kasih, @ThomasNieto - Saya berharap kami bisa menurunkan persentasenya menjadi 0,0005%... (bercanda).

Jadi panitia pasti menggunakan yang berbeda - pribadi? - badan.

Jadi, selain memutuskan masalah yang dihadapi, muncul pertanyaan: apakah corpus yang tersedia untuk umum perlu diperbarui? Apakah resmi dipertahankan (saat ini tanggal 26 Juli 2017)?

@SteveL-MSFT, bisa tolong jelaskan?

@mklement0 Saya membulatkan jadi jika Anda ingin merasa sedikit lebih baik sebenarnya 0,00058%

Di https://github.com/PowerShell/PowerShell-RFC/pull/223#discussion_r318340339 @adityapatwardhan melakukan analisis menggunakan corpus publik yang sama yang saya gunakan dan menghasilkan 62% dengan variabel yang diakhiri dengan tanda tanya. Saya tidak melihat tanggapan tentang bagaimana dia mendapatkan persentase itu. Apakah komite PS menggunakan analisis itu untuk menentukan permintaan ini?

Melihat komentar terkait, saya pikir apa yang @adityapatwardhan mengatakan bahwa _among semua variabel yang memiliki ? di name_ mereka 62% memiliki ? sebagai nama karakter _last_.

Sebaliknya, analisis Anda tentang prevalensi aktual (tanpa kurung kurawal) variabel berakhiran- ? (sebagai persentase dari penggunaan variabel secara keseluruhan) tampaknya jauh lebih relevan.

Pada titik ini, sepertinya panitia hanya mengatakan "kami tidak mau" dan jika itu masalahnya, mengapa memiliki fitur ini jika itu akan menjadi kikuk dan tidak digunakan sebagai hasilnya?

@ThomasNieto juga saya melakukan analisis di suatu tempat di sekitar masalah ini dan mendapatkan hasil yang serupa dengan Anda.

@mburszley Terima kasih telah melakukan analisis Anda. Saya ingin menggunakan metode lain (ast vs regex) untuk mengonfirmasi hasil yang Anda dapatkan tahun lalu.

Saya mendengar Anda, @mburszley , tetapi kembali:

panitia hanya mengatakan "kami tidak mau"

Jika ini benar-benar keputusan _fiat_ - keputusan yang tidak didasarkan pada analisis penggunaan di dunia nyata - itu tidak akan menjadi pertanda baik bagi masyarakat luas, terutama mengingat bahwa alasan _stated_ adalah dasar dalam analisis tersebut.

Dengan demikian, kita harus memberikan kesempatan kepada komite untuk menunjukkan analisis penggunaan dunia nyata yang menjadi dasar keputusan - atau untuk mengenali bahwa analisis tersebut gagal dan mempertimbangkan kembali keputusan tersebut.

Bagaimana dengan saran saya di https://github.com/PowerShell/PowerShell/issues/11379#issuecomment-566756120 ?

Saya sarankan melakukannya agar $obj?.Method() berfungsi sebagai $<var i="9">obj</var> ?. <var i="12">Method</var>() secara default, dan hanya kembali ke $<var i="14">obj?</var> . <var i="17">Method</var>() ketika $<var i="19">obj</var> tidak ada dalam cakupan, tetapi $<var i="21">obj?</var> ada dan #requires ‑Version bukan v7+.

Saya berharap itu akan mengatasi sebagian besar masalah kompatibilitas mundur.

@ThomasNieto

@mklement0 benar, maksud saya di antara variabel yang menggunakan ? , 62% menggunakannya di akhir.

Dari hasil yang ditunjukkan dalam komentar di sini tampaknya semua variabel yang menggunakan ? menggunakannya di akhir. Oleh karena itu proposal untuk membuat perubahan yang tidak melanggar.

Jika syarat {..} dihilangkan maka script akan tetap parse tetapi semantiknya akan berbeda, yang menurut saya sangat berbahaya.

Tentu... tetapi analisis menunjukkan bahwa hampir tidak ada orang yang menggunakannya.

Sama seperti perubahan melanggar lainnya, dapat diumumkan, diperkenalkan sebagai fitur eksperimental untuk sementara waktu, dan kemudian didokumentasikan dan dibawa ke stabil.

Saya tidak melihat alasan untuk merekomendasikan sintaks esoterik ketika ? sebagai karakter pengenal sebenarnya tidak digunakan dalam sejumlah kasus yang signifikan.

Jika persyaratan untuk {..} dihilangkan maka skrip akan tetap diurai tetapi semantiknya akan berbeda, yang menurut saya sangat berbahaya.

Tidakkah Anda juga khawatir tentang orang-orang yang menggunakan ?. seperti yang mereka lakukan di C/C++/C# dan mendapatkan hasil yang salah tanpa indikasi bahwa mereka melakukan kesalahan? Sebagai contoh:

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

Tentu, mode ketat akan menemukan ini, tetapi saya tidak tahu bahwa banyak orang menggunakan mode ketat. Jadi, untuk mencegah sebagian kecil skrip rusak, sepertinya kami menyiapkan banyak orang untuk kegagalan menggunakan ?. . Saya tidak tergila-gila dengan trade-off. Yang mengatakan, saya benar-benar memahami keinginan untuk menghindari melanggar orang bahkan jika itu adalah sejumlah kecil orang.

Mungkin PowerShell membutuhkan yang setara dengan Enable-ExperimentalFeature sebut saja Enable-PSFeature , untuk fitur yang tidak lagi dalam status eksperimental tetapi belum siap untuk diaktifkan secara default . Untuk skrip yang dijalankan dengan kode seperti ini $?.GetType() Anda dapat mulai mengeluarkan peringatan bahwa di masa mendatang ini akan rusak dan Anda harus menggunakan ${?}.GetType() sebagai gantinya. Skrip individu dapat mengaktifkan fitur dengan #requires -version 7.1 -feature PSNullConditionalOperators . Kemudian mungkin setiap kali PS 8 hits, fitur tersebut dapat diaktifkan secara default.

Contoh @rkeithhill langsung ke intinya.
Lupakan sejenak apa yang Anda ketahui tentang cara kerja PowerShell hari ini. Ketika kamu melihat

PS> $res?.Length

Sepertinya _name, operator, name_ - yang tentu saja.
Mana yang lebih masuk akal: _"?" adalah bagian dari operator_ , atau _"?" adalah bagian dari nama-element_ pertama?
Jika operator ini diperlukan (dan saya pikir mereka "bukan PowerShelly") ini adalah pilihan antara sesuatu yang akan digunakan secara tidak benar dan sejumlah kecil kerusakan.

Saya akan mulai memasukkan aturan ke psScriptAnalyzer _now_ untuk mengatakan itu gaya yang buruk untuk menggunakan karakter [legal] tertentu dalam nama variabel.

Saya tidak suka Enable-feature . Seseorang memasukkannya ke dalam skrip untuk membuat sesuatu yang ingin mereka gunakan berfungsi, dan skrip lama rusak jika dijalankan setelah skrip baru, (tetapi berfungsi sepanjang waktu). Saya telah melihat _skrip pihak ketiga X gagal setelah menjalankan skrip Y_ karena Y mengaktifkan mode ketat dan X mengandalkannya untuk dimatikan; penulis kedua skrip ada di buku buruk saya.

Saya akan mulai memasukkan aturan ke psScriptAnalyzer sekarang untuk mengatakan itu gaya yang buruk untuk menggunakan karakter [legal] tertentu dalam nama variabel.

Inilah masalahnya: jika Anda mengubah cara PowerShell memberi token pada variabel, PSScriptAnalyzer juga akan melihatnya secara berbeda. Jika Anda memiliki variabel seperti $res? , maka lihat sesuatu seperti ini:

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

Memberi anda

res?

TETAPI, jika Anda mengubah cara PowerShell diuraikan, katakanlah, 7.2, maka Anda akan mendapatkan


Sekarang PSScriptAnalyzer tidak dapat melihat ? , karena itu bukan lagi bagian dari nama variabel (menurut definisi, karena itu adalah perubahan yang kami coba uji). Ini karena PSScriptAnalyzer adalah modul PowerShell dan menggunakan kembali parser yang sama yang dikirimkan di PowerShell. (Dan itu akan benar-benar tidak dapat dipertahankan dan merupakan resep bencana jika mencoba menerapkannya kembali).

Ada beberapa cara untuk mengatasi hal ini, seperti mengompilasi PSScriptAnalyzer secara kondisional (dan mengirimkan seluruh perakitan baru) untuk menguji logika 7.2 baru untuk menyediakan diagnostik yang sama. Tetapi kemudian Anda telah meningkatkan kompleksitas di mana-mana (atau sebagai alternatif menurunkan permukaan pengujian Anda) untuk melayani skenario yang agak kosmetik.

Lebih buruk lagi, semua alat lain di luar sana yang juga mengandalkan AST tidak akan memiliki kapasitas untuk mempertahankan kompleksitas semacam ini bahkan jika PSScriptAnalyzer melakukannya. Kebanyakan orang yang membangun alat penargetan AST di luar sana tidak akan mengkompilasi terhadap versi kecil individual PowerShell untuk kebenaran yang sempurna. Mereka mungkin bahkan tidak akan tahu tentang perubahan kecil seperti itu, terutama karena itu bukan kesalahan dalam versi apa pun; itu adalah bentuk paling berbahaya dari perubahan, di mana satu perilaku diam-diam menjadi perilaku lain.

Pada dasarnya itulah yang membuat perubahan level parser/tokeniser seperti ini lebih berbahaya. Bahkan PSScriptAnalyzer harus berusaha sekuat tenaga untuk memperbaikinya dengan benar, yang berarti mereka harus ditimbang terhadap perubahan yang memberatkan tersebut.

@rjmholt , sementara saya pikir kita semua dapat menghargai betapa rumitnya perubahan seperti ini _dalam prinsip_, dalam kasus khusus ini tidak masalah _dalam praktik_, dan saya rasa aturan PSSA bahkan tidak diperlukan:

  • Analisis @ThomasNieto telah menunjukkan bahwa - jika kami percaya korpus mewakili semua kode PowerShell di luar sana - bahwa _hampir tidak ada yang menggunakan variabel dengan nama yang diakhiri dengan ? _.

  • Jika saya menebak, kebanyakan orang bahkan tidak akan _berpikir_ untuk menggunakan nama variabel seperti itu, karena mereka tidak mengharapkannya berfungsi (termasuk saya), dan mungkin bahkan tidak memperhatikan pengecualian bahwa $? variabel merupakan (yang namanya sama-sama merupakan pengecualian dalam shell yang kompatibel dengan POSIX seperti bash ).

    • Faktanya, melihat lebih dekat pada analisis @ThomasNieto mengungkapkan bahwa, di antara file 8 terdaftar:

      • 5 hanya berisi _false positives_, yaitu variabel yang digunakan di dalam _string_ seperti "Are you sure you want to kill $vParam?" - sebenarnya, penggunaan ini _broken_, dan mengungkapkan bahwa penulis skrip _tidak_ mengharapkan ? menjadi bagian dari nama variabel.

      • 2 dari file tersebut tidak lagi tersedia untuk umum.

      • Hanya _1_ dari mereka yang dapat digunakan secara bonafide dari ? -variabel akhir - sebagai variabel _Boolean_ (misalnya, $key1? ), yang, sebagai tambahan, oleh karena itu _not_ digabungkan dengan operator akses anggota , . /cc @stevenayers.

Berdasarkan hal di atas, ini menurut saya sebagai buku teks Bucket 3: Perubahan

_Mendokumentasikan_ perubahan perilaku (dengan alasan) sudah cukup.

Tentu saja:

  1. ini didasarkan pada (a) analisis yang benar dan (b) korpus yang tersedia untuk umum menjadi perwakilan.

  2. itu sangat bertentangan dengan klaim komite bahwa "ada sedikit penggunaan nama variabel yang diakhiri dengan tanda tanya" (yang, tentu saja, hanya akan menjadi masalah jika nama variabel tersebut tidak disertakan dalam {...} ).

Melanjutkan asumsi bahwa 1. benar (kami belum mendengar apa pun untuk mendukung 2.), kami memiliki dua opsi:

  • Lepaskan band-aid dan cukup larang ? dalam nama variabel ke depan, kecuali jika diapit {...} (dengan pengecualian yang jelas dari $? ) - ini akan merusak yang semakin kecil proporsi skrip yang saat ini mengandalkan itu.

    • Yaitu, sesuatu seperti $key1? yang tidak diikuti oleh . atau ? ( $key1??'else' ) atau ekspresi ternary ( $key1?1:0 ) akan menyebabkan _parser error_.

      • Seperti yang ditunjukkan oleh contoh null-coalescing dan operator ternary, mereka juga akan mendapat manfaat dari perubahan ini - saat ini, Anda memerlukan _space_ - $key1 ?1:0 / $key1 ??'else' - atau {...} - ${key1}?1:0 / ${key1}??'else'

    • Di dalam _expandable strings_, ? tidak akan lagi dianggap sebagai bagian dari nama variabel (non- {...} -tertutup), jadi kita sebenarnya akan _memperbaiki_ skrip yang ada yang salah menggunakan string seperti "Are you sure you want to kill $vParam?" . 😁
  • Jika kami benar-benar merasa perlu untuk menghindari pemecahan sebagian kecil dari skrip yang ada, kami _dapat_ mempertimbangkan logika yang diusulkan oleh @ExE-Boss , tetapi saya rasa kami tidak ingin memperkenalkan kompleksitas konseptual ini - apalagi kompleksitas implementasi (yang saya tidak bisa benar-benar berbicara).

@SteveL-MSFT

Terima kasih telah mendiskusikan masalah ini dalam panggilan komunitas September (https://aka.ms/PSCommunityCall; hingga tulisan ini dibuat, rekaman panggilan September belum diposting di sana, tetapi dapat diakses di https://aka.ms/JoinPSCall, sampai panggilan berikutnya), mulai pukul 46:00, berdasarkan saran @ThomasNieto dalam ajakan sebelumnya untuk topik diskusi di https://github.com/PowerShell/PowerShell-RFC/issues/260 :

(Saya berharap dapat memberikan tautan langsung ke bagian rekaman yang relevan, tetapi itu harus menunggu hingga diposting ke YouTube dan ditautkan ke https://aka.ms/PSCommunityCall.)

Berdasarkan komentar Anda dalam rekaman:

  • Mengingat bahwa Anda menunjukkan kesediaan untuk meninjau kembali ini, silakan buka kembali masalah ini dan beri tag ulang sebagai Review - Committee .

  • Adapun komentar Anda bahwa melampirkan nama variabel dalam kurung kurawal adalah fitur yang sudah ada sebelumnya dan orang-orang keberatan harus menggunakannya dalam kasus ini dengan alasan _esthetic_:

    • Saya tidak berpikir siapa pun di sini _tidak_ menyadari bahwa {...} _can_ dan terkadang _harus_ digunakan untuk membedakan nama variabel.
    • Ini juga bukan tentang _esthetics_, ini terutama tentang _tidak mendapatkan perilaku yang diharapkan_ dengan cara yang _gagal secara diam-diam_, karena _tidak berharap harus menggunakan {...} dalam kasus ini_; kekhawatiran sekunder adalah ketidaknyamanan mengetik.
GitHub
Dokumen RFC (Permintaan untuk Komentar) untuk umpan balik komunitas tentang perubahan desain dan peningkatan ekosistem PowerShell - PowerShell/PowerShell-RFC
Tim Microsoft

Saya khawatir bahwa masalah ini - sekarang tampaknya dalam keadaan tertutup tanpa batas waktu - akan gagal, jadi saya telah membuka #14025 sebagai pengingat untuk mengunjunginya kembali, dan saya mengundang semua orang yang tertarik untuk menunjukkan dukungan mereka di sana.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat