SlideShare a Scribd company logo
Perl 6
オブジェクト指向
プログラミング
YAPC::Asia TOKYO 2013
2013/09/21
risou
※注意
ここでのPerl 6の説明は簡素化のため、
厳密には正しくない表現も含まれます。
(もしくは私の間違いです)
お話する人
• risou ( @risou )
• 職業プログラマではない
• 普段は Java とか Haskell とか書いてます
• たまに Perl 入学式にいたりいなかったり
• 昨夜、銀歯がとれました
今喋ってるのはこんな人です。
本日のお題
• Perl 6 でオブジェクト指向プログラミング
今日喋るのはこんなことです。
本日のお題
• Perl 6 でオブジェクト指向プログラミング
今日喋るのはこんなことです。
もっと言うと……
• Perl でのオブジェクト指向
• Perl 6 でのオブジェクト指向
• Perl と Perl 6 の違いとかに間接的に言及するかも
オブジェクト指向
オブジェクト指向とは
• データの構造と振舞いをオブジェクトとして扱う
• オブジェクト間でのメッセージのやりとりでシステムを
構成する
• 様々なプログラミング言語がサポートしている
• Smalltalk / C++ / Java / Perl / Ruby / ...
ご存知の方も多いかと思いますが……
オブジェクト指向の特徴
• カプセル化
• ポリモーフィズム
• 継承
オブジェクト指向の代表的な特徴をあげると……
※全てのオブジェクト指向言語が
 これらの特徴を備えているわけではない
