Featured image of post 差し替えた部品が月末だけ落ちる。Perl でインタフェースを書き、can で確かめる【Extract Interface】

差し替えた部品が月末だけ落ちる。Perl でインタフェースを書き、can で確かめる【Extract Interface】

通知先を別の部品に替えたら、日次処理は通るのに月末処理だけがメソッド不足で止まった。使う側が呼ぶメソッド名の一覧を1か所に書き、can で本物と替えの両方を確かめる――インタフェースの抽出(Extract Interface)を素の Perl で書きます。

第1幕: 検分 ── 表の戸口

今朝の素屋根は、光が弱い。

薄曇りで、隙間から差す筋は細く、鉋屑が舞っても、光の中を降りてこない。表の戸口の土間には、夏のあいだ入れていた葦戸が外されて、壁に立てかけてあった。通りを人が行き来するので、戸口の半分には養生の板が渡してあり、店の人はその脇を通っていく。クロベさんとナギさんは、板の内側で、新しい板戸を敷居の溝へ入れようとしていた。板戸は、昨日の夕方に建具屋から届いたものだった。冬のあいだ、葦戸の代わりに立てる戸になる。

私は、通りがかりに足を止めた。

ナギさんが、板戸を下から支えて、溝へ滑らせた。戸は三分の二ほど進んで、止まった。さらに押しても動かない。木と木が当たる鈍い音がして、ナギさんは手を止め、戸を少し引き戻した。鉋には、手を伸ばさなかった。

クロベさんは、戸には触れなかった。溝の脇にしゃがんで、差し金の先を、敷居の溝へ当てた。

「九分」

それだけ言って、立ち上がらずに、ナギさんのほうを見た。ナギさんは、戸の下の桟に、差し金を当てた。

「九分五厘です」

五厘、戸のほうが厚い。ナギさんは鉋を取って、桟の下面を削りはじめた。削っては戸を溝に当て、また削る。何度か繰り返したあと、戸は、最後まで滑って溝に収まった。手を添えるだけで、開け閉めができる。

そのあいだ、私は、クロベさんの手元を見ていた。溝を測った差し金が、そのまま前掛けの隠しへ戻っていく。この溝の寸法を書いたものを、私は三十年のあいだ、一度も見たことがなかった。

クロベさんは、差し金を前掛けの隠しにしまった。戸口に、鉋屑の匂いだけが残っていた。

「帳場のほうも、今朝、替えたところです」

私が切り出すと、二人がこちらを向いた。

帳場の締めは、その日の売上を数えたあと、結果を一行にして、奥の間の知らせ板へ貼り出す。店主は朝と夕にそれを見る。月末の締めでは、貼り出したあとで、板を一か月分ひとまとめに閉じる。その貼り出す先を、店主は、月末を前に、板でなく書状に替えたいと言った。ナギさんが、今朝のうちに、書状の部品を書いてくれた。

「毎日の締めの検めは、通してあります」

ナギさんが言った。

「五本、緑です」

「月末の締めも、同じ替えで通りますか」

私が訊くと、ナギさんは、返事の前に、手拭いで手を拭いた。

「月末のほうは、まだ検めていません」

月末の締めは、二日後だった。毎日の締めは通っていて、月末の道は、一度も通っていない。

クロベさんは、土間の隅の桶で手を洗い、手拭いで拭いた。

「帳場へ」

三人で、戸口を離れた。戸は、背後で、開け閉めできる形のまま、溝に収まっていた。

第2幕: 手が入らない ── 月末の道

帳場の文机には、端末が開いてあった。

ナギさんが、書状の部品を画面に出した。書いたばかりの、短い部品だった。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package Omote::Fumi;
use strict;
use warnings;

sub new {
    my ($class) = @_;
    return bless { sent => [] }, $class;
}
sub open_line   { return 1 }
sub send_notice { my ($self, $text) = @_; push @{ $self->{sent} }, $text; return 1 }

