• モジュール
• 拡張⼦は.pm
package Example::Greeter;
use strict;
use warnings;
sub greet {
my ($class, $what) = @_;
print "hello, $what\n";
}
1;
#hatenaintern)*)+
Slide 18
Slide 18 text
• メインスクリプト
• 拡張⼦は.pl
• Prologも同じ拡張⼦
use strict;
use warnings;
use lib 'lib';
use Example::Greeter;
Example::Greeter->greet('world');
• 実⾏
% perl -Ilib main.pl
hello, world
#hatenaintern)*)+
Slide 19
Slide 19 text
おまじない
• use strict; use warnings;
• 素のPerlはかなり⾃由
• もともとawk/sedの影響が強いので同じようなことができる
• use strict; すると my で宣⾔していない変数があると静的にエラー
• use warnings; すると警告が有効になる
• 詳しくは perldoc strict / perldoc warnings
#hatenaintern)*)+
コンテキストのよくある罠
なんかユーザから送られた⼊⼒を受けとり、リストコンテキスト
では配列を返す関数 param() があったとして
my $in = {
name => param('key') # ͜ͷؔݺͼग़͠ϦετίϯςΩετͰධՁ͞ΕΔ
};
#hatenaintern)*)+
Slide 46
Slide 46 text
コンテキストのよくある罠
my $in = {
name => ('foo', 'bar', 'baz')
};
my $in = {
name => 'foo',
bar => 'baz',
};
という感じになり、なぜかbarという不思議なキーが⽣え、不可解
なバグの原因となりうる
#hatenaintern)*)+
Slide 47
Slide 47 text
コンテキストクイズ
sort <͜͜>;
length <͜͜>;
if (<͜͜>) { }
for my $i (<͜͜>) { }
$obj->method(<͜͜>);
my $x = <͜͜>;
my ($x) = <͜͜>;
my @y = <͜͜>;
my %hash = (
key0 => 'hoge',
key1 => <͜͜>,
);
scalar(<͜͜>);
<͜͜>;
#hatenaintern)*)+
Slide 48
Slide 48 text
コンテキストクイズ(解答)
sort <Ϧετ>;
length <Ϧετ>;
if (<εΧϥ>) { }
for my $i (<Ϧετ>) { }
$obj->method(<Ϧετ>);
my $x = <εΧϥ>
my ($x) = <Ϧετ>;
my @y = <Ϧετ>;
my %hash = (
key0 => 'hoge',
key1 => <εΧϥ>,
);
scalar(<Ϧετ>);
<εΧϥ>;
#hatenaintern)*)+
Slide 49
Slide 49 text
関数(サブルーチン)
sub foo {
my ($a, $b, $c) = @_;
}
のように宣⾔して
foo(1, 2, 3);
で呼び出す。引数なしの関数呼び出しはカッコ省略できる
#hatenaintern)*)+
Slide 50
Slide 50 text
引数の受け取り⽅
sub add {
my ($x, $y) = @_;
return $x + $y;
}
my $three = add(1, 2);
• add(1,2) と呼び出したときの引数は @_ という特殊な配列に格納さ
れる
• これが($x, $y)に分割代⼊される
#hatenaintern)*)+
Slide 51
Slide 51 text
引数の受け取り⽅
• shiftを使う
• 引数なしのshiftは暗黙的に@_を引数に取る
• my $arg1 = shift;とすると@_の先頭要素が$arg1に代⼊され
る
• @_は配列なので...
• my $arg1 = $_[0]で最初の引数にアクセスすることもできる
#hatenaintern)*)+
Slide 52
Slide 52 text
引数処理イディオム
sub func1 {
my ($arg1, $arg2, %args) = @_;
my $opt1 = $args{opt1};
my $opt2 = $args{opt2};
}
func1('hoge', 'fuga', opt1 => 1, opt2 => 2);
最後に%argsと受けることで(省略可能な)名前付き引数を実現で
きる
#hatenaintern)*)+
メソッド
package Person;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
sub age {
my ($self) = @_;
return $self->{age};
}
sub incr_age {
my ($self) = @_;
$self->{age}++;
}
#hatenaintern)*)+
継承
package Animal;
use strict;
use warnings;
sub new { ... }
sub walk { ... }
1;
package Dog;
use strict;
use warnings;
use parent 'Animal';
1;
#hatenaintern)*)+
便利なCPANモジュール
package Foo;
use strict;
use warnings;
use Class::Accessor::Lite (
new => 1,
ro => ['bar'],
);
1;
my $foo = Foo->new(bar => 1); # new Ͱ͖ͯΔ
$fop->bar; # bar ϝιουੜ͑ͯΔ
#hatenaintern)*)+
便利なCPANモジュール
なんとか::Liteとかの⾼速なモジュールはだいたい⽇本のコミュニ
ティから作られている
"why does it need to be so fast?"
"because we are japanese !!!!"
https://uzulla.hateblo.jp/entry/<=>?/=@/>=A=B<@
#hatenaintern)*)+
テスト
use strict;
use warnings;
use Test::More;
use Person;
my $person = Person->new(age => 18);
is $person->age, 18, '࠷ॳ18ࡀ';
$person->incr_age;
is $person->age, 19, 'incr_age ݺΜͩΒ19ࡀ';
done_testing;
#hatenaintern)*)+
Test::Class
package t::Person;
use strict;
use warnings;
use parent 'Test::Class';
sub setup : Test(setup) { # ͳʹ͔ෆࢥٞͳຐ๏Ͱ໊ؔͷ͋ͱʹΞϊʔςʔγϣϯͰ͖Δ
# ֤ςετલͷηοτΞοϓʢมΛΫϦΞͨ͠Γͱ͔ʣ
}
sub incr_age : Tests {
is ...;
}
#hatenaintern)*)+