例えば、Perlではオブジェクトを文字列として評価したときの挙動をコントロールしたい場合は、
以下のようにoverloadプラグマを利用して文字列化のためのメソッドをcoderefとして登録すると良い。
package MyURI; use strict; use warnings; use utf8; use Class::Accessor::Lite ( rw => [qw/scheme host path query/], new => 1, ); use overload ( q{""} => \&as_string, fallback => 1, ); sub as_string { my $self = shift; my $uri_str = sprintf '%s://%s%s', $self->scheme, $self->host, $self->path; $uri_str .= '?' . $self->query if $self->query; return $uri_str; } 1;
このMyURIのObjectを以下のコードのように文字列として評価させようとすると、
内部的に上のoverloadプラグマで指定したas_stringメソッド*1が実行される。
use strict; use warnings; use utf8; use MyURI; my $uri = MyURI->new( scheme => 'http', host => 'www.example.co.jp', path => '/', ); print $uri, "\n"; # http://www.example.co.jp/ $uri->query('aaa=bbb'); print $uri, "\n"; # http://www.example.co.jp/?aaa=bbb
先日、業務でJavaScriptで同様の事をやりたくなり、調べたところ、
以下のようにtoStringメソッドをoverrideすると出来るらしい事が分かった。
var MyURI = (function () { var Constructor = function (opt) { this.scheme = opt.scheme; this.host = opt.host; this.path = opt.path; this.query = opt.query; }; Constructor.prototype.toString = function () { var uriStr = this.scheme + '://' + this.host + this.path; if (this.query) uriStr += '?' + this.query; return uriStr; }; return Constructor; })();
以下のように呼び出してみると、ちゃんと文字列化出来ているのが分かる。
var uri = new MyURI({ scheme: 'http', host: 'www.example.co.jp', path: '/' }); console.log(uri + ""); // http://www.example.co.jp/ uri.query = 'aaa=bbb'; console.log(uri + ""); // http://www.example.co.jp/?aaa=bbb
参考記事
http://blog.livedoor.jp/dankogai/archives/50851804.html
http://blog.anselmbradford.com/2009/04/05/object-oriented-javascript-tip-overriding-tostring-for-readable-object-imprints/