1;

blessは、ハッシュを、そのクラスのオブジェクトにする組み込みだった。open_lineは書状の口を開けること、send_noticeは知らせを一件積むこと。ナギさんは、そう説明した。毎日の締めの検めは、この二つで通っている。

ナギさんは、誰にも言われないまま、月末の締めを、この書状で走らせた。抜けた版の書状を置いたフォルダを、先に指して読み込ませる。

1
2
3
4
$ perl -Ired/lib -Ilib t/red/month_half.pl
エラー: Can't locate object method "close_line" via package "Omote::Fumi" at lib/Omote/Shirase.pm line 22.
知らせは出ている(send_notice が積んだ数): 1
控えの数: 0

エラーは一行だった。

ナギさんは、打ったコマンドの一行を、端から端まで読み直した。手は、そこで止まった。私は、出力の下の二行を読んだ。知らせは、出ている。止まったのは、そのあとだった。月末の締めを済ませたという記録は、残っていない。

「知らせは出たのに、締めが済んだことになっていません」

私が言うと、ナギさんは小さくうなずいた。

クロベさんは、書状のファイルを開かなかった。代わりに、締めを担う部品のほうを、画面に出させた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package Omote::Shirase;
use strict;
use warnings;

# 使う側。渡された line に対して、三つの名前だけを呼ぶ。
sub new {
    my ($class, %args) = @_;
    return bless { line => $args{line}, log => [] }, $class;
}

sub close_day {
    my ($self, $text) = @_;
    $self->{line}->open_line;
    $self->{line}->send_notice($text);
    return 'day closed';
}

sub close_month {
    my ($self, $text) = @_;
    $self->{line}->open_line;
    $self->{line}->send_notice($text);
    $self->{line}->close_line;
    push @{ $self->{log} }, 'month closed';
    return 'month closed';
}

# 控え(月末の締めが済んだ記録)
sub log_entries {
    my ($self) = @_;
    return @{ $self->{log} };
}

1;

「毎日の締めと、月末の締めです。どちらも、渡された一つの部品に、決まった名前を呼んで頼んでいます」

クロベさんは、この作りが今まで何を支えてきたかを、先に言った。

「頼む相手が、板でも書状でも、頼み方は一つです。この一つの頼み方が、板の時代から、毎日の締めを守ってきました。ここには、手を入れません」

それから、画面の端末に、コマンドを打たせた。

1
2
3
4
5
6
$ grep -n 'line}->' lib/Omote/Shirase.pm
13:    $self->{line}->open_line;
14:    $self->{line}->send_notice($text);
20:    $self->{line}->open_line;
21:    $self->{line}->send_notice($text);
22:    $self->{line}->close_line;

部品に頼んでいる所を、上から拾った。クロベさんは、紙を一枚取って、鉛筆で表を書いた。

名前呼ぶ所
open_line毎日の締め・月末の締め
send_notice毎日の締め・月末の締め
close_line月末の締めだけ

「三つです。月末の締めだけが、三つ目を呼んでいます」

書状には、二つしか無かった。close_lineの行は、月末の道でしか実行されない。毎日の締めは、その行まで届かないので、持っていない名前でも、落ちない。三つ目の名前が要るのは、月に一度、月末の道だけだった。

クロベさんは、もう一つ、端末に打たせた。今度は、本物の知らせ板のほうだった。

