LoginSignup
15
11

More than 5 years have passed since last update.

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

Posted at

Perl Quiz

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

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

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

Quiz1

BEGIN 句の問題です。

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

これは簡単ですね!

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

print 1;

BEGIN {
    print 2;
}

print 3;

答え

Quiz2

BEGIN 句の問題その2です。

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

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

my $var = 'foo';

BEGIN {
    print $var; 
}

答え

Quiz3

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

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

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

BEGIN {
    print $var; 
}

my $var = 'foo';

答え

Quiz4

BEGIN 句の問題その4です。

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

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

my $var;

BEGIN {
    $var = 'foo';
}

print $var; 

答え

Quiz5

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

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

(main.pl)

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

use Foo;

BEGIN {
    print "main BEGIN\n";
}

print "main\n";

use Bar;

(lib/Foo.pm)

package Foo;
use strict;
use warnings;

print "Foo\n";

BEGIN {
    print "Foo BEGIN\n";
}

1;

(lib/Bar.pm)

package Bar;
use strict;
use warnings;

print "Bar\n";

BEGIN {
    print "Bar BEGIN\n";
}

1;

答え

Quiz6

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

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

use constant BAR パターン sub BAR パターン sub BAR () パターン
use Foo パターン
require Foo パターン

(main.pl)

#! /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)

package Foo;
use strict;
use warnings;

use Bar qw/BAR/;

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

1;

(lib/Bar.pm)

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;

答え

おわりに

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

15
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
11