読者です 読者をやめる 読者になる 読者になる

ついにPerlでオブジェクト指向・いろいろ補足編

表題の件、昨日書いた記事で2点ほど謎が残ってしまっていたのですが、今朝すっきりした頭でトライしたら分かった(はずな)ので、一日仕事してふたたび夜中になった今、あらためて書きます。

まず、前回の内容は以下ですが、
ついにPerlでオブジェクト指向 - draft

それを経て、どんな謎が残っていたのかというと、ひとつは、以下のモジュール「PerlEntrance.pm」に対して、

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

package PerlEntrance {
    sub tokyo {
        print "papix!!!\n";
    }
    sub osaka {
	print "boolfool!!!\n";
    }
}

1;

以下の処理「practice.pl」を実行しますと、

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

use PerlEntrance;

print PerlEntrance::tokyo();
print PerlEntrance::osaka();

こんな風に出てきたんでした。

papix!!!
1boolfool!!!
1

ええ、まあ、この「boolfool!!!」の前後にそれぞれ入ってる「1」は何なのか、と。
何なのかと、いうところで一旦その記事は終わったのでしたが、

そうしましたら、Perl入学式にサポーターとして参加してくださっていますてつじさん(@xtetsuji)からコメントを頂きまして、*.pmの方ですでにサブルーチン内にprint関数を使っているので、*.plでもprint関数を使うことで、print可能な1が戻ってしまうのでは、と。
よって上記の場合、*.plでprint関数を使わなければ解決できるというお話で、やってみたらまさに、

papix!!!
boolfool!!!

が戻ってきました! ありがとうございます!!

さて、しかし・・個人的にはそれでもう、全部解決した気になっていたのですが、もうひとつ謎が残っていまして、具体的には以下のお題目に沿って、
https://github.com/perl-entrance-org/workshop-2013-05/blob/master/slide.md#%E3%83%86%E3%82%B9%E3%83%88
以下のようなテスト「practice.t」を書きましたところ、

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

use Test::More;
use PerlEntrance;

is PerlEntrance::tokyo(), 'moznion!!!';

done_testing();

こんなふうな結果になってしまい・・

practice.t .. 1/?
#   Failed test at practice.t line 8.
#          got: '1'
#     expected: 'moznion!!!'
# Looks like you failed 1 test of 1.
practice.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/1 subtests

Test Summary Report
-------------------
practice.t (Wstat: 256 Tests: 1 Failed: 1)
  Failed test:  1
  Non-zero exit status: 1
Files=1, Tests=1,  1 wallclock secs ( 0.05 usr  0.01 sys +  0.05 cusr  0.01 csys =  0.12 CPU)
Result: FAIL

ええ、ようは、本来なら結果の3行目で、

#          got: 'papix!!!'

と返るはずのところが、

#          got: '1'

という具合にまた(まだ)「1」が返っています。

で、昨夜はこれがもういくら調べても分からなくて、そもそもこの「Test::More」って何なんだ? テストの書き方に間違いがあるのでは・・と、「Test::More」関連のブログ記事をいろいろ漁ったり、それに沿って「practice.t」をあれこれ書き換えてみたりとか、それはそれで楽しかったのですが、どうもこれが違う、という確証も持てず、とりあえず謎のママでその日は終わり・・

でも翌日になって、よくよく考えてみたらやっぱり、「1」が返ってる時点でテストの方はちゃんと動いてるじゃないかと。そう思い至りまして。んで、そうなると問題はもう一方のスクリプトである「PerlEntrance.pm」にあることになるわけですが、いくらじっくり見直してもやっぱりわからない。

わからないんだけど、ふと、「あれそういえば、この第5回の内容について詳細にレポートされている受講生の方がいたなあ〜」と思い出しまして、そこでは確か、こんな問題が生じたなんてぜんぜん書いてなかったはずだな、と。であれば、そこに回答またはそのきっかけがあるのでは、と思って、そちらの記事を見直しました。
Perl入学式in東京 #5に参加しました - m_shige1979のささやかな抵抗と欲望の日々

そうしたら、おそらく現場でいろいろ資料以外の情報が出たのか、細かく異なるところもいくつかあるのですが、何より当該部分が「print」ではなく「return」になってる!!

