PowerShell -Part 6

■ このスレッドは過去ログ倉庫に格納されています
2022/02/13(日) 18:36:12.07ID:LaQ04ZoE
前スレ
PowerShell -Part 5
https://mevius.5ch.net/test/read.cgi/tech/1615994992/

次スレは>>980が立ててね!!
390デフォルトの名無しさん
垢版 |
2022/06/20(月) 18:28:34.00ID:E6UoKUAB
バッチスレは論外ですな
batやスケジューラの挙動に関して最初から細かく説明していたのですが、どう考えてもガチ支那の五毛っぽいDQNが私の最後のレスを部分的にチラ見しただけで、答えている感じでしたね^^;
冷やかしがオナニーしている状態で、バッチスレの名が泣いていました

原因も提示し、それら打開策などの例や実施結果を挙げつつも、堂々巡りの、それもむっちゃ浅い既出内容をドヤ顔で書き込まれる感じ
バッチスレで唯一のプログラミングスレらしい収穫は「俺だったら.ps1で作る」という言葉、ただひとつのみでしたわorz

あとはなかなかまとまった時間が作れず、もう少ししたらps1版のサービス削除などもネット検索・吟味できそうです

最も盛んでしたwinXP時代にソフトを制作していた年代は今50前後?で開発・更新停止などが相次いでいますよね
そんで2022年現在、高校辺りでプログラミングを必修とする云々が出ている
間が20年くらいスッカラカンなのは日本の経済力低迷を表しているようで大変残念です
そりゃ今の官僚層が自衛隊へ支那産PC送ったりするはずですわ、そんなのが国を回しているんだから^^;
2022/06/20(月) 20:16:43.25ID:+SBlN13D
直接編集しちゃいけないなんてルールはないから好きにしな
無知が無学のまま弄った責任を負わされることを防ぐためのおまじないでしかないよ
2022/06/20(月) 20:23:12.95ID:ItZjQb2L
行き着いた答えがレジストリ書き換えの定期実行だから頭悪いにも程がある
2022/06/20(月) 21:31:17.15ID:yjTGWQu/
俺はちゃんとバッチスレにサービスの設定を変えるコマンドの事書いたぞ
コマンドのドキュメントのリンク付きで

このスレでも他の人が設定変更用のコマンドレットのこと書いてるし
何をどう見てるのやら
2022/06/20(月) 22:24:09.27ID:4G+nodK/
レジストリなんて不整合があれば書き戻されることもあるのでレジストリ弄るだけで解決しない
2022/06/21(火) 00:22:01.55ID:KK61fTqr
てかバッチスレが余りにも低水準かつ五毛全開だったからこそ呆れ、唯一のまともなアドバイスに従ってパワシェへ切り替えようとしているのにさ

わざわざ別スレのリンク貼ったりパワシェスレへ出張(笑)してきたり、ほんま意味不明ですわw

ま、ストーカー云々の類いはリアルもネットも気色悪いですしバッチスレ関係者から得られるものが無いのも経験済み
似た主題なので両方のスレを高頻度で訪問しているのかな、そう思うことにして特定のレスは流し聞きしときますよwww
2022/06/21(火) 00:36:09.32ID:xELEw2uC
Linux なら、systemd とか

Windows の仕組みは知らないけど、
レジストリはその結果を収めたデータベースだから、
結果をいじっても問題解決にはならない

設定は各アプリ製作者が作っているものだから、
製作者以外の人間にできる事は、アプリをアンインストールする事だけ

設定にも様々な依存関係があるから、
アプリの内容も分からない人が、ある設定を変えても、どう作用するか分からない

例えば、アプリのメモリが解放されなくなって、
他のアプリも動かなくなるかも

それに設定を変えても、再起動しないと有効にならないかも知れないし、
再起動すると、設定が元に戻るかも知れない

