関数

これまでPoewrShell Coreの制御構文やデータを格納する機能について説明してきた。制御構文とデータ格納については基本的なところを網羅したので、今回からは関数を取り上げていこう。

スクリプト言語やプログラミング言語としてPowerShell Coreを使おうと思ったら欠かすことのできない機能だ。

PowerShell Coreの言語仕様的には次のような書き方ができるのが関数ということになる。

PowerShell Coreの関数のシンタックス

function [<スコープ:>]<関数名> [([型]$パラメータ1[,[型]$パラメータ2])]
{
  param([型]$パラメータ1 [,[型]$パラメータ2])
  dynamicparam {<処理>}
  begin {<処理>}
  process {<処理>}
  end {<処理>}
}

これだとわけがわからないと思うが、ようするに次のように処理をまとめておくことができるというのが関数だ。

関数のサンプル

PS /Users/daichi> function Get-Test
>> {
>>     "テスト関数です"
>> }
PS /Users/daichi> Get-Test
テスト関数です
PS /Users/daichi>

たとえば上記の例だとGet-Testという名前の関数が作成されている。関数の機能はメッセージを出力するだけの簡単なものだ。作成した関数はコマンドレットのように実行することができる。繰り返し実行するような処理は関数としてまとめておくというのがプログラミングの定石だ。

関数名

PowerShell Coreでは関数名の命名規則が定められている。「動詞-名詞」のような形式をとる必要があるとされており、使用できる動詞にも種類がある。既存のコマンドレットや関数を参考にすれば使っていい動詞や名前の規則、大文字や小文字の使い方などはわかってくるはずだ。

このように命名規則が決めてある理由は、どのユーザもその名前を見るだけでどのような処理をするものなのか推測しやすくするためとされている。たとえば、これまでに取り上げてきたコマンドレットを使って、関数を作ってみよう。現在の年を出力する関数、次の年を出力する関数、前の年を出力する関数として、Get-ThisYear、Get-NextYear、Get-LastYearという関数を作成する。次のような感じになるだろう。

今年を出力する Get-ThisYear

PS /Users/daichi> function Get-ThisYear
>> {
>>     $(Get-Date).Year
>> }
PS /Users/daichi> Get-ThisYear
2019
PS /Users/daichi>

来年を出力する Get-NextYear

PS /Users/daichi> function Get-NextYear
>> {
>>     $(Get-Date).AddYears(1).Year
>> }
PS /Users/daichi> Get-NextYear
2020
PS /Users/daichi>

昨年を出力する Get-LastYear

PS /Users/daichi> function Get-LastYear
>> {
>>     $(Get-Date).AddYears(-1).Year
>> }
PS /Users/daichi> Get-LastYear
2018
PS /Users/daichi>

Get-Dateコマンドレットの使い方は連載で紹介したとおりだ。関数名としてこのような規則にしたがっておけば、関数名を見ただけで何をするコマンドかなんとなるわかる。

ただし、絶対にこの規則に従わなければならないかといえば、そういうことではない。先ほどの関数を次のように好きな名前で作成して利用することもできる。

Get-ThisYear → year

PS /Users/daichi> function year
>> {
>>     $(Get-Date).Year
>> }
PS /Users/daichi> year
2019
PS /Users/daichi>

Get-NextYear → year_next

PS /Users/daichi> function year_next
>> {
>>     $(Get-Date).AddYears(1).Year
>> }
PS /Users/daichi> year_next
2020
PS /Users/daichi>

Get-LastYear → year_last

PS /Users/daichi> function year_last
>> {
>>     $(Get-Date).AddYears(-1).Year
>> }
PS /Users/daichi> year_last
2018
PS /Users/daichi>

機能的には任意の名前をつけることができるのだが、郷に入りては郷に従えというものだ。名前はPowerShell Coreで推奨されている方法に従ってつけておいた方がよいだろう。

パラメータ

コマンドレットには引数やパラメータを指定して挙動を変えることができる。この機能は関数でも利用できる。関数の場合には関数の中でParam()という書き方をすることで、パラメータを指定することが可能になる。

たとえば関数の中でParam($Offset = 1)のように書いておくと、$Offset変数の値をパラメータで指定できるようになる。= 1と書いてあるのはデフォルトの値の指定で、パラメータの指定がなければ1が使われるようになる。

