[C++-sig] Interface design.

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Wed Apr 23 01:00:47 CEST 2003


--- David Abrahams <dave at boost-consulting.com> wrote:
> Exercise for the reader: finish the following proof-of-concept code
> which uses metaclasses to allow a nicer syntax for injection of
> additional methods:
> 
>     # The one Boost.Python uses for all wrapped classes.
>     class BoostPythonMetaclass(type): pass
> 
>     # some Boost.Python wrapped class
>     class foo(object):
>         __metaclass__ = BoostPythonMetaclass
> 
>     class injector(object):
>         class __metaclass__(BoostPythonMetaclass):
>             def __init__(self, name, bases, dict):
>                 for b in bases:
>                     if type(b) not in (self, type):
>                         for k,v in dict.items():
>                             setattr(b,k,v)
>                 return type.__init__(self, name, bases, dict)
> 
>     # inject some methods in foo
>     class more_foo(injector, foo):
>         def __repr__(self):
>             return 'foobar'
>         def ga(self, x):
>             return getattr(self, x)
> 
>     print repr(foo())
>     print foo().ga('__repr__')
> 
> Its biggest problem is that it sets some attributes it shouldn't,
> like __module__ and, well, __metaclass__ ;-)

Cool! A few simple conventions could solve this in a general way. E.g.:

- Only function names starting with a letter are injected.

- The prefix "inject" is stripped.

So __repr__ could be def'ed as inject__repr__.

FWIW: here is an alternative that I am actually using:

Create a new module foo_inject.py.
def all additional functions at module scope.
In another module (e.g. __init__.py):

for v in foo_inject.__dict__.values():
  if (hasattr(v, "func_name")):
    setattr(foo, v.func_name, v)

Ralf


__________________________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo
http://search.yahoo.com




More information about the Cplusplus-sig mailing list