OS 起動時の処理に、設定読み込みを登録しているかも知れない
2022/06/21(火) 09:15:38.14ID:lQ/zAxwG
ウダウダと一体何の話をしてるんだ
いいからStop-ServiceとSet-Service使えよ
ただ老人がじゃれ合いたいだけなのか?
2022/06/21(火) 11:49:55.72ID:+f2eC/vV
こんな辺境にまでやべーやつ | Out-Null
2022/06/22(水) 20:51:18.50ID:At4JlVSH
>>375
管理者やSYSTEMじゃなくてTrustedInstallerとして実行しても駄目か?
もちろんレジストリをいじるんじゃんなくてSet-Serviceを使うんだぞ
もう見てないかもしれんが
2022/06/22(水) 22:28:41.71ID:OsaOMnRZ
わざわざ召喚しようとする馬鹿発見伝
2022/06/24(金) 13:29:04.40ID:VuoDyj+3
最近foreach文のコレクションの要素を受け取る変数の名前をつけるのが
めんどくさくって
for文のカウンター変数の名前に i を使うのはよくありますが
foreachにも同じような定石ってありますか?
402デフォルトの名無しさん
垢版 |
2022/06/24(金) 13:47:20.90ID:4Qrsm7mD
aオブジェクト名
403デフォルトの名無しさん
垢版 |
2022/06/24(金) 14:25:06.98ID:K2we1Lar
e
2022/06/24(金) 20:56:03.77ID:EMaN3eAt
Item
2022/06/24(金) 23:55:58.07ID:/S8ogjuv
item, element
406デフォルトの名無しさん
垢版 |
2022/06/26(日) 07:43:19.31ID:G39l7ngg
例えば$url = "https://yyyy.xxx/aaa/bbbb/2/";があり、最後の[2/]をカウンタを使ってアクセスしたいとおもいます。
その際、$nextUrl = ($url -replace ".{2}$") + $cnt + "`\"
で行けると思ったのですが、何か間違えていますでしょうか?
407デフォルトの名無しさん
垢版 |
2022/06/26(日) 08:16:14.03ID:JGEtGMnz
-replaceの使い方を間違えてる
408デフォルトの名無しさん
垢版 |
2022/06/26(日) 11:32:39.54ID:G39l7ngg
replaceですか。ありがとうございます
409デフォルトの名無しさん
垢版 |
2022/06/29(水) 00:00:51.24ID:x2p/lm6W
arrayListの使い方がわからない。

----------------------------
$arrayReturn = new-object system.collections.arrayList
$col = new-object PSObject | select "A", "B", "C"

foreach ($i in 1..3) {
$col."A" = $i
$col."B" = $i + 1
$col."C" = $i + 2
$nul = $arrayReturn.add($col)
}

$arrayReturn
----------------------------

上記のコードを実行すると以下のようになってしまう。
A B C
- - -
3 4 5
3 4 5
3 4 5

本当は以下のようにしたい
A B C
- - -
1 2 3
2 3 4
3 4 5

なぜうまくいかないのか謎。
2022/06/29(水) 00:51:19.50ID:cjQj2yfD
$col のnew-object生成をforeach{}内に移動してみては
411デフォルトの名無しさん
垢版 |
2022/06/29(水) 07:19:16.62ID:x2p/lm6W
>>410
うまくいった
はあああああああああああああ!?
なんで!? なんでこれでうまくいくんだ!?