次のサンプルがパラメータ指定を取り込んだGet-NextYear関数だ。

パラメータ-Offsetを指定できるようにしたGet-NextYear関数

PS /Users/daichi> function Get-NextYear
>> {
>>     Param($Offset = 1)
>>     $(Get-Date).AddYears($Offset).Year
>> }
PS /Users/daichi> Get-NextYear
2020
PS /Users/daichi> Get-NextYear -Offset 1
2020
PS /Users/daichi> Get-NextYear -Offset 2
2021
PS /Users/daichi> Get-NextYear -Offset 3
2022
PS /Users/daichi> Get-NextYear -Offset 4
2023
PS /Users/daichi> Get-NextYear -Offset 100
2119
PS /Users/daichi>

-Offsetパラーメタは何年分の次の年を計算するかという指定で、デフォルトで1が使われる。つまり1年後の年がデフォルトで表示される。-Offset 100なら100年後が表示される。

Param()で指定する内容は、次のように関数名のあとに記述することもできる。関数の記述としてはこちらの方が馴染みがあるだろう。JavaやC言語ではこちらの記述の方が近いからだ。

パラメータの指定を別の書き方で記述した場合

PS /Users/daichi> function Get-NextYear($Offset = 1)
>> {
>>     $(Get-Date).AddYears($Offset).Year
>> }
PS /Users/daichi> Get-NextYear
2020
PS /Users/daichi> Get-NextYear -Offset 1
2020
PS /Users/daichi> Get-NextYear -Offset 2
2021
PS /Users/daichi> Get-NextYear -Offset 3
2022
PS /Users/daichi> Get-NextYear -Offset 4
2023
PS /Users/daichi> Get-NextYear -Offset 100
2119
PS /Users/daichi>

パラメータは1つではなく複数指定することができる。複数のパラメータを指定するには、次のようにパラメータの指定をカンマで区切って指定する。

複数のパラメータを指定する場合はカンマで区切って指定する

PS /Users/daichi> function Get-NextYear
>> {
>>     Param($Offset = 1, $Unit = '年')
>>     Write-Host $(Get-Date).AddYears($Offset).Year $Unit
>> }
PS /Users/daichi> Get-NextYear
2020 年
PS /Users/daichi> Get-NextYear -Offset 1
2020 年
PS /Users/daichi> Get-NextYear -Offset 2
2021 年
PS /Users/daichi> Get-NextYear -Offset 3 -Unit 'Year'
2022 Year
PS /Users/daichi> Get-NextYear -Offset 4 -Unit 'ネン'
2023 ネン
PS /Users/daichi>

もちろんこちらの記述も関数名のあとに記述する方法でも利用できる。

関数名にあとに記述する場合にはこうなる

PS /Users/daichi> function Get-NextYear($Offset = 1, $Unit = '年')
>> {
>>     Write-Host $(Get-Date).AddYears($Offset).Year $Unit
>> }
PS /Users/daichi> Get-NextYear
2020 年
PS /Users/daichi> Get-NextYear -Offset 1
2020 年
PS /Users/daichi> Get-NextYear -Offset 2
2021 年
PS /Users/daichi> Get-NextYear -Offset 3 -Unit 'Year'
2022 Year
PS /Users/daichi> Get-NextYear -Offset 4 -Unit 'ネン'
2023 ネン
PS /Users/daichi>

コマンドレットではパラメータ指定を省略して値を指定することができるのだが、同じことは関数でも機能する。次のようにParam()に指定した順で値が渡されることになる。

パラメータは省略して指定することが可能

PS /Users/daichi> Get-NextYear 1
2020 年
PS /Users/daichi> Get-NextYear 2
2021 年
PS /Users/daichi> Get-NextYear 3 'Year'
2022 Year
PS /Users/daichi> Get-NextYear 3 'ネン'
2022 ネン
PS /Users/daichi>

PowerShell Coreの関数としてはまずはこのあたりは基本的なところだ。これだけでもけっこう自由に関数が作成できるようになる。便利な機能なのでぜひとも覚えてしまいたい。関数は重要な機能であり、用意されている機能はもっと多い。

次回はPowerShell Coreに用意されている関数のほかの機能を紹介する。

参考資料