New V3 Language Features - Windows PowerShell Blog - Site Home - MSDN Blogsで説明されていたV3の機能をちょっと試してみました。
 まずはちょっと便利になった単数と複数を同一視してくれる機能。
    | PS>dir ディレクトリ: C:\Users\minminnana\test
 Mode                LastWriteTime     Length Name
 ----                -------------     ------ ----
 -a---        2012/06/20     11:18         10 a.txt
 | 
 上記のようなディレクトリで以下のようなコマンドを実行すると、
    | PS>(dir).fullnameC:\Users\minminnana\test\a.txt
 | 
 となります。
 しかし、これがうまくいくのはどちらかというと「たまたま」で、誰かがここにファイルを追加したりすると突然機能しなくなります。
    | PS>"aaa" > b.txtPS>dir
 ディレクトリ: C:\Users\minminnana\test
 Mode                LastWriteTime     Length Name
 ----                -------------     ------ ----
 -a---        2012/06/20     11:18         10 a.txt
 -a---        2012/06/20     11:33         12 b.txt
 PS>(dir).fullname
 PS>
 | 
 これは、(dir)で返ってくるオブジェクトが単数の場合はファイルオブジェクト、複数の場合はオブジェクト配列になることが原因です。
    | PS>dir ディレクトリ: C:\Users\minminnana\test
 Mode                LastWriteTime     Length Name
 ----                -------------     ------ ----
 -a---        2012/06/20     11:18         10 a.txt
 PS>(dir).gettype()
 IsPublic IsSerial Name                                     BaseType-------- -------- ----                                     --------
 True     True     FileInfo                                 System.IO.FileSystemInfo
 PS>"aaa" > b.txt
 PS>(dir).gettype()
 IsPublic IsSerial Name                                     BaseType-------- -------- ----                                     --------
 True     True     Object[]                                 System.Array
 
 | 
 この単数と複数の挙動の違いは誰しもが一度は嵌る道のように思います。
 これまでは、この単数と複数の挙動の違いを吸収するために@()などで変数を定義して単数でも配列扱いとする方法が使われましたが、V3ではPowerShell側がこの違いを良きに計らってくれるようです。
 V3ではこんな感じになります。
    | PS>dir ディレクトリ: C:\Users\minminnana\test
 Mode                LastWriteTime     Length Name
 ----                -------------     ------ ----
 -a---        2012/06/20     11:45         12 a.txt
 -a---        2012/06/20     11:45         12 b.txt
 PS>(dir).fullname
 C:\Users\minminnana\test\a.txt
 C:\Users\minminnana\test\b.txt
 | 
 これまでは、複数オブジェクトの場合は自分でループして個々のプロパティを参照する必要がありました。
    | PS>dir | %{$_.fullname}C:\Users\minminnana\test\a.txt
 C:\Users\minminnana\test\b.txt
 PS>dir | % fullname
 C:\Users\minminnana\test\a.txt
 C:\Users\minminnana\test\b.txt
 | 
 (最初の例はこれまでのV2の書き方、2つ目はV3での書き方。)
 パイプを使った書き方も簡略化されているので、
    | > (dir).fullname > dir | % fullname
 | 
 どちらもタイプ量的には似たようなものですが、Blogによると前者のほうが(内部的にパイプ処理に展開しているわけではないので)高速だと書いてあるように読めました。
 他にもCountプロパティが参照できたり添え字付きで参照できたりといった感じになっているようです。
 V2
 
   | PS>$a = 1PS>$a.count
 PS>$a[0]
 型 System.Int32 のオブジェクトにインデックスを付けることはできません。
 発生場所 行:1 文字:4
 + $a[ <<<< 0]
 + CategoryInfo          : InvalidOperation: (0:Int32) []、RuntimeException
 + FullyQualifiedErrorId : CannotIndex
 
 | 
 V3
 
   | PS>$a = 1PS>$a.count
 1
 PS>$a[0]
 1
 | 
 
また、もともとオブジェクト配列に持っているプロパティの場合はそちらが優先されるようです。
    | PS>$a = "aaa","b","cc","ddd"PS>$a.length
 4
 PS>$a | % length
 3
 1
 2
 3
 | 
  
 
0 件のコメント:
コメントを投稿