ループの中に入れたら毎回$colの中身が破壊されると思うんですけど????
2022/06/29(水) 08:20:00.62ID:8GN1KOCk
PSObjectは参照型
ArrayListに追加されるのはオブジェクトそのものじゃなくてオブジェクトの参照だけ
2022/06/29(水) 09:10:01.99ID:ofsaM31D
>>412
完全に理解しました。thx
2022/06/29(水) 14:16:08.11ID:SZ5j8L6g
PSReadLine 2.2.6 enables Predictive Intellisense by default
https://devblogs.microsoft.com/powershell/psreadline-2-2-6-enables-predictive-intellisense-by-default/
入力しようとしているコマンドを予測 〜PowerShellで「Predictive IntelliSense」が既定有効に
履歴やプラグインなどを参考に推測できるIntelliSense機能
https://forest.watch.impress.co.jp/docs/news/1420812.html
2022/06/29(水) 21:06:08.62ID:h+5hcb7e
PSCustomObjectは積極的に使っていいものかどうか判断できない
結局C#でクラスや構造体宣言して使った方がいい気がするし
Powershellで作成したPSCustomObjectを、同ソースに埋め込んだC#コード側から参照する方法ってある?
2022/06/29(水) 21:46:04.47ID:4kwBO65f
>>415
dynamic
2022/06/30(木) 01:46:52.84ID:LVSNczoT
>>415
New-Object PSCustomObject や [PSCustomObject]@{} は
Win10 の v5.1 なら Add-Type の C# でなくとも class があるからスクリプトでの使用頻度は下がった。
Win7 の v2 では function NewABC {} みたいなコンストラクタ的な関数用意して積極的に使ってた。

Win10 の今でも ConvertTo-Csv へ渡す前に日時や数値を書式指定して文字列化するために使ってる。
CSV に日本語カラム名が欲しい時に日本語プロパティ名の class 用意するのはなんか気が引けるけど
[PSCustomObject]@{} や Select-Object での誰が見ても短命なオブジェクトなら気にならない。

データだけでメソッドがなく複数作るなら System.Data.DataTable も有り。
.Columns.AddRange([string[]]) でプロパティ(DataColumn)定義して
.Rows.Add([Object[]]) でデータ(DataRow)追加する使い方なら意外と手軽に使える。
日本語カラム名の使用も問題ないし。
418デフォルトの名無しさん
垢版 |
2022/07/06(水) 09:44:42.33ID:L+R7c7Gd
-replaceと-ireplaceの違いって分かりますか?
まだ勉強中ですが、当然のように出てきて両方同じ説明しかされてないので気になって調べてみてもどこにも解説がなくて…
扱える値の範囲が違ったりとかするんでしょうか?
普通はどっちを使うものなんですか?
419デフォルトの名無しさん
垢版 |
2022/07/06(水) 11:05:49.65ID:MXaUuSJv
1.完全に理解した←初心者
2.チョットワカル←中級者
3.全然判らん←上級者
2022/07/06(水) 11:41:17.81ID:HSp/EaB5
>>418
https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.2
既定では、 -replace 演算子では大文字と小文字が区別されません。
大文字と小文字を区別するには、次を使用します -creplace。
明示的に大文字と小文字を区別しないようにするには、次を使用します -ireplace。

replaceの既定動作を変更する方法は知りません。
大文字小文字を区別しようがしまいがどっちでもいいときは replace
そこんとこ間違ってもらっちゃ困るときは ireplace か creplace

普通がどっちかは分かりません。
2022/07/06(水) 13:11:25.93ID:c6fRPAAn
例えば、Ruby のCSV 処理なら、

require 'csv'

input_csv = <<"CSV_TEXT"
id,果物
1,りんご
21,スイカ
33,みかん
CSV_TEXT

# 2次元配列
ary = CSV.parse( input_csv, headers: true ).each do |row|
row[ '果物' ] = "レモン" if row[ 'id' ].to_i == 21
end

p ary.to_a
#=> [ ["id", "果物"], ["1", "りんご"], ["21", "レモン"], ["33", "みかん"] ]
422デフォルトの名無しさん
垢版 |
2022/07/06(水) 13:16:19.97ID:iisDFTgh
>>420
ありがとうございます!
理解できました!
明示的に大文字の区別をつけるかつけないか指定する際に利用するものなんですね!
たしかにそれだと【普通】は場合によるとしか言えないですよね
2022/07/06(水) 20:34:21.87ID:428zggiP
迷ったら明示でいいと思う
2022/07/06(水) 22:49:51.62ID:pVM7wVd2
パワシェルの-replaceは勝手に右辺を正規表現と解釈するから
それが必要ない場合は文字列.Replace()のがいいよ
2022/07/07(木) 08:47:36.53ID:fDYvmpy4
>>423
そうですね!