1
2
3
4
5
6
7
$ grep -n '^sub ' lib/Omote/Ita.pm
6:sub new {
10:sub open_line   { my ($self) = @_; $self->{open} = 1; return 1 }
11:sub send_notice { my ($self, $text) = @_; push @{ $self->{notices} }, $text; return 1 }
12:sub close_line  { my ($self) = @_; $self->{open} = 0; return 1 }
13:sub history     { my ($self) = @_; return @{ $self->{notices} } }
14:sub clear       { my ($self) = @_; $self->{notices} = []; return 1 }

newを除いて、名前は五つある。表の三つのほかに、historyとclearがあった。

「この二つを呼んでいる所は、ありますか」

クロベさんは、ナギさんに、探させた。historyとclearを、使う側のファイルも含めて、libとbinの全部から探す。

1
2
3
$ grep -rn -E 'history|clear' lib bin
lib/Omote/Ita.pm:13:sub history     { my ($self) = @_; return @{ $self->{notices} } }
lib/Omote/Ita.pm:14:sub clear       { my ($self) = @_; $self->{notices} = []; return 1 }

出てきたのは、板のファイルの、定義の二行だけだった。呼んでいる所は、どこにも無かった。

ナギさんは、書状のファイルに戻って、一行足した。中身は何もしない、名前だけを満たす一行だった。

1
sub close_line  { 1 }

月末の検めを、走らせ直した。

1
2
3
4
5
$ prove -l t/shirase_monthly.t
t/shirase_monthly.t .. ok
All tests successful.
Files=1, Tests=7,  0 wallclock secs
Result: PASS

緑になった。月末の締めも、書状で通るようになった。クロベさんは、書状のファイルを閉じた。

私は、野帳を膝に置いていた。月末の朝に、締めを押すのは、私だ。押したあと、替えがこの建物に合っているのかどうかを、私は、今のところ、自分では言えない。ナギさんが一行足して、緑になった。その緑が、次の替えでも続くのかどうか、確かめる手立てが、私の手元には無い。

戸の溝の九分は、書いたものが無かった。この替えに求められる名前の数と顔ぶれは、どこかに書いてあるのだろうか。

私は、野帳を閉じて、クロベさんの顔を見た。

「替えの寸法は、どこに書いてあるんですか」

クロベさんは、机の上の表を、上から順に目で追った。

「どこにも、ありません。この表にしか」

第3幕: 手立て ── 寸法を先に書く

クロベさんは、表の紙を、机の真ん中へ寄せた。

「この表は、紙の上にしかありません。機械には、読めない。使う側が呼んでいる名前だけを取り出して、替えの部品が満たすべき形として、一か所に書いておく。その技法を、インタフェースの抽出、Extract Interface と呼びます」

形、というのは、この三つの名前のことです、とクロベさんは言い足した。以降、形も、名前の一覧も、同じものを指す。

Michael Feathers の『Working Effectively with Legacy Code』に載っている技法だった。Java のように、interfaceを書ける言語が前提になっている。本の例では、描画の部品が使う側に必要なのは、点を打つ一つだけだった。だから、インタフェースにも、その一つだけを書く。使う側が必要としない名前は、入れない。私は、この二文を野帳に書いた。手順そのものは、本の言い回しではなく、今日の Perl での形で見せる、とクロベさんは言った。

「他の言語には、満たすべき形を書く場所があります。Perl には、その場所がありません」

Perl は、型を宣言しない。部品が、呼ばれた名前のメソッドを持っていれば、動く。持っていなければ、呼ばれたその場で止まる。この動き方は、前に印字の部品を替えたときに見たものと同じだった。今日はそれを、説明し直さない、とクロベさんは言った。

「場所が無いなら、場所を作ります。ただの名前の一覧を、一つのファイルに書きます」

ナギさんが、新しいファイルに、その一覧を書いた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package Omote::Sunpo;
use strict;
use warnings;

# 使う側(Omote::Shirase)が line に呼ぶ名前だけ。Ita の history / clear は入れない。
our @REQUIRED = qw(open_line send_notice close_line);

sub required { return @REQUIRED }

# bless 済みのオブジェクトかクラス名を渡す。欠けた名前を並べて返す。
sub missing {
    my ($thing) = @_;
    return grep { !$thing->can($_) } @REQUIRED;
}

1;

「ここでいう寸法は、この名前の一覧のことです」

クロベさんは、パッケージの名前を指した。Sunpo。戸口の九分とは別のもので、同じ言葉で呼んでいる。以降、コードの話では、この言葉は、名前の一覧のほうを指す。戸口の話をするときは、戸口の、と付ける。

qw(...)は、空白で区切った文字列の並びを作る書き方だった。ourは、パッケージ変数に、この場所からも名前で届くようにする宣言で、前に使ったものと同じ。新しいのは、次の二つだった。

「canは、オブジェクトやクラスの名前に、->can('名前')と続けて呼ぶと、その名前のメソッドを持っていれば、そのメソッドへの参照を返し、持っていなければ、何も返さない組み込みです。親から受け継いだ名前も、持っているものに数えます」

返ってくる「メソッドへの参照」は、その名前の処理を、あとから呼べる形にしたものだった。ここでは、あるかないかの判定にだけ使う。

もう一つのgrepは、条件に合う要素だけを、並びから取り出す組み込みだった。ここのgrep { ... }は、さっき端末で打ったgrepコマンドとは、名前が同じだけの、別のものだ。一覧の名前を一つずつ取り、canで持っていない名前だけを残して返す。canは持っていなければ何も返さず、それは偽として扱われる。!で逆にするので、持っていない名前だけが残る。返ってくるのは、欠けている名前の並びになる。

「三つの部品に、同じ検めを通します」

ナギさんが、検めのファイルを書いた。本物の知らせ板、書状、それに、前に使った検め用の代役。検めのあいだだけ本物の代わりを務める、あの部品だった。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
use strict;
use warnings;
use Test::More;
use Omote::Sunpo;
use Omote::Ita;
use Omote::Fumi;
use Stub::Line;

for my $obj (Omote::Ita->new, Omote::Fumi->new, Stub::Line->new) {
    my @lack = Omote::Sunpo::missing($obj);
    is_deeply(\@lack, [], ref($obj) . ' は使う側が呼ぶ名前を全部持つ')
        or diag "欠けた名前: @lack";
}

done_testing;

検めのファイルには、このほかに、一覧そのものと、欠けた名前を言えることを確かめる検めも書いてある。ここに出したのは、本物・替え・代役を通す部分だけだ。

refは、オブジェクトを渡すと、それが属するクラスの名前を返す組み込みだった。ここでは、検めの名前に、部品の名前を入れるためだけに使っている。

ナギさんは、まず、抜けた版の書状を先に指して、検めを走らせた。朝のうちに書いた、close_lineの無い版だ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
$ perl -Ired/lib -Ilib t/contract.t
ok 1 - 寸法(名前の一覧)は使う側が呼ぶ三つだけ
ok 2 - Omote::Ita は使う側が呼ぶ名前を全部持つ
not ok 3 - Omote::Fumi は使う側が呼ぶ名前を全部持つ
#   Failed test 'Omote::Fumi は使う側が呼ぶ名前を全部持つ'
#   at t/contract.t line 16.
#     Structures begin differing at:
#          $got->[0] = 'close_line'
#     $expected->[0] = Does not exist
# 欠けた名前: close_line
ok 4 - Stub::Line は使う側が呼ぶ名前を全部持つ
ok 5 - 欠けた名前を名前で言える(オブジェクト)
ok 6 - 欠けた名前を名前で言える(クラス名)
ok 7 - 何も無ければ三つとも欠け(一覧の順)
ok 8 - bless されていない参照は検めに渡せない
ok 9 - Ita: history は積んだ知らせを返す
ok 10 - Ita: clear で空になる
1..10
# Looks like you failed 1 test of 10.

月末の締めを走らせなくても、書状にclose_lineが無いことが、名前つきで出た。ナギさんは、直した版の書状へ戻して、もう一度走らせた。

1
2
3
4
5
6
7
$ prove -l t/
t/contract.t ......... ok
t/shirase_daily.t .... ok
t/shirase_monthly.t .. ok
All tests successful.
Files=3, Tests=22,  0 wallclock secs
Result: PASS

「一覧に、板の持っている名前を、全部入れないのは、なぜですか」

私が訊くと、クロベさんは、板の側の二つの名前を指した。

「板の五つを全部入れれば、書状も代役も、historyとclearが無くて、検めで落ちます。一覧が、使う側の必要でなく、板の持ち物になる。一覧は、使う側が呼んでいる名前だけです」

私は、検めの一行目を見た。一覧は三つだけだと、検めの側でも確かめてある。

次に、手を入れた範囲を確かめた。使う側のファイルは、一字も変えていない。一覧を読んでいるのは、検めだけだった。

1
2
$ grep -rn Sunpo lib bin
lib/Omote/Sunpo.pm:1:package Omote::Sunpo;

libとbinの中で、Sunpoという名前が出てくるのは、そのファイル自身だけだった。使う側も、本番の組み立ても、この一覧を知らない。この技法のために足したのは、一覧のファイルと、検めのファイルだけだ。

本番の組み立ては、これまでと同じ書き方だった。替えの部品に取り替えるとき、変わるのは、一か所だけだった。

1
2
3
4
5
6
# 本番の組み立て。
my $honmono = Omote::Shirase->new(line => Omote::Ita->new);
# 替えに替えた後の組み立て。違うのは line => の右側の一か所だけ。
my $kae     = Omote::Shirase->new(line => Omote::Fumi->new);

print $_->close_month('bye'), "\n" for $honmono, $kae;
1
2
month closed
month closed

組み立てる場所は、消えていない。一覧が加わっても、そこに誰かが部品を渡す仕事は、これまでと同じ場所にある。

野帳を開いて、今日手を入れた所と入れなかった所を、一枚に写してみた。一覧のファイルと検めのファイルは、墨の実線で描いた。使う側と本物の知らせ板と本番の組み立ては、一字も変えていないので、薄い墨の破線にした。一覧から検めへ、検めから三つの部品へ引いた線は太くして、使う側へは、一本も引かなかった。

野帳に描いた構成図。左の「この回で足した所」では、一覧 Omote::Sunpo から検め t/contract.t へ太い線が引かれ、検めから Omote::Fumi、Stub::Line、そして本物の Omote::Ita の三つの部品へ、同じ検めを通す太い線が伸びている。右の「この回で触っていない所」には、本番の組み立て、Omote::Shirase、Omote::Ita が灰色の破線で描かれ、組み立てから Omote::Shirase へ細い破線が一本引かれている。Omote::Shirase と一覧のあいだには線が無い

ひと通り見せ終えると、クロベさんは席を立った。何も告げずに、戸口のほうへ出ていった。しばらくして戻ってきて、席に着いた。

「宮大工の言い方では、寸法を定める、です」

「使う側は、毎日の締めを支えています。だから手を入れずに、替えのほうを合わせます。戸口の戸は削って合わせられて、溝は建物です。入る寸法は、受ける側で、先に決めておきます」

墨差しを、机の端に置いた。

私は、野帳に、定める、と書いた。戸口の九分と、今日の三つの名前は、同じことをしている。受ける側が、入るものの寸法を、先に言葉にしておくこと。

第4幕: 検め ── 一覧が古くなるとき

「使う側に、呼ぶ名前を、一つ足してみてください」

クロベさんが言った。

ナギさんは、使う側のファイルを別の場所へ写して、その写しの毎日の締めに、一行足した。本体には、触れていない。

1
2
3
$ diff lib/Omote/Shirase.pm t/red/stale_list/lib/Omote/Shirase.pm
14a15
>     $self->{line}->retry;

retryという名前を、部品に頼む。一覧は、そのままだ。検めを走らせて、続けて、実際に毎日の締めを呼んだ。

1
2
3
4
5
$ perl -It/red/stale_list/lib -Ilib t/red/stale_list/run.pl
Omote::Ita 検め: 欠け 0
Omote::Ita 実呼び出し: Can't locate object method "retry" via package "Omote::Ita" at t/red/stale_list/lib/Omote/Shirase.pm line 15.
Omote::Fumi 検め: 欠け 0
Omote::Fumi 実呼び出し: Can't locate object method "retry" via package "Omote::Fumi" at t/red/stale_list/lib/Omote/Shirase.pm line 15.

検めは、緑のままだった。実際に呼ぶと、板でも書状でも止まる。本物の知らせ板もretryを持っていないので、これは、替えの落ち度ではない。

「使う側が変わったときは、一覧は、誰が直すんですか」

私が訊くと、クロベさんは、短く答えた。

「人です。この検めは、一覧に書いてある名前を見ているだけで、使う側を見てはいません。一覧は、使う側の写しです。写しは、元が変われば、古くなります」

私は、野帳を開いた。一覧を直すのが人なら、その人は、使う側が変わったと、いつ知るのだろう。

「使う側に、呼ぶ名前を足す話は、私のところにも来ます。そのときは、一覧のことを、私から先に訊きます」

クロベさんは、うなずいた。私は、その一行を、野帳に書いた。

戸口の溝を彫り直したのに、墨で書いた九分が古いまま。そういう古さが、ここにも起こりうる。

クロベさんは、この手立てで言えることを、先に三つ言った。

「使う側と本物は、一字も変えていません。使う側が呼ぶ三つの名前が、本物にも、替えにも、代役にも揃っています。月末を待たずに、欠けた名前を、名前で言えます」

それから、言えないことを、一つずつ見せた。ナギさんが、canの見えないものを、実際に動かして並べた。

1
2
3
4
5
6
$ perl -Ilib t/red/limits.pl
Wrong     missing=[]
Child     missing=[]
AutoLine  missing=[open_line send_notice close_line]
unblessed hashref: DIED: Can't call method "can" on unblessed reference at lib/Omote/Sunpo.pm line 13.
AutoLine->new->close_line (real call): 1

Wrongは、渡された知らせを捨てて、意味のない文字列を返すsend_noticeと、呼ばれたら必ずdieするclose_lineを持つ部品で、名前の有無だけを見る検めは「欠けなし」と答えた。Childは、三つの名前を全部、親から受け継いでいる。名前の有無だけを見る検めは、これも「欠けなし」とする。AutoLineは、持っていない名前の呼び出しを、まとめて自分で受ける仕組みを持つ部品で、実際には、呼べる。それなのに、検めは、三つとも欠けと答えた。canは、その仕組みで受ける名前が見えない。四行目は、bless されていない参照を渡したときで、canの呼び出し自体が止まる。最後の行は、AutoLineのclose_lineを、実際に呼んだ結果だった。

「見えるのは、名前の有無だけです」

クロベさんは、ナギさんの出力の脇に、七つの行を書いた。

言えないことわけ
引数や中身が合っているかcanは名前の有無だけを見る。Wrongを動かした結果
受け継いだ名前の中身が合っているか持っている名前に数える。Childを動かした結果
持っていない名前をまとめて受ける部品見えず、欠けと出る。AutoLineを動かした結果
一覧と使う側のずれ検めは使う側を見ない。retryを動かした結果
bless されていない参照検めに渡せない。止まる
書状が店主の手に届くか見ていない。今日見たのは、一度動かした範囲
知らせの中身が正しいか見ていない

「最後の二つは、今日の検めの外です」

クロベさんは、鉛筆を置いた。

「今日の検めは、一度動かした話です。毎月、届き続ける保証では、ありません。もう一つ、入れていないことがあります。組み立ての時点で、欠けた名前を止める仕掛けです。入れると、これまで動いていた毎日の締めまで、止まる日が出ます。振る舞いが、変わってしまいます」

日が、午後に傾いていた。ナギさんが、自分の机から、紙を一枚持ってきた。

「シオリさん、これを通してください」

紙には、部品の名前だけが書いてあった。Omote::Fusen。ナギさんが、さっき、自分で書いた替えだった。何が抜けているかは、書いていなかった。私にも、聞かされていなかった。

私は、検めのファイルを開いた。三つの部品を並べた行の最後に、その名前を足した。useの行も一つ足して、走らせた。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ perl -Ilib t/contract.t
ok 1 - 寸法(名前の一覧)は使う側が呼ぶ三つだけ
ok 2 - Omote::Ita は使う側が呼ぶ名前を全部持つ
ok 3 - Omote::Fumi は使う側が呼ぶ名前を全部持つ
ok 4 - Stub::Line は使う側が呼ぶ名前を全部持つ
not ok 5 - Omote::Fusen は使う側が呼ぶ名前を全部持つ
#   Failed test 'Omote::Fusen は使う側が呼ぶ名前を全部持つ'
#   at t/contract.t line 17.
#     Structures begin differing at:
#          $got->[0] = 'open_line'
#     $expected->[0] = Does not exist
# 欠けた名前: open_line

赤い行は、五つ目だった。欠けた名前の行を、私は、声に出して読んだ。

「open_lineが、ありません」

ナギさんは、うなずいた。

「合っています。open_lineを抜きました」

今朝、直したのはclose_lineだった。今日、私が読んだのは、別の名前だった。クロベさんは、何も言わなかった。ナギさんは、Omote::Fusenのファイルを開いて、open_lineを一行、足しはじめた。

夕方、私は、表の戸を閉めに出た。

朝に入れた板戸を、溝に沿って滑らせる。戸は、最後まで滑って、溝に収まった。軽く手を添えると、音も立てずに閉まる。戸の下をのぞくと、敷居の内側に、墨で小さく、九分、と書いてあるのが見えた。

通りの人の足音が、戸の向こうで、遠ざかっていった。


普請控

  • 見立て: 知らせ先を板から書状に替えたところ、毎日の締めは通ったが、月末の締めだけが、書状に無い名前を呼んで止まった。使う側がどの名前を呼んでいるのかは、どこにも書かれておらず、替えを書く人は、使う側を読み取るほかなかった
  • 手を入れた所: インタフェースの抽出(Extract Interface)を使った。使う側が呼ぶ三つの名前をOmote::Sunpoに一覧として書き、本物の知らせ板・書状・検め用の代役に、同じ検めを通して、欠けた名前を名前で言えるようにした。書状には、欠けていたclose_lineを一行足した
  • 触っていない所: 使う側のOmote::Shirase(毎日の締めと月末の締めの呼び方)、本物の知らせ板Omote::Ita(historyとclearは使う側が呼ばないので、一覧に入れていない)、本番の組み立ての書き方(line =>の右側だけが替えの違い)は、一字も変えていない。canが区別できない所(引数と中身・受け継いだ名前の中身・まとめて受ける仕組みの名前)、一覧と使う側の呼び出しを突き合わせる仕掛け、書状が店主に実際に届くかどうかは、見ていない
  • 次の工程へ送ること: 組み立ての時点で、欠けた名前を止める仕掛けと、一覧と使う側の呼び出しを突き合わせる検めは、今日は置かない。前者は、これまで動いていた毎日の締めまで止めてしまい、振る舞いが変わるため。後者は、使う側の呼び出しが決まった書き方のうちは拾えても、名前を組み立てて呼ぶ所は見落とすため、呼び出しがどこに集まっているかを見てからにする
  • 私が引き受けたこと: 替えが寸法に合うかどうかを、私が自分の検めで確かめられる。ナギさんが用意した、何が抜けているかを聞かされていない替えに検めを通し、欠けた名前を読んで返した。使う側に呼ぶ名前を足す話を聞いたら、一覧のことを私から先に訊く、と決めて、野帳に控えた
comments powered by Disqus
システム開発・AIワークフローのご相談は Meetsource へ
Hugo で構築されています。
テーマ Stack は Jimmy によって設計されています。