overloadプラグマの使い方
404 Blog Not Found:紹介 - Software Design 2013年06月号
呼ばれてないけど勝手に添削。
use overload '""' => 'toString', '_' => 'add', ;はないわー。そこは
use overload '""' => \&toString, '_' => \&add, ;でしょうが。
いいえ、overloadプラグマの引数は文字列でいいんです。でないとサブクラスでオーバーライドできませんから。
つまり、overloadプラグマへ与えるメソッドの実体$method
は、$obj->$method()
として与えられたかのように振舞うのです。コードリファレンスを与えると、メソッドのレシーバが何であろうとそのコードリファレンスが呼び出されてしまいます。文字列であれば、サブクラスでたとえばtoString()メソッドをオーバーライドしたときに正しくそのサブクラスのtoString()メソッドが呼び出されます。オーバーライドしたメソッドを適切に呼び出すということであれば'""' => sub { shift()->toString() }
でもかまいませんが、ぼくは文字列で指定するほうが簡潔なので好きです。
以下検証コード:
#!perl use 5.14.0; use strict; use warnings; package ByStr { use overload '""' => 'toString'; sub new { my($class) = @_; return bless {}, $class; } sub toString { __PACKAGE__ } } package ByCodeRef { use overload '""' => \&toString; sub new { my($class) = @_; return bless {}, $class; } sub toString { __PACKAGE__ } } package DerivedFromByStr { use parent -norequire, 'ByStr'; sub toString { __PACKAGE__ } } package DerivedFromByCodeRef { use parent -norequire, 'ByCodeRef'; sub toString { __PACKAGE__ } } say DerivedFromByStr->new(); # "DerivedFromByStr" <- オーバーライドできている say DerivedFromByCodeRef->new(); # "ByCodeRef" <- オーバーライドできていない