PerlのOOにおける強力な機構の一つに、AUTOLOADがあります。
具体的に他の言語でAUTOLOADを実現する方法にはどんなものがあるでしょうか?
たとえば、こんなことをしてほしいClassを考えます。
use strict; use warnings; use Unicode::Char; my $u = Unicode::Char->new; binmode STDOUT, ":utf8"; # 小飼弾と表示 print $u->u5c0f, $u->u98fc, $u->u5f3e, "\n";
Perlでは、以下で出来ます。
package Unicode::Char; use strict; use warnings; use Carp; our $DEBUG = 1; sub new { my $pkg = shift; return bless \eval{ my $scalar }, $pkg; } sub DESTROY{} # so AUTOLOAD will not handle this sub AUTOLOAD{ my $self = shift; my $method = our $AUTOLOAD; $DEBUG and carp $method; $method =~ s/.*:://o; $method =~ s/^u_?//o; return chr(hex($method)); } 1;
あるいは、AUTOLOAD()を以下のように書き換えて、AUTOLOADは最初の一回目の呼び出し時のみに使われるようにも出来ます。
sub AUTOLOAD{ my $method = our $AUTOLOAD; $DEBUG and carp $method; $method =~ s/.*:://o; $method =~ s/^u_?//o; no strict 'refs'; *{$AUTOLOAD} = sub { my $self = shift; return chr(hex($method)); }; goto &$AUTOLOAD; }
要は動的にかつeval()に頼らずにメソッドを生成しているわけです。
これって他のLLではどうやってやるんでしょう?
さらに詳しいことを知りたい人は、↑のAdvanced Perl Programmingを読みましょう。
Dan the Perl Monger
追伸:
rubyco(るびこ)の日記 - メソッド名自動生成Danさんからお題が出ていたのでRubyで書いてみました。(Danさんのこのエントリ、なぜかトラックバックもコメントもできない…)
へ?と見てみたら、trackbackの設定のところで「する」にも「しない」にもradio buttonが付いてないというちょっと奇妙な事態になっていました。再構築したらなおったので皆さん改めてTBくださいませ
というか、こちらからTBとばしちゃいます。
回答編(順不同):- Ruby
- rubyco(るびこ)の日記 - メソッド名自動生成
- PHP
- p4lifeのメモ - 「Perl Monger の質問 - AUTOLOADって他でどうやるの?」:PHP編
- Gauce (scheme)
- shiroさんによるコメント参照
- Squeak (smalltalk)
- sumim’s smalltalking-tos - 起動すべきメソッドが見つからないメッセージに対処する
- Python
- パパパパパイソン - メソッド名自動生成
- へいきちさんのコメント参照
- TCL
- shiroさんのコメント参照
これでLLの主なところは揃ったのだけど、常にmissing methodが呼ばれるものばかりで、perlのgoto &$AUTOLOADに相当するものがまだにゃいなあ....
これではダメですねorz.
? はバックスラッシュってことで。
import sys, codecs
class my_unicode:
..def __getattr__(self, attrname):
....return (lambda: unicode('??' + attrname, 'raw-unicode-escape'))
if __name__ == '__main__':
..(e,d,sr,sw) = codecs.lookup('utf-8')
..sys.stdout = sw(sys.stdout)
..u = my_unicode()
..print u.u5c0f() + u.u98fc() + u.u5f3e()