【PowerShell】Class に関するメモ

class の使い方に関して意外と情報が少ないので書き残す。(誤りがあればご指摘ください)
 

 

環境

Windows環境と Linux環境の 2つでテストした

Ubuntu18.04 PowerShell v6.1.0-preview.3
Windows10 PowerShell 5.0

 

コード

 

サンプル1:PathHolder

入力ファイルの絶対パス、ディレクトリ部, ファイル部のパス保持するだけのクラス

#!/usr/bin/env pwsh

# コンストラクタで渡されたファイルの下記 3つの情報を持つクラス
# - realpath
# - dirname
# - basename
# 
# メソッド:
#   EchoAll(): 上記 3つのパスを表示する機能を持つ

class   PathHolder
{
  $m_FN         = ''    # 入力ファイルの realpath (フルパス)
  $m_DN         = ''    # 入力ファイルの dirname
  $m_BN         = ''    # 入力ファイルの basename

  # コンストラクタ
  PathHolder([string] $f)
  {
    $this.m_FN  = (Get-Item $f).FullName
    $this.m_DN  = $this.m_FN.Substring(0,$this.m_FN.LastIndexOf("/") + 1)
    $this.m_BN  = [System.IO.Path]::GetFileName($f)
  }

  [void] EchoAll()
  {
    Write-Host $this.m_FN
    Write-Host $this.m_DN
    Write-Host $this.m_BN
  }
}

$H = [PathHolder]::new($Args[0])
$H.EchoAll()

 

実行結果
Linux 環境での確認結果のため、「/」を「\」に読み換えること。

% Get-Location
% ./class1.ps1 ./output.txt
/home/neko/output.txt
/home/neko/
output.txt

 
 

注意点

EchoAll() クラスでの変数を "" で囲むと展開されない。

  [void] EchoAll()
  {
    Write-Host "$this.m_FN"
    Write-Host "$this.m_DN"
    Write-Host "$this.m_BN"
  }

 
実行結果

% 
PathHolder.m_FN
PathHolder.m_DN
PathHolder.m_BN

 
この場合は次のように $this.m_FN を $($this.m_FN) といった具合に括ってやると良い。

  [void] EchoAll()
  {
    Write-Host "$($this.m_FN)"
    Write-Host "$($this.m_DN)"
    Write-Host "$($this.m_BN)"
  }

 

各種トラブル

「OverloadDefinitions」と出しまう

作成した関数を呼び出しているが、「OverloadDefinitions」というエラーが出てしまう。

OverloadDefinitions
-------------------
void EchoAll()

 
対策方法
呼び出し時の引数が間
具体的には, 「引数ありなのに引数渡さず」や「引数が string なのに int を渡している」等々。

 

「Cannot assign property, use '$this.m_XXXX'」と出てしまう

作成したメンバ変数 m_XXXX にアクセスすると「Cannot assign property, use '$this.m_XXXX'」と出てしまう。

+     $m_XXXX  = (Get-Item $f).FullName
+     ~~~~~
Cannot assign property, use '$this.m_XXXX'.

 
対策方法
メンバ変数を呼び出すときに $this. という文言が欠落している疑いあり。
エラーメッセージの警告通りに $this.m_XXXX としてアクセスすれば良い。

 

Write-Output $this.XXXX としてもログが表示されない

例として、下記の EchoAll() を呼び出しても何も表示されない。
これは "$(this.m_FN)" の内容が戻り値になってしまっているためらしい。

class   PathHolder
{
  $m_FN         = ''    # 入力ファイルの realpath (フルパス)

  [void] EchoAll()
  {
    Write-Output "$($this.m_FN)"

対策としては,[Console]::WriteLineメソッドを使えば良いとのこと。
(あるいは Write-Host でも表示可能)
 
参考にしたサイト
PowerShellのechoにつまづいたので忘備録。 - Logic Dice