diff options
author | Marcelo Lira <marcelo.lira@openbossa.org> | 2011-01-12 16:24:10 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:12:53 -0300 |
commit | 78e3c256ff6a154ce8068b3dd7bc551394d73422 (patch) | |
tree | ff9491186a25de7d5906bd29b788831a24e451a3 /doc | |
parent | 0eef7934bc0dc0a3b915c1502bfc0be60d7eb365 (diff) |
Updated Shiboken documentation with advice about duck punching and virtual methods.
Reviewed by Luciano Wolf <luciano.wolf@openbossa.org>
Reviewed by Renato Araújo <renato.filho@openbossa.org>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/_templates/index.html | 2 | ||||
-rw-r--r-- | doc/contents.rst | 1 | ||||
-rw-r--r-- | doc/wordsofadvice.rst | 71 |
3 files changed, 74 insertions, 0 deletions
diff --git a/doc/_templates/index.html b/doc/_templates/index.html index 076f3bd3d..129a398be 100644 --- a/doc/_templates/index.html +++ b/doc/_templates/index.html @@ -25,6 +25,8 @@ <span class="linkdescr">support for python sequence protocol</span></p> <p class="biglink"><a class="biglink" href="{{ pathto("ownership") }}">Object Ownership</a><br/> <span class="linkdescr">object ownership features</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("wordsofadvice") }}">Words of Advice</a><br/> + <span class="linkdescr">Advice for binding developers and users.</span></p> </td></tr> </table> </div> diff --git a/doc/contents.rst b/doc/contents.rst index 6292e9527..a97216937 100644 --- a/doc/contents.rst +++ b/doc/contents.rst @@ -10,3 +10,4 @@ Table of contents codeinjectionsemantics.rst sequenceprotocol.rst ownership.rst + wordsofadvice.rst diff --git a/doc/wordsofadvice.rst b/doc/wordsofadvice.rst new file mode 100644 index 000000000..d27cae00f --- /dev/null +++ b/doc/wordsofadvice.rst @@ -0,0 +1,71 @@ +.. _words-of-advice: + +*************** +Words of Advice +*************** + +When writing or using Python bindings there is some things you must keep in mind. + + +.. _duck-punching-and-virtual-methods: + +Duck punching and virtual methods +================================= + +The combination of duck punching, the practice of altering class characteristics +of already instantiated objects, and virtual methods of wrapped C++ classes, can +be tricky. That was an optimistic statement. + +Let's see duck punching in action for educational purposes. + + .. code-block:: python + + import types + import Binding + + obj = Binding.CppClass() + + # CppClass has a virtual method called 'virtualMethod', + # but we don't like it anymore. + def myVirtualMethod(self_obj, arg): + pass + + obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass) + + +If some C++ code happens to call `CppClass::virtualMethod(...)` on the C++ object +held by "obj" Python object, the new duck punched "virtualMethod" method will be +properly called. That happens because the underlying C++ object is in fact an instance +of a generated C++ class that inherits from `CppClass`, let's call it `CppClassWrapper`, +responsible for receiving the C++ virtual method calls and finding out the proper Python +override to which handle such a call. + +Now that you know this, consider the case when C++ has a factory method that gives you +new C++ objects originated somewhere in C++-land, in opposition to the ones generated in +Python-land by the usage of class constructors, like in the example above. + +Brief interruption to show what I was saying: + + .. code-block:: python + + import types + import Binding + + obj = Binding.createCppClass() + def myVirtualMethod(self_obj, arg): + pass + + # Punching a dead duck... + obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass) + + +The `Binding.createCppClass()` factory method is just an example, C++ created objects +can pop out for a number of other reasons. Objects created this way have a Python wrapper +holding them as usual, but the object held is not a `CppClassWrapper`, but a regular +`CppClass`. All virtual method calls originated in C++ will stay in C++ and never reach +a Python virtual method overridden via duck punching. + +Although duck punching is an interesting Python feature, it don't mix well with wrapped +C++ virtual methods, specially when you can't tell the origin of every single wrapped +C++ object. In summary: don't do it! + |