BEGIN句、useに関する Perl Quiz に挑戦してみよう！

# Perl Quiz

Perl の `BEGIN` 句とか `use` まわりでつまずくことがあまりに多かったので、Quiz形式にして知識を確認できるようにしてみました。

Quiz1〜6について、それぞれ実行結果を予想してみてください。
なお、問題によっては実行時エラーの可能性もあるので、エラーの場合は「エラー」と回答してくださいね！

それではいってみましょう。


## Quiz1

`BEGIN` 句の問題です。

`1`, `2`, `3` はどの順番で `print` されるでしょうか？
エラーの場合は「エラー」と回答してください。

これは簡単ですね！

```perl
#!/usr/bin/env perl
use strict;
use warnings;

print 1;

BEGIN {
    print 2;
}

print 3;
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz1-answer-markdown)


## Quiz2

`BEGIN` 句の問題その2です。

何が `print` されるでしょうか？
エラーの場合は「エラー」と回答してください。

```perl
#!/usr/bin/env perl
use strict;
use warnings;

my $var = 'foo';

BEGIN {
    print $var; 
}
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz2-answer-markdown)


## Quiz3

`BEGIN` 句の問題その3です。
前問とは `my $var = 'foo';` の位置が変わっていますね。 

何が `print` されるでしょうか？
エラーの場合は「エラー」と回答してください。

```perl
#!/usr/bin/env perl
use strict;
use warnings;

BEGIN {
    print $var; 
}

my $var = 'foo';
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz3-answer-markdown)


## Quiz4

`BEGIN` 句の問題その4です。

何が `print` されるでしょうか？
エラーの場合は「エラー」と回答してください。

```perl
#!/usr/bin/env perl
use strict;
use warnings;

my $var;

BEGIN {
    $var = 'foo';
}

print $var; 
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz4-answer-markdown)


## Quiz5

今回は複数のモジュールを読み込んだ場合の `BEGIN` 句の実行順序の問題です。

main.plを実行すると、`main BEGIN`, `main`, `Foo BEGIN`, `Foo`, `Bar BEGIN`, `Bar`はどの順番で `print` されるでしょうか？
エラーの場合は「エラー」と回答してください。

（main.pl）

```perl
#!/usr/bin/env perl
use strict;
use warnings;

use Foo;

BEGIN {
    print "main BEGIN\n";
}

print "main\n";

use Bar;
```

（lib/Foo.pm）

```perl
package Foo;
use strict;
use warnings;

print "Foo\n";

BEGIN {
    print "Foo BEGIN\n";
}

1;
```

（lib/Bar.pm）

```perl
package Bar;
use strict;
use warnings;

print "Bar\n";

BEGIN {
    print "Bar BEGIN\n";
}

1;
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz5-answer-markdown)


## Quiz6

最後の問題です。`use` / `require` の実行タイミング、 `Exporter` の振る舞い、プロトタイピングの振る舞いを熟知していれば解けるはずです！（たぶん）

main.pl を実行して表示される内容を、下の表の空欄部分について答えてください。
なお、コードの中で `# ほげほげパターン` と書いてある行のみコメントが解除されものとします。

|                            | `use constant BAR` パターン | `sub BAR` パターン | `sub BAR ()` パターン |
|:---------------------------|:---------------------------:|:------------------:|:---------------------:|
| `use Foo` **パターン**     |                             |                    |                       |
| `require Foo` **パターン** |                             |                    |                       |

（main.pl）

```perl
#! /usr/bin/env perl
use strict;
use warnings;

use Test::MockModule;

my $mocked_bar = Test::MockModule->new('Bar');
# $mocked_bar->mock('BAR', sub () { 'bye!' }); # use constant BAR パターンまたは sub BAR () パターン
# $mocked_bar->mock('BAR', sub { 'bye!' });    # sub BAR パターン

use Foo;     # use Foo パターン
require Foo; # require Foo パターン
Foo::say();
```

（lib/Foo.pm）

```perl
package Foo;
use strict;
use warnings;

use Bar qw/BAR/;

sub say {
    print BAR;
    print Bar::BAR;
}

1;
```
（lib/Bar.pm）

```perl
package Bar;
use strict;
use warnings;
use Exporter qw/import/;

our @EXPORT_OK = qw/BAR/;

# use constant BAR => 'hello!'; # use constant BAR パターン
# sub BAR { 'hello!' }          # sub BAR パターン
# sub BAR () { 'hello!' }       # sub BAR () パターン

1;
```

[答え](https://gist.github.com/Kuniwak/fb6b2d353b2133216bcf/ab3137893c03ab88852c0a57e4c61f90510d8604#file-perl-quiz6-answer-markdown)


# おわりに

いかがでしたか？
直感に反する振る舞いがいくつかあったと思います。
後日、解説記事を公開する予定ですので、ぜひご覧ください！