>>424
おお、知りませんでした。
ありがとうございます!
2022/07/08(金) 13:33:50.89ID:EP1tRVB4
Windowsでコマンドラインシェルとして使う場合に
外部コマンド引数のクオーテーションの振る舞いをなんとかして欲しい

例えばpwshを外部コマンドとして使うとして

pwsh -nop -c "`$a = 'abc'; `$a | out-host"

は期待通り abc が出力されるのに

pwsh -nop -c '$a = "abc"; $a | out-host'

はエラーになるの不便過ぎる
2022/07/08(金) 20:51:35.26ID:Bjqd/A21
補完が有効になってやっとまともに使えるようになったなよくこんなクソ長くて覚え辛くて入力し辛いコマンドレットなんて使ってるよなお前ら
しかしMSって言語やフレームワークでもそうだが命名規則にセンスねーゎ
なんでnpmやgitみたいに使いやすく作れないのか壊滅的にセンスねーゎ
2022/07/08(金) 21:48:06.89ID:SkLqj5eb
互換性のあるエイリアス
https://docs.microsoft.com/ja-jp/powershell/scripting/learn/compatibility-aliases
2022/07/08(金) 22:10:30.33ID:EP1tRVB4
PS> pwsh -nop -c "`$a = 'abc'; `$a | out-host"
abc
PS> pwsh -nop -c '$a = "abc"; $a | out-host'
abc: The term 'abc' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

これほんと何がどうしてこうなるの?
2022/07/08(金) 23:27:21.05ID:UIv0TQaX
pwsh.exeへのコマンドラインとして解釈されるから、まずOSのルールに従って引数リストが次のように分解される
-nop
-c
'$a
=
abc
;
$a
|
out-host'
pwsh.exeの内側でコマンド文字列を再結合した時点では既にダブルクォートが失われているという寸法
2022/07/08(金) 23:35:00.16ID:v6YmQ/+d
PS内で呼び出すならスクリプトブロックでよくね?
2022/07/08(金) 23:40:56.26ID:UIv0TQaX
無茶言うなよ…
pwshの-cより右ならスクリプト扱いで、cmdやその他大勢の右ならOS解釈? pwshという同名のオレオレアプリの類だったときもスクリプト扱い?
言語仕様の一貫性的にあかんことになるだろ常考
2022/07/08(金) 23:49:47.55ID:cCHwpa3p
もしかして
リモートコマンド
2022/07/08(金) 23:52:42.34ID:PFPNTTsE
>>429
「'$a = "abc"; $a | out-host'」の「'〜'」は
そのコマンドライン上の文字列リテラルである事をPowerShellに指示してる事になって
PowerShellは1つの文字列「$a = "abc"; $a | out-host」の事だと受け取る。

コマンドが実行ファイルの実行で、その引数の文字列にスペースがあると
その文字列全体が「"〜"」で括られて文字列「"$a = "abc"; $a | out-host"」になる。
↑Windows PowerShell v5.1のTrace-Commandで確認
↓自信なし
powershell実行時の引数パース時に「\"」とか「"""」とかではない
単独「"」は不正な(余分な)メタキャラとして取り除かれるもよう。
で-cには「$a = abc; $a | out-host」が渡る。

