SSブログ

関数やメソッドがない場合の動作を定義する方法の比較 [言語比較]

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);

?>
関数

関数については不明。


nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。