Changeset 86
- Timestamp:
- 01/15/07 00:19:22 (2 years ago)
- Files:
-
- trunk/html_doc/basics.html (modified) (1 diff)
- trunk/html_doc/celerid.html (modified) (1 diff)
- trunk/html_doc/class_wrapping.html (modified) (2 diffs)
- trunk/html_doc/conversion.html (modified) (1 diff)
- trunk/html_doc/credits.html (modified) (1 diff)
- trunk/html_doc/except_wrapping.html (modified) (1 diff)
- trunk/html_doc/func_wrapping.html (modified) (1 diff)
- trunk/html_doc/index.html (modified) (1 diff)
- trunk/html_doc/inherit.html (added)
- trunk/html_doc/install.html (modified) (1 diff)
- trunk/html_doc/pydobject.html (modified) (1 diff)
- trunk/html_doc/struct_wrapping.html (modified) (1 diff)
- trunk/html_doc/vsboost.html (modified) (1 diff)
- trunk/raw_html/class_wrapping.html (modified) (1 diff)
- trunk/raw_html/header_template.html (modified) (1 diff)
- trunk/raw_html/inherit.html (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/html_doc/basics.html
r64 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/celerid.html
r64 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/class_wrapping.html
r64 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="navcur" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> … … 106 107 </dl> 107 108 108 <h3><a class="anchor" name="inheritance">Inheritance</a></h3>109 110 <p>If you wrap both a class and a child of that class, Pyd is smart enough to make the resulting Python classes have a parent-child relationship. Any methods of the parent class will automatically be available to the child class. If the child class overloads any of those methods, it is important that the user wrap them in the module's init function. For example:</p>111 112 <pre class="code"><span class="keyword">import</span> std.stdio;113 114 <span class="keyword">class</span> Base {115 <span class="keyword">void</span> foo() { writefln(<span class="string">"Base.foo"</span>); }116 <span class="keyword">void</span> bar() { writefln(<span class="string">"Base.bar"</span>); }117 }118 119 <span class="keyword">class</span> Derived : Base {120 <span class="keyword">void</span> foo() { writefln(<span class="string">"Derived.foo"</span>); }121 }</pre>122 123 <p>These would be exposed to Python by putting this code in <code>PydMain</code> after the call to <code>module_init</code>:</p>124 125 <pre class="code">wrapped_class!(Base) b;126 b.def!(Base.foo);127 b.def!(Base.bar);128 finalize_class(b);129 130 wrapped_class!(Derived) d;131 d.def!(Derived.foo);132 finalize_class(d);</pre>133 134 <p>When used in Python, we get the expected behavior:</p>135 136 <pre class="code">>>> issubclass(Derived, Base)137 True138 >>> b = Base()139 >>> d = Derived()140 >>> b.foo()141 Base.foo142 >>> b.bar()143 Base.bar144 >>> d.foo()145 Derived.foo146 >>> d.bar()147 Base.bar</pre>148 149 <p>There is one weakness in the default behavior. Take a function like the following:</p>150 151 <pre class="code"><span class="keyword">void</span> polymorphic_call(Base b) {152 b.foo();153 }</pre>154 155 <p>And in Python:</p>156 157 <pre class="code"><span class="keyword">class</span> PyClass(Base):158 <span class="keyword">def</span> foo(self):159 <span class="keyword">print</span> <span class="string">"PyClass.foo"</span>160 161 >>> p = PyClass()162 >>> polymorphic_call(p)163 Base.foo</pre>164 165 <p>Optimally, we would want <code>polymorphic_call</code> to call PyClass.foo. This requires some additional work on the D side of things. To get this behavior, then rather than expose Base directly, we must expose a wrapper class:</p>166 167 <pre class="code"><span class="keyword">class</span> BaseWrap : Base {168 <span class="keyword">mixin</span> OverloadShim;169 <span class="keyword">void</span> foo() {170 get_overload(&<span class="keyword">super</span>.foo, <span class="string">"foo"</span>);171 }172 <span class="keyword">void</span> bar() {173 get_overload(&<span class="keyword">super</span>.bar, <span class="string">"bar"</span>);174 }175 }</pre>176 177 <p>The <code>OverloadShim</code> template has but a single member, the <code>get_overload</code> function.</p>178 179 <dl>180 <dt><code>ReturnType!(dg_t) get_overload(<span class="t_arg">dg_t</span>, <span class="t_arg">T ...</span>) (dg_t <span class="arg">dg</span>, char[] <span class="arg">name</span>, T <span class="arg">t</span>);</code></dt>181 <dd><ul>182 <li><span class="arg">dg</span> should be a delegate to the parent class's method.</li>183 <li><span class="arg">name</span> should be the name of the method as Python understands it to be. <i>(There's no efficient way to derive this automatically based on only the delegate.)</i></li>184 <li><span class="arg">t</span> is a tuple argument. These arguments will be passed on to the actual function call, be it the parent class's implementation or a Python subclass's implementation.</li>185 </ul></dd>186 </dl>187 188 <p><code>get_overload</code> returns whatever the method does.</p>189 190 <p>Now, we must replace the old wrapping of Base with this:</p>191 192 <pre class="code">wrapped_class!(BaseWrap, <span class="string">"Base"</span>) w;193 w.def!(BaseWrap.foo);194 w.def!(BaseWrap.bar);195 finalize_class(w);</pre>196 197 <p>Now our subclass will perform just like we expect:</p>198 199 <pre class="code">>>> p = PyClass()200 >>> polymorphic_call(p)201 PyClass.foo</pre>202 203 109 <h3><a class="anchor" name="examples">Examples</a></h3> 204 110 trunk/html_doc/conversion.html
r57 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/credits.html
r57 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/except_wrapping.html
r57 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="navcur" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/func_wrapping.html
r64 r86 17 17 <a class="navcur" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/index.html
r64 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/install.html
r62 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/pydobject.html
r57 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/struct_wrapping.html
r59 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="navcur" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/html_doc/vsboost.html
r57 r86 17 17 <a class="nav" href="func_wrapping.html">Function wrapping</a><br /> 18 18 <a class="nav" href="class_wrapping.html">Class wrapping</a><br /> 19 <a class="nav" href="inherit.html">Inheritance</a><br /> 19 20 <a class="nav" href="struct_wrapping.html">Struct wrapping</a><br /> 20 21 <a class="nav" href="except_wrapping.html">Exception wrapping</a><br /> trunk/raw_html/class_wrapping.html
r64 r86 91 91 </dl> 92 92 93 <h3><a class="anchor" name="inheritance">Inheritance</a></h3>94 95 <p>If you wrap both a class and a child of that class, Pyd is smart enough to make the resulting Python classes have a parent-child relationship. Any methods of the parent class will automatically be available to the child class. If the child class overloads any of those methods, it is important that the user wrap them in the module's init function. For example:</p>96 97 <pre class="code"><span class="keyword">import</span> std.stdio;98 99 <span class="keyword">class</span> Base {100 <span class="keyword">void</span> foo() { writefln(<span class="string">"Base.foo"</span>); }101 <span class="keyword">void</span> bar() { writefln(<span class="string">"Base.bar"</span>); }102 }103 104 <span class="keyword">class</span> Derived : Base {105 <span class="keyword">void</span> foo() { writefln(<span class="string">"Derived.foo"</span>); }106 }</pre>107 108 <p>These would be exposed to Python by putting this code in <code>PydMain</code> after the call to <code>module_init</code>:</p>109 110 <pre class="code">wrapped_class!(Base) b;111 b.def!(Base.foo);112 b.def!(Base.bar);113 finalize_class(b);114 115 wrapped_class!(Derived) d;116 d.def!(Derived.foo);117 finalize_class(d);</pre>118 119 <p>When used in Python, we get the expected behavior:</p>120 121 <pre class="code">>>> issubclass(Derived, Base)122 True123 >>> b = Base()124 >>> d = Derived()125 >>> b.foo()126 Base.foo127 >>> b.bar()128 Base.bar129 >>> d.foo()130 Derived.foo131 >>> d.bar()132 Base.bar</pre>133 134 <p>There is one weakness in the default behavior. Take a function like the following:</p>135 136 <pre class="code"><span class="keyword">void</span> polymorphic_call(Base b) {137 b.foo();138 }</pre>139 140 <p>And in Python:</p>141 142 <pre class="code"><span class="keyword">class</span> PyClass(Base):143 <span class="keyword">def</span> foo(self):144 <span class="keyword">print</span> <span class="string">"PyClass.foo"</span>145 146 >>> p = PyClass()147 >>> polymorphic_call(p)148 Base.foo</pre>149 150 <p>Optimally, we would want <code>polymorphic_call</code> to call PyClass.foo. This requires some additional work on the D side of things. To get this behavior, then rather than expose Base directly, we must expose a wrapper class:</p>151 152 <pre class="code"><span class="keyword">class</span> BaseWrap : Base {153 <span class="keyword">mixin</span> OverloadShim;154 <span class="keyword">void</span> foo() {155 get_overload(&<span class="keyword">super</span>.foo, <span class="string">"foo"</span>);156 }157 <span class="keyword">void</span> bar() {158 get_overload(&<span class="keyword">super</span>.bar, <span class="string">"bar"</span>);159 }160 }</pre>161 162 <p>The <code>OverloadShim</code> template has but a single member, the <code>get_overload</code> function.</p>163 164 <dl>165 <dt><code>ReturnType!(dg_t) get_overload(<span class="t_arg">dg_t</span>, <span class="t_arg">T ...</span>) (dg_t <span class="arg">dg</span>, char[] <span class="arg">name</span>, T <span class="arg">t</span>);</code></dt>166 <dd><ul>167 <li><span class="arg">dg</span> should be a delegate to the parent class's method.</li>168 <li><span class="arg">name</span> should be the name of the method as Python understands it to be. <i>(There's no efficient way to derive this automatically based on only the delegate.)</i></li>169 <li><span class="arg">t</span> is a tuple argument. These arguments will be passed on to the actual function call, be it the parent class's implementation or a Python subclass's implementation.</li>170 </ul></dd>171 </dl>172 173 <p><code>get_overload</code> returns whatever the method does.</p>174 175 <p>Now, we must replace the old wrapping of Base with this:</p>176 177 <pre class="code">wrapped_class!(BaseWrap, <span class="string">"Base"</span>) w;178 w.def!(BaseWrap.foo);179 w.def!(BaseWrap.bar);180 finalize_class(w);</pre>181 182 <p>Now our subclass will perform just like we expect:</p>183 184 <pre class="code">>>> p = PyClass()185 >>> polymorphic_call(p)186 PyClass.foo</pre>187 188 93 <h3><a class="anchor" name="examples">Examples</a></h3> 189 94 trunk/raw_html/header_template.html
r62 r86 8 8 <a class="%(func_wrapping)s" href="func_wrapping.html">Function wrapping</a><br /> 9 9 <a class="%(class_wrapping)s" href="class_wrapping.html">Class wrapping</a><br /> 10 <a class="%(inherit)s" href="inherit.html">Inheritance</a><br /> 10 11 <a class="%(struct_wrapping)s" href="struct_wrapping.html">Struct wrapping</a><br /> 11 12 <a class="%(except_wrapping)s" href="except_wrapping.html">Exception wrapping</a><br />