>>430
確か「OSのルール」だと、実行ファイルに渡される引数は単一の文字列で、
スペースで区切ったり「"」を特別扱いするのはpowershell(pwsh).exeの独自のただし非常に一般的な仕様。
(大抵は、exeにコンパイルした際のコンパイラの仕様。)
2022/07/09(土) 00:09:26.45ID:qWQ5DRIr
Linuxのpowershellなら
PS> pwsh -nop -c '$a = "abc"; $a | out-host'
abc
になるんだろうな
2022/07/09(土) 08:04:26.74ID:qWQ5DRIr
コマンドプロンプトで
pwsh -nop -c "$a=\"abc\"; $a | out-host"
とするのは " 内部の " をエスケープするように見えて自然に納得できる
Windows版のPowerShellだけ
pwsh -nop -c '$a=\"abc\"; $a | out-host'
とするのは ' 内部の " をエスケープさせられて気持ち悪すぎる
おまけにLinux版でこう書くと動かないんでしょ
2022/07/09(土) 10:32:21.09ID:d4+i07Ea
>>436
コマンドプロンプト(cmd)だともっと高難易度の問題がある。
cmdのメタキャラ(&, |, <, >など)が偶数番目の「"」の後にあるとだめとか、
powershellコンソール以上に問題有り。
pwsh -nop -c "$a=\"&abc\"; $a | out-host"

同一のシェル名(pwsh)であっても、OSによって他プロセス起動の作法が違うのは仕方ないと思う。
国や地域で言葉や文化が違っても仕方ない感じ。
(POSIXとかに規定あればば別だが。)

例えば「ping」を動かすだけにしても結局オプションも挙動も違う訳だし、
現時点では他プロセス使う時点で、移植性考慮はプログラマの領分かな〜と思ってる。
2022/07/09(土) 10:48:49.98ID:d4+i07Ea
PowerShellのコンソールやスクリプト上で他プロセスを起動したい場合、
自分だとほぼ下記2通り。

(A) System.Diagnostics.ProcessStartInfoを使う。
(ちゃんと制御したい場合。スクリプトだと基本これ。)
$si = [Diagnostics.ProcessStartInfo]::new()
$si.FileName = 'powershell.exe'
$si.Arguments = '-nop -c "$a = \"abc\"; $a | out-host"'
$si.UseShellExecute = $false
$proc = [Diagnostics.Process]::Start($si)
$proc.WaitForExit()

(B) 引数を1つずつ@()に入れ、「"〜"」としたい場合は最初から値に含める。
(コマンドラインとかで手軽に。…手軽?)
& 'powershell' @('-nop', '-c', '"$a = \"abc\"; $a | out-host"')
2022/07/09(土) 10:59:09.60ID:qWQ5DRIr
MSYS2のbashもWindows上のコマンドラインシェルだけど
pwsh -nop -c "\$a = 'abc'; \$a | out-host"
pwsh -nop -c '$a = "abc"; $a | out-host'
のどちらでも動くんだよね
PowerShellには頑張って欲しい
2022/07/09(土) 14:41:14.65ID:OGG0CV73
わざわざProcessStartInfo使うとかめんどくさいわ
Start-Processでいい

Start-Process -FilePath 'powershell.exe' -ArgumentList '-nop -c "$a = \"abc\"; $a | out-host"' -NoNewWindow -Wait
2022/07/09(土) 21:16:37.86ID:d4+i07Ea
ProcessStartInfoが面倒なのは同意。
Start-Processで済む時は使う事もあって
大体はUseShellExecute = $trueの時かな。

