概要

継承

  • Point クラスを継承した Point3D クラスには、追加のプロパティ(z)と追加されたプロパティが影響する部分のみを実装する。
  • new(), stringify(), abs() については継承元の Point クラスのメソッドが呼び出される。

ソース

  • Point.pm

    package Point;
    
    use Object::Simple -base;
    use overload '""' => \&stringify;
    
    has label => '';
    has x     => 0;
    has y     => 0;
    
    sub stringify {
        my $self = shift;
        return sprintf( '[%s](%s)', $self->label, join( ', ', $self->values ) );
    }
    
    sub values {
        my $self = shift;
        return ( $self->x, $self->y );
    }
    
    sub clear {
        my $self = shift;
        $self->x(0);
        $self->y(0);
    }
    
    sub abs {
        my $self = shift;
        my $sum  = 0;
        map { $sum += $_ * $_ } $self->values;
        return sqrt($sum);
    }
    
    1;
  • Point3D.pm

    package Point3D;
    
    use Object::Simple 'Point';
    
    has z => 0;
    
    sub values {
        my $self = shift;
        return ( $self->SUPER::values, $self->z );
    }
    
    sub clear {
        my $self = shift;
        $self->SUPER::clear;
        $self->z(0);
    }
    
    1;
  • use-Point.pl

    #!/bin/perl
    # [GitHub:yuki-kimoto/Object-Simple](https://github.com/yuki-kimoto/Object-Simple)
    
    use strict;
    use warnings;
    use utf8;
    use Encode;
    use Point;
    use Point3D;
    use open ':std' => ':locale';
    
    print "\n# Point サンプル\n";
    my $pointA = Point->new(
        label => '点A',
        x     => 3,
        y     => 4,
    );
    print "${pointA}\n";
    print "x: " . $pointA->x . "\n";
    print "abs: " . $pointA->abs . "\n";
    $pointA->y(9.3);
    print "${pointA}\n";
    $pointA->clear;
    print "${pointA}\n";
    
    print "\n# Point3D サンプル\n";
    my $pointB = Point3D->new(
        label => '点B',
        x     => 3,
        y     => 4,
        z     => 5,
    );
    print "${pointB}\n";
    print "z: " . $pointB->z . "\n";
    print "abs: " . $pointB->abs . "\n";
    $pointB->z(9.6);
    print "${pointB}\n";
    $pointB->clear;
    print "${pointB}\n";
    
    exit;

出力

# Point サンプル
[点A](3, 4)
x: 3
abs: 5
[点A](3, 9.3)
[点A](0, 0)

# Point3D サンプル
[点B](3, 4, 5)
z: 5
abs: 7.07106781186548
[点B](3, 4, 9.6)
[点B](0, 0, 0)

インラインモジュール

  • 同一ファイル内でモジュールを定義する場合は、main ルーチンを実行する前にモジュール部分を実行しないとモジュールが正常に初期化されない。
  • main ルーチンより先にモジュール部分を実行するには、下記のいずれかを行う。
    • main ルーチンの前でモジュール部分を定義する。
    • main ルーチンを関数化し、モジュール定義後に main() を呼び出す。
    • BEGIN ブロック内にモジュール定義を配置する。

ソース

  • inlineModule.pl
    #!/bin/perl
    
    use strict;
    use warnings;
    use utf8;
    use Encode;
    use open ':std' => ':locale';
    
    my $user = User->new(
        id          => '0001',
        account     => 'TaroY',
        displayname => '山田 太郎',
    );
    print "${user}\n";
    print "displayname: " . $user->displayname . "\n";
    $user->account('JiroT');
    $user->displayname('高橋 次郎');
    print "${user}\n";
    
    exit;
    
    BEGIN {
    
        package User;
        use Object::Simple -base;
        use overload '""' => \&stringify;
    
        has id          => '';
        has account     => '';
        has displayname => '';
    
        sub stringify {
            my $self = shift;
            return sprintf( '{id:"%s", account:"%s", displayname:"%s"}',
                $self->id, $self->account, $self->displayname );
        }
    }

出力

{id:"0001", account:"TaroY", displayname:"山田 太郎"}
displayname: 山田 太郎
{id:"0001", account:"JiroT", displayname:"高橋 次郎"}

リンク