sironekotoroの日記

Perl で楽をしたい

Perl のサブルーチンにおける引数の取り込みかたを 3 種類ほど紹介

その 1:おなじみ @_

先に開催された Perl入学式で、サブルーチンに渡す引数について「Perl においては仮引数はない」というようなお話をしました。

仮引数というのは、例えば JavaScript でいうと fizz の横にある number のことです。

function fizz(number) { // この number が仮引数 
  if (number % 3 === 0) {
    return 'Fizz';
  };
}

console.log(fizz(3)); // Fizz
console.log(fizz(5)); // undefined

おなじ関数を Perl で書くとこうです。

仮引数がない代わりに、引数を取り込む処理をサブルーチン内部で my $number = shift @_ として行っています。

sub fizz {
    my $number = shift @_;

    if ( $number % 3 == 0 ) {
        return 'Fizz';
    }
}

print fizz(3) . "\n";   # Fizz
print fizz(4) . "\n";   # 何も表示されない

これがスタンダードな Perl のサブルーチンにおける引数の取り込みかた 1 つ目です。

その 2 :実験的機能 signatures

Perl にはいくつか実験的な機能が搭載されています。

その中の一つに仮引数に関するものがあります。それが signatures です。

実験的機能は通常は無効になっていますが、明示的に記述することで有効にできます。

perldoc.jp

これを使って書くと、だいぶ JavaScript の例に近くなります。

というかほぼ同じ?

use feature 'signatures';   # 実験的機能のうち signatures を使う旨の宣言
no warnings "experimental::signatures";
                            # 実験的機能利用時の警告メッセージを消す

sub buzz ($number) {
    if ( $number % 5 == 0 ) {
        return 'Buzz';
    }
}

print buzz(5) . "\n";   # Buzz

実験的機能とはいえ、この機能が搭載されたのは Perl 5.20 で 2014 年。もう 7 年になります。

最近 Perl を入れたのであれば大体使えるはずなので、個人プロジェクトや、新しい Perl が稼働する環境では使って良いと思います。

なお、Perl のバージョンを確認するにはコンソールから perl -v 、または Perl のプログラム内では print $] で表示されます。

その 3:モジュール Function::Params

Perl には・・・というか、大抵のプログラム言語には外部からプログラムを追加することで、機能を追加する仕組みがあります。

Perl の場合には「モジュール」と呼ばれています。

JavaScript でもモジュールで、 Ruby だと Gemジェム ですかね)

Function::Params モジュールはインストールこそ必要ですが、仮引数的な書き方が可能です。

なお、このモジュールを使う場合にはサブルーチンの宣言は sub ではなく fun になります。

gihyo.jp

use Function::Parameters;
fun fizzbuzz($number) {
    if ( $number % 3 == 0 && $number % 5 == 0 ) {
        return 'FizzBuzz';
    }
}

print fizzbuzz(15) . "\n"; # FizzBuzz

脱線:引数の型チェック

Function::Params は型チェックをする他のモジュールと組み合わせることで、引数の中身が希望の型か確認できます。

use Function::Parameters;
use Type::Tiny;                 # 型モジュール
use Types::Standard qw(Int);    # Int 整数型を宣言
fun fizzbuzz( Int $number) {    # Int 型の引数に限定
    if ( $number % 3 == 0 && $number % 5 == 0 ) {
        return 'FizzBuzz';
    }
}

print fizzbuzz(15) . "\n";    # FizzBuzz
print fizzbuzz('foo') . "\n"; # Int 型ではないのでエラー
                              # In fun fizzbuzz: parameter 1 ($number): Value "foo" did not pass type constraint "Int"

というわけで

Perl のサブルーチンにおける引数の取り込み方でした。

Perl 入学式ではモダンな(現代的な)Perl を教えることを旨としています。

これまでに書かれてきた Perl の書き方については当然学ぶ必要がありますが、よりモダンな書き方も教えていく必要はあるなぁ、と思ったのでした。