PythonをRubyっぽく書くテスト
Dive Into Pythonの
あたりを読んでいて思い付きました。何度目の車輪の再発明なのかは謎です。
まず、以下のようなクラスを定義します。
class Object: def __init__(self, instance): self.__dict__.update([(attr, getattr(instance, attr)) for attr in dir(instance)]) self.instance = instance def __getattr__(self, attr): if hasattr(self.instance, attr): return getattr(self.instance, attr) else: return getattr(__builtins__, attr)(self.instance)
すると、
>>> i = Object(97) >>> i.abs 97 >>> i = Object(97) >>> i.chr 'a' >>> i.complex (97+0j) >>> i.float 97.0 >>> l = Object([4, 2, 1, 3]) >>> l.sorted [1, 2, 3, 4] >>> l.min 1 >>> l.sum 10 >>> for i in l.reversed: print i, ... 3 1 2 4 >>> s = Object('hoge') >>> s.len 4 >>> s.index('o') 1 >>> s.type <type 'str'> >>> s.id -1215441888
こんな感じに書けます。
要は、元のオブジェクトに該当するメソッドや属性がなかった場合、オブジェクトを第一引数にするような組み込み関数を、Rubyのメッセージのように呼び出せるわけです。
dirすると元のオブジェクト(intやlistやstring)と同じ属性を持っているのがわかると思います。
>>> l.dir ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'instance', 'pop', 'remove', 'reverse', 'sort']
まあ、問題は、いちいち s = Object('hoge')みたいにするのがめんどくさいことなのですが。。(^^;
もしかしてこの辺の振る舞いもフック&自動化できたりするのかなぁ。