<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Apr 2, 2013, at 3:52 AM, Hynek Schlawack &lt;<a href="mailto:hs@ox.cx">hs@ox.cx</a>&gt; wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">My question can be simplified to: Closures yes or no?<br></div></blockquote><div><br></div><div>"As appropriate".</div><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">They seem *really* handy since they allow to have some data present without handing it through all the time. Eg in my cred checker, I can refer to the user name from the closure instead of passing it around all the time – making the code much cleaner. Also most current examples and callbacks-are-hard-FUD-rebuttals seem to use them.<br><br>OTOH, private methods like `_cbPrintResult` are nicer to test individually.<br></div></blockquote><div><br></div><div>Ideally, any private method exists in service of some goal of the public interface. &nbsp;It's best to test them by exercising the case in the public API which they support, rather than calling them directly. &nbsp;Before you write any such method, you ought to be able to write a failing test for the public interface which doesn't pass because you haven't written the private method yet :).</div><div><br></div><div>If you're writing private methods which need their own extensive internal test coverage, it might be good to consider whether what you're writing really needs to be public functionality.</div><div><br></div><div>However, even if you're going to have a private implementation detail complex enough to warrant its own test suite independent of the public feature it's supporting – and it <i>is</i>&nbsp;better to have such a suite than to have an explosion of irrelevant complexity in the tests for the public API - it's best to go with a private class or module than private methods on a public class. &nbsp;Callback methods like _cbSomethingSomethingResult generally indicate an ad-hoc state machine as part of your class. &nbsp;Chances are, if you're going down this road, you're missing quite a few states, and the ad-hoc state is smeared out across many poorly-encapsulated attributes. &nbsp;After all, since it's not a closure, your only place to store any resulting state is 'self'.</div><div><br></div><div>The best solution at this point is not to try to test _cbWhatever methods directly, but rather, to spin out all the _cbSetDisconnected and _ebFixUpStuff methods into a dedicated class which has its own "public" interface that can be tested, but which is still private for Twisted's compatibility purposes. &nbsp;That dedicated class can then have an explicit state machine of its own and will have attributes dedicated to just encapsulating the state that it's tasked with maintaining, instead of a random potpourri of different states from different responsibilities.</div><div><br></div><div>So I guess my recommendation would be "closures", because any time using private methods as callbacks would be better, it seems like something else has gone wrong :).</div><div><br></div><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">If “yes, closures”: Still using cb/eb prefixes? I don’t see them very often in recent examples. What about addBoth handlers?<br></div></blockquote><div><br></div><div>If you're using a closure, use a descriptive name. &nbsp;The 'cb/eb' prefix notation is not particularly illustrative; I often use an english word like 'when'. &nbsp;whenDisconnected, whenResponseReceived, etc.</div><div><br></div><div>The only hard and fast rule is, if you have a closure, don't start its name with an underscore, there's no point to that :).</div><div><br></div><div>-g</div><div><br></div></div></body></html>