ということで、さっそく上記の「PerlEntrance.pm」もそのように書き直しました。

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

package PerlEntrance {
    sub tokyo {
        return "papix!!!\n";
    }
    sub osaka {
        return "boolfool!!!\n";
    }
}

1;

すると、テストの結果が・・

practice.t .. 1/?
#   Failed test at practice.t line 8.
#          got: 'papix!!!
# '
#     expected: 'moznion!!!'
# Looks like you failed 1 test of 1.
practice.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/1 subtests

Test Summary Report
-------------------
practice.t (Wstat: 256 Tests: 1 Failed: 1)
  Failed test:  1
  Non-zero exit status: 1
Files=1, Tests=1,  1 wallclock secs ( 0.06 usr  0.01 sys +  0.05 cusr  0.01 csys =  0.13 CPU)
Result: FAIL

やった!! ついに「1」ではなく「papix!!!」が戻ってます。

いやあ〜、良かった〜! ということで、これを受けてあらためて、.pmの「papix」を「moznion」に修正して・・

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

package PerlEntrance {
    sub tokyo {
        return "moznion!!!\n";
    }
    sub osaka {
	return "boolfool!!!\n";
    }
}

1;

実行!!!

practice.t .. 1/?
#   Failed test at practice.t line 8.
#          got: 'moznion!!!
# '
#     expected: 'moznion!!!'
# Looks like you failed 1 test of 1.
practice.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/1 subtests

Test Summary Report
-------------------
practice.t (Wstat: 256 Tests: 1 Failed: 1)
  Failed test:  1
  Non-zero exit status: 1
Files=1, Tests=1,  0 wallclock secs ( 0.05 usr  0.01 sys +  0.05 cusr  0.01 csys =  0.12 CPU)
Result: FAIL

・・・あれ??? 「All tests successful.」じゃない??
文字列的には「moznion!!!」になってるし・・一致しているはずなんだけど・・

と思ったら、よく見たらなんか、「got:」の方は「moznion!!!」を閉じるシングルクォーテーションが次の行にいってますね・・
というか一つ前の実行結果も、よく見たら「papix!!!」の閉じ括弧が改行されてるやん・・気づいてなかった。

ということは・・と思って、再び自分の「PerlEntrance.pm」をチェック。
すると、そうか、「moznion!!!」の後に「\n」が入ってる。これのせいか? と思って、先ほどの受講生さんのブログをもう一回見にいくと、やっぱり、「\n」なんて入ってない!

ということで、あらためてその点を修正したのがこちら。

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

package PerlEntrance {
    sub tokyo {
        return "moznion!!!";
    }
    sub osaka {
        return "boolfool!!!";
    }
}

1;

で、実行!!!(何度目の・・)

practice.t .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.05 usr  0.01 sys +  0.05 cusr  0.01 csys =  0.12 CPU)
Result: PASS

はい〜〜! できた〜〜〜!!(笑)
いやあ長かったな・・

しかしこれ、こうなると今度はまた「practice.pl」の方にはprint関数を付けなきゃいけなさそうですね・・
かつ、そのまま実行すると改行がなくなっちゃうようなので、こんな感じ?

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

print PerlEntrance::tokyo()."\n";
print PerlEntrance::osaka()."\n";

ん〜む、正解かどうかは分かりませんが、とりあえず個人的には納得しました。

さてそれで、この次はいよいよ第5回の最終問題ですか。
次回はそちらを扱いたいと思いますが、
https://github.com/perl-entrance-org/workshop-2013-05/blob/master/slide.md#%E6%9C%80%E7%B5%82%E5%95%8F%E9%A1%8C

じつは今回のこのハマりにともなって、いろいろ本の資料を読んだり、試したりしたこともあったので、できればその辺についても時間のあるときに触れられたらなあ、とも思っています。

あとはそれとは別にここ数日、自分の作業のために作った&使った小さいスクリプトなどもあるので、それも紹介したりご意見を伺ったりしていきたいとおぼろげに思っています。年内は難しいかな・・とも思うけど、でも1月半ば以降けっこう多忙になりそうなので、出来るときに出来るだけ書きたいですが・・