Perl でオブジェクト指向
Perl でオブジェクト指向
package Classname;
use strict;
use warnings;
sub new {
my ($class) = @_;
return bless {
field => $field,
}, $class;
}
Perl でオブジェクト指向
• カプセル化されていない
• public/privateなど可視性を指定できない
• オブジェクト=パッケージという縛り
オブジェクト指向のように書けるが……
という短所(見方によっては長所?)もある
Perl 6
Camelia
Perl 6 について
• 既存の Perl (∼ v.5.18)とは異なる言語
• 互換性がない
• 作者は Larry Wall ( Perl と作者が同じ)
• オブジェクト指向スクリプト言語
• 静的型付けにも対応
• 全ての仕様を反映した実装はまだない
基本的な話
完全な実装がない?
• 今はまだない
• 仕様のある程度の部分に対応した実装はある
• 今回提示するコードは Rakudo で動作確認しました
• テクニカルな実装をしなければ、けっこう使えるかも
Perl 6
オブジェクト指向
プログラミング
• 予約語
• class
• method
• 同一ファイル内で
定義も呼び出しもできる
(良いかどうかは別として)
• sub も色々ある
(ここで話すには時間がry)
クラス and メソッド
class Engineer {
method greeting {
say ‘hello, YAPC!’;
}
}
my $c = Engineer.new;
$c.greeting; # hello, YAPC!
メソッドの可視性
メソッドの可視性
class Engineer {
method greeting {
say ‘hello, YAPC!’;
}
method !thinking {
say ‘sleepy...’;
}
my $c = Engineer.new;
$c.greeting; # hello, YAPC!
$c!thinking; # NG
メソッドの可視性
• メソッドに public/private を指定できる
• private メソッドはメソッド名の最初に ! をつける
• private メソッドはクラス外からはアクセスできないが
当然クラス内からはアクセスできるので……
メソッドの可視性
class Engineer {
method greeting {
say ‘hello, YAPC!’;
}
method !thinking {
say ‘sleepy...’;
method unconsciously {
self!thinking;
}
my $c = Engineer.new;
$c.greeting; # hello, YAPC!
$c!thinking; # NG
$c.unconsciously; # sleepy...
アトリビュート
アトリビュート
class Attrs {
has $!priv_var;
has $.pub_var;
method print_all {
say $!priv_var;
say $.pub_var;
}
method set_all ($priv, $pub) {
$!priv_var = $priv;
$.pub_var = $pub;
}
}
my $attr = Attrs.new;
$attr.set_all(1, 2);
$attr.print_all; # 1 2
アトリビュート
• メソッドと同様に public/private を指定できる
• さっきのコード、動きそうですが……
Cannot assign to a readonly variable or a value
in method set_all at attrs.p6:10
in block at attrs.p6:16
エラー!
アトリビュート
• public アトリビュートはデフォルトでは readonly
• 無理やり代入したい場合は ! を使う
アトリビュート
class Attrs {
has $!priv_var;
has $.pub_var;
method print_all {
say $!priv_var;
say $.pub_var;
}
method set_all ($priv, $pub) {
$!priv_var = $priv;
$!pub_var = $pub; # change twigil
}
}
my $attr = Attrs.new;
$attr.set_all(1, 2);
$attr.print_all; # 1 2
アトリビュート
• public アトリビュートはデフォルトでは readonly
• 無理やり代入したい場合は ! を使う
• ん……でも ! だと private 扱いになる?
• じゃあクラス外からアクセスするには?
アトリビュート
class Attrs {
has $!priv_var;
has $.pub_var is rw;
}
my $attr = Attrs.new;
$attr!priv_var = “alpha”; # NG
$attr.pub_var = “bravo”;
say $attr!priv_var; # NG
say $attr.pub_var; # bravo
アトリビュート
• public アトリビュートはデフォルトでは readonly
• 無理やり代入したい場合は ! を使う
• ん……でも ! だと private 扱いになる?
• じゃあクラス外からアクセスするには?
• is rw をつけることで writable にできる
継承
継承
class Person {
has $.name is rw;
}
class Speaker is Person {
method get_name {
return $.name;
}
}
my $speaker = Speaker.new;
$speaker.name = ‘risou’; # risou
my Person $p = Speaker.new;
継承
• 他の多くのオブジェクト指向言語と同様に
メソッドは自分→親→……→ルートの順で探索する
• 親クラスのアトリビュート、メソッドを引き継ぐ
• 多重継承もできる
class Charlie is Alpha is Bravo ... {
オーバーライド
オーバーライド
class Parent {
method print_generation {
say ‘first generation’;
}
}
class Child is Parent {
method print_generation {
say ‘second generation’;
}
}
Parent.print_generation; # first generation
Child.print_generation; # second generation
my Parent $p = Child.new;
$p.print_generation; # second generation
オーバーライド
• もちろんオーバーライドもできる
• (ここ特筆すべきことないですね)
コンストラクタ
コンストラクタ
class OneAttr {
has $.attr;
method new ($attr) {
return self.bless(*, :attr);
}
method print_attr {
say $.attr;
}
}
my $oa = OneAttr.new(10);
$oa.print_attr; # 10
コンストラクタ
• コンストラクタの戻り値は bless
• オブジェクトを生成するために
bless の第1引数に * をセットする
• bless の引数で名前付き引数を用いることで
アトリビュートに値をセットできる
コンストラクタ
• ルートオブジェクトがコンストラクタを持つため
引数付きコンストラクタが必要ないなら定義は不要
method new {
return self.bless(*);
}
コンストラクタ
class OneAttr {
has $.attr;
method new ($attr) {
return self.bless(*, :attr);
}
method print_attr {
say $.attr;
}
}
my $oa = OneAttr.new;
$oa.print_attr; # ??
Not enough positional parameters passed; got 1 but
expected 2
in method new at con2.p6:4
in block at con2.p6:13
エラー!
コンストラクタ
• 引数なしコンストラクタが呼べ……ない!
• 同名のメソッドが既に定義されているため
(引数の有無/数にかかわらず同名のメソッド扱い)
• これは不便ですね
• デフォルトの引数なしコンストラクタと
独自定義の引数ありコンストラクタを共存させたい
• させましょう!
コンストラクタ
• 引数なしコンストラクタが呼べ……ない!
• 同名のメソッドが既に定義されているため
(引数の有無/数にかかわらず同名のメソッド扱い)
• これは不便ですね
• デフォルトの引数なしコンストラクタと
独自定義の引数ありコンストラクタを共存させたい
• させましょう!
コンストラクタ
• 引数なしコンストラクタが呼べ……ない!
• 同名のメソッドが既に定義されているため
(引数の有無/数にかかわらず同名のメソッド扱い)
• これは不便ですね
• デフォルトの引数なしコンストラクタと
独自定義の引数ありコンストラクタを共存させたい
• させましょう!
コンストラクタ
• 引数なしコンストラクタが呼べ……ない!
• 同名のメソッドが既に定義されているため
(引数の有無/数にかかわらず同名のメソッド扱い)
• これは不便ですね
• デフォルトの引数なしコンストラクタと
独自定義の引数ありコンストラクタを共存させたい
• させましょう!
コンストラクタ
class OneAttr {
has $.attr;
multi method new ($attr) {
return self.bless(*, :attr);
}
method print_attr {
say $.attr;
}
}
my $oa = OneAttr.new;
$oa.print_attr; # Any()
コンストラクタ
• multi これだけ!
• multi をつけることでメソッドをオーバーロードできる
• (親クラスの)引数なしメソッドと
引数ありメソッドが同じクラスの中で同居できる
Role
Role
role Dice {
method roll {
return [1..$.plane].pick;
}
}
class Cube does Dice {
has $.plane = 6;
}
my $dice = Cube.new;
$dice.roll; # 1∼6
Role
• オブジェクトに役割を与える
(Javaで言うとインタフェース)
• 継承とは異なるものなので注意
• オブジェクト生成時に Role を与えることもできる
Role
role Dice {
method roll {
return [1..$.plane].pick;
}
}
class Cube {
has $.plane = 6;
}
my $dice = Cube.new does Dice;
$dice.roll; # 1∼6
と、ここまで駆け足でお送りしてきました
Perl 6
• Perl よりも自然にオブジェクト指向が書ける
• 記号プレフィックス(sigil, twigil)が豊富・複雑に
• (ここでは紹介してないけど)メタクラスなどもあります
ところで
• Perlでオブジェクト指向するならモジュール使いましょう
• 個人的には素で書くのも嫌いじゃないけど、
規模が大きくなると苦しくなってくる
OOP モジュール
• 選択肢はいくつかある
• Mouse
• Moo
• より良い選択肢(の候補)
• p5-mop-redux
OOP モジュール
• 選択肢はいくつかある
• Mouse
• Moo
• より良い選択肢(の候補)
• p5-mop-redux
p5-mop-redux
• 今日説明した Perl 6 の OOP にかなり近い
• ドット演算子は無理だけと twigil はなんとかできそう
• コアに入れば Perl での OOP がすごく楽になるはず

More Related Content

Perl 6 Object-Oliented Programming