関数やメソッドがない場合の動作を定義する方法の比較 [言語比較]
Ruby
メソッド
method_missing メソッドを定義することで可能。呼び出し時にメソッドが無かった場合はこれが呼ばれる。
irb(main):005:0> class Foo irb(main):006:1> def method_missing(name, *args) irb(main):007:2> puts "#{name}: #{args.inspect}" irb(main):008:2> end irb(main):009:1> end nil irb(main):010:0> Foo.new.foo(1,2,3) foo: [1, 2, 3] nil irb(main):011:0>
関数
関数についても同様。
irb(main):001:0> def method_missing(name, *args) irb(main):002:1> puts "#{name}: #{args.inspect}" irb(main):003:1> end nil irb(main):004:0> foo(1,2,3) foo: [1, 2, 3] nil
Perl
メソッド
AUTOLOAD を定義してあげるとできる。
{
package Foo;
sub new { bless {}, shift; }
sub AUTOLOAD {
shift;
print "$AUTOLOAD: ";
print "@_\n";
}
}
$foo = new Foo;
$foo->foo(1, 2, 3);
関数
関数のサーチは最終的に UNIVERSAL パッケージにたどり着くので、そこで AUTOLOAD を定義すればよい。
{
package UNIVERSAL;
sub AUTOLOAD {
print "$AUTOLOAD: ";
print "@_\n";
}
}
foo(1, 2, 3);
Python
メソッド
__getattr__ を定義することで可能。属性の値として関数を返すというところに注意。
>>> class Foo: ... def __getattr__(self, name): ... def tmpf(*args): ... print name+":", ... for x in args: ... print x, ... return tmpf ... >>> Foo().foo(1,2,3) foo: 1 2 3
関数
関数についてはわからない。
Tcl
メソッド
Tcl には標準のオブジェクト指向機構はない。古典的な「プロシージャ=オブジェクト」方式の場合、そもそもメソッドのディスパッチをユーザレベルで書くことになるのである意味どうにでもなる。
関数
プロシージャが見つからない場合は unknown コマンドが呼ばれる。
% proc unknown {name args} { puts [concat "$name: " $args] } % foo 1 2 3 foo: 1 2 3
Lua
メソッド
テーブルにメタメソッドを定義する。Python と同様に関数を返すやり方。
> foo = {} > setmetatable(foo, { >> __index = function(t, k) >> return function(...) >> io.write(k..": ") >> for i, v in ipairs{...} do >> io.write(v.." ") >> end >> print() >> end >> end >> }) > foo.foo(1,2,3) foo: 1 2 3
関数
_G にメタメソッドを定義する。
> setmetatable(_G, { >> __index = function(t, k) >> return function(...) >> io.write(k..": ") >> for i, v in ipairs{...} do >> io.write(v.." ") >> end >> print() >> end >> end >> }) > foo(1,2,3) foo: 1 2 3
Lua は「未定義のグローバル変数の参照は nil を返す」という既定動作があるが、Lua は関数と変数の名前空間が同じなので上記を実施した場合影響を受けてしまう。
JavaScript
prototype プロパティという仕組みはあるのだが、上記の他の言語に対応するコードは書けないような気がする。
Lisp
わかりません(こればっかり)。
PHP
(2006-11-22 に追加)
メソッド
__call メソッドを定義する。
<?php
class Foo {
public function __call($name, $args) {
print("$name:\n");
print_r($args);
}
}
$o = new Foo;
$o->foo(1, 2, 3);
?>
関数
関数については不明。
コメント 0