Start-Processを使わない一番の理由は-Redirect*がファイルパス指定な事。
出力を無加工でファイル出力したい事がまずないので使いづらい。
なんで-PassThruのProcessオブジェクトの出力制御変更のスイッチじゃないのか。
標準出力・エラーを同時に制御するとデッドロックしやすいからかな。
Start-Processがその辺うまい事制御してくれたらスクリプトでも使うんだけど。
2022/07/09(土) 21:55:59.58ID:0vXUA52p
コマンドラインパラメーターの処理はexeをビルドした処理系のスタートアップコードに依存するのだ
MSのC/C++やMingwとかで微妙に変わってくるのだガハハ
WindowsでC/C++/C#の場合argvとかではなくWin32APIのGetCommandLineで取得するのが一番正解に近い
2022/07/09(土) 22:06:03.52ID:qWQ5DRIr
"" や \" が必要な仕様は気持ち悪いって話をしてたつもりが…
ネイティブコマンドを呼ぶのはコマンドと引数を並べて書くだけが普通でしょ
about_Parsing の icacls を呼ぶ例もそのまま並べてる
そのままと異なる動きをさせたい時以外は、>>438>>440 も面倒すぎる
2022/07/09(土) 22:40:11.92ID:GKrnmeJx
引数のワイルドカードを展開するかしないかみたいなやつね
2022/07/09(土) 23:17:22.46ID:d4+i07Ea
MSもこの辺の気持ち悪さ・分かりづらさは分かってるみたいで
core v7とかだと環境変数かなんかで、パースルール変更できるんじゃなかったっけ。
Win10のv5.1しか使わないから知らんけど。
446デフォルトの名無しさん
垢版 |
2022/07/10(日) 00:25:59.02ID:qiFT6lHF
実行順がわかりにくい
2022/07/10(日) 00:55:31.74ID:KsOikrPY
何言いたいかがわかりにくい
2022/07/10(日) 01:17:57.68ID:KsOikrPY
>>443
> ネイティブコマンドを呼ぶのはコマンドと引数を並べて書くだけが普通でしょ
例えば
$a = "abc"; cmd /c "echo $a"
を実行したら「$a」と出力されて欲しくて
「abc」と出力されて欲しければ>>438,440ってこと?
好みが分かれるところかなー
449デフォルトの名無しさん
垢版 |
2022/07/10(日) 04:27:28.58ID:qiFT6lHF
UNIXのシェルスクリプトのマネにならないようにした結果がこれ
450デフォルトの名無しさん
垢版 |
2022/07/10(日) 04:30:45.24ID:qiFT6lHF
PowerShellは、記号に独自の意味を持たせているから、PowerShell職人を養成しないと使いこなせない。
2022/07/10(日) 09:49:01.94ID:os7PFybL
PowerShell in ActionにはUNIXシェルを参考にしたっていろんな所に書いてあるけど
たとえば比較演算子とか
452デフォルトの名無しさん
垢版 |
2022/07/10(日) 10:20:51.27ID:j6DdFbos
powershellはPerlの匂いがする
俺が好きになった理由はここ
2022/07/10(日) 20:59:21.65ID:KsOikrPY
>>450
記号に独自の意味を持たせてる言語は多数あるのでは。
というか程度の差こそあれ殆どでは。
学習せず「使いこなせる」言語はないでしょ。
2022/07/10(日) 21:53:38.94ID:bG/pnkmn
powershellの記号が特殊とかはあまり思わないな
それより配列の扱いがトリッキーとかの方が職人の養成が必要と思う
2022/07/10(日) 22:11:42.01ID:PiYySnCe
ファイル名に[]が含まれてて苦労した人なのかなと思った
456デフォルトの名無しさん
垢版 |
2022/07/10(日) 22:53:56.17ID:qiFT6lHF
>>453
バッチファイルとの相性が最悪なのに気づかないとは情けないよ、あんた。
457デフォルトの名無しさん
垢版 |
2022/07/10(日) 22:55:51.37ID:qiFT6lHF
>>451
あらゆる言語を参考にして、いろいろ混ぜ込んで、奇妙奇天烈なものになってしまった。
2022/07/10(日) 23:58:19.25ID:RTsqHO1/
まあ最大の問題は、空白をトークンの区切り、改行を入力に終わりとしたことだな
2022/07/11(月) 00:03:16.90ID:bX2QAhdS
変数のスコープが他と違うPowershellには何も期待してない
グローバル変数を更新したつもりがローカル変数と見なされたりして使い難すぎる
グローバルデータを全部.NETのコンテナに逃がしてようやく使えるようになった
460デフォルトの名無しさん
垢版 |
2022/07/11(月) 00:04:59.61ID:vt1vW9IA
ファイルや文字列の操作の構文がヘンテコすぎる
2022/07/11(月) 01:41:49.71ID:4UtqkfgJ
超ヘンテコなJavaScriptだって一世を風靡したんだからPowershellだっていけるし(震え声
462デフォルトの名無しさん
垢版 |
2022/07/11(月) 03:32:17.37ID:vt1vW9IA
>>461
あんたPowerShellをほどんど知らないでしょ?
2022/07/11(月) 07:53:28.56ID:3aArSxtS
>>456
そんな話してなかったでしょ。会話になってないよ。

バッチ(コマンドプロンプト)上でワンライナー書くときに
記号の取り扱いに注意しなくていいメジャー言語は一つも知らない。
2022/07/11(月) 09:42:24.64ID:zwDcIdQY
>>463
個人的にはバッチは制限多過ぎだよね
今回の問題もPowershellというより旧cmm互換性のせいだし
2022/07/11(月) 10:44:52.35ID:KonxbxUI
あんた
あのこの
なんなのさ
2022/07/11(月) 11:27:13.34ID:4o6o7MFx
おらシェル子のこどほどんどしらねっちゃ
2022/07/11(月) 13:10:07.01ID:ekYGS06D
そもそもpsでスクリプト使うならバッチじゃなくてps1だろ
2022/07/11(月) 20:50:06.93ID:M3Mn448S
>>460
どこがどうヘンテコって思い込んでるんだ?
2022/07/12(火) 00:36:46.01ID:XdROtN2x
Perlなんかもヘンテコって思ってれば筋は通る
2022/07/14(木) 22:41:31.83ID:ztzbKaJ8
久々にvbsで書いたらめっちゃ素直でスラスラ書けるわ
Powershellはせめてレキシカルスコープで作り直してくれ
クラス使えって?
2022/07/15(金) 10:39:19.02ID:y/m5s/RL
VBSはクソだろ
https://twitter.com/Benshi_Orator/status/1546400388680945665
https://twitter.com/5chan_nel (5ch newer account)
2022/07/15(金) 12:26:17.41ID:nJv/8gNm
>>470
psだってレキシカルスコープだよ
どういう動作を求めてるのかはしらんけど
2022/07/15(金) 13:13:05.28ID:Wgy0KDme
ダイナミックスコープだったような
2022/07/15(金) 13:20:06.85ID:Wgy0KDme
PowerShellの悲しい点は、関数とスクリプトブロックが動的にスコープされることです。
しかし、私が驚いたもう1つの点は、変数が内部スコープ内でコピーオンライトとして動作することです。
$array=@("g")

function foo() {
$array += "h" Write-Host $array
}

& { $array +="s" Write-Host $array }

foo Write-Host $array

出力は次のとおりです。
g s
g h
g
これにより、動的スコープの苦痛が少し軽減されます。
しかし、どうすればコピーオンライトを回避できますか?
2022/07/15(金) 13:22:56.94ID:Wgy0KDme
これの解決策
([ref]$array).Value += "h"

ちとうんこすぎるね
2022/07/15(金) 14:34:08.02ID:ROJrTMPq
コピーオンライトじゃなくてローカル変数が新しく定義されてるだけでは
動的スコープが嫌ならGetNewClosure()を呼べ

[PSv2]PowerShellでクロージャ&カリー化
https://winscript.jp/powershell/204
ScriptBlock.GetNewClosure Method
https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.scriptblock.getnewclosure
2022/07/15(金) 16:26:41.50ID:mFZqR7Di
せめて問題を理解してからレスしろよ

この動的スコープとは何ですか?
ほとんどのプログラムは、理解しやすいため、レキシカルとも呼ばれる静的スコープを使用します。ソースコードを見ると、範囲内にあるものがわかります。Pythonの例では、スコープ内のxの唯一の値はxのグローバル値です。

対照的に、PowerShellは動的スコープを使用します。このモデルでは、スコープスタックに基づいて実行時に変数を検索します。関数を呼び出すたびに、新しいスコープを作成し、すべての値を親スコープからそのスコープにコピーします。PowerShellの例では、printXがsetAndprintXから呼び出されると、setAndprintXスコープで設定された$xの値を取得します。

なぜ動的スコープが必要なのですか?

字句スコープよりも動的スコープを選択する理由について、適切な説明を思い付くことができません。

「健康は病人だけが見ることができる王冠です」
2022/07/15(金) 17:59:02.69ID:jPbc5odD
function foo() {
$global:array += "h" Write-Host $array
}
& { $global:array +="s" Write-Host $array }
ってやるだけじゃねーの?
そもそもグローバル変数自体はそれ程使わん、ましてや関数やスクリプトブロックで更新なんてほぼやらん
2022/07/15(金) 21:33:28.03ID:Keau4pUF
>>477
PowerShell in ActionによるとダイナミックスコープはUNIXシェルを参考にしたらしい
2022/07/15(金) 23:56:32.68ID:avBUMPl6
using namespace System.Collections.Generic
$list = [List[string]] @('ggg');
'$list={0}' -f ($list -join ', ') | oh
function f {$list.Add('fff'); 'f={0}' -f ($list -join ', ') | oh;}
&{$list.Add('sb'); 'sb={0}' -f ($list -join ', ')|oh;}
f
'$list={0}' -f ($list -join ', ') | oh

$list=ggg
sb=ggg, sb
f=ggg, sb, fff
$list=ggg, sb, fff
2022/07/16(土) 13:19:21.19ID:3YCfDQK3
>>480
.NEtのListコンテナ使うと意図通り動くのはなんでなん
Powershellの配列の変数は値型とか?
この辺をちゃんと理解ておきたい
2022/07/16(土) 14:25:05.61ID:QBrOblFw
Listかどうかは関係ない 変数に新しい値を代入してるかどうか
>>474の $array += "h"は 新しく作った配列を $array に代入してるけど
>>480の $list はそんな事してないでしょ
2022/07/16(土) 14:36:33.24ID:3YCfDQK3
>>482
えーつまり$array += "h"は文字列への追加じゃなくて
やってることは$array = $array + "h"相当で新規に文字列のインスタンスとローカル変数が作成されるってことなの?
$arrayに対してのAdd相当は$global:的な装飾子以外にないの?
2022/07/16(土) 15:02:15.96ID:m/XBj/Ao
メインclerだけど、動的静的スコープの使い分けがclの武器と刷り込まれてた
評判悪いのか…
呼び出し側から振り分けられるのは便利では?出力先とか
2022/07/16(土) 15:49:49.15ID:OVIs5jsH
lispのようにメモリ上フラットにオブジェクトが住む思想(~pwshのfunction:プロバイダ)だと、動的スコープになるのが自然では
レキシカルな文脈が無いのだから
2022/07/16(土) 15:54:08.82ID:yus9SEVI
Powershellの配列は固定長だよ
追加はできない
+=演算子はその見た目のイメージ通り、新しい配列による再代入を伴う
これはスコープとは関係ない問題
2022/07/16(土) 15:57:07.03ID:m/XBj/Ao
ミュータブルかイミュータブルか、あと参照の話がごっちゃになってるよね

GetNewClosureはclのfunctionフォームと等価だね
2022/07/16(土) 16:10:18.66ID:XIhDxiQx
>>479
unixシェルもpwshもclもそうだけど、関数定義をズラズラっとダンプできて、それをちゃんと読み戻せる言語は原理的にレキシカルスコープでは有り得ない
(暗黙のうちにletやクロージャ生成を行う)ブロックぽい構文でレキシカルスコープを模倣することは可能だけど
2022/07/16(土) 17:23:13.80ID:3YCfDQK3
LISP族はletか何かで変数に対しての宣言を必ずするからダイナミックでも違和感ないでしょ
Powershellの違和感は暗黙的に変数の意味が代わるところじゃないかな
2022/07/17(日) 18:41:53.37ID:zSvUsLU3
コード適当に書いていってある程度の規模になった頃にそろそそ関数化でもすっか!
ってなった時に下手にグローバル変数更新してたりすると即はまるなコレ
しかも一見何が悪いのかさっぱり判らないという
Powershellコーティング十か条でも壁に貼っとかないとな
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況