tag:blogger.com,1999:blog-2768398862956057132024-03-19T01:47:26.330-07:00More Thinking, Less CodingDavid P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-276839886295605713.post-77099942715238862392016-04-28T18:42:00.000-07:002016-04-28T18:42:05.263-07:00Who called stopPropagation?When dealing with mature JavaScript systems these days, there are a lot of moving parts -- frameworks, levels of indirection, shadow DOMs, minified code, and so forth. Today I was debugging an issue in which a third-party component was not able to "hear" an event at the top level of the document, even though the event was being fired. I figured someone was intercepting the event and canceling it, or calling <span style="font-family: "courier new" , "courier" , monospace;">stopPropagation()</span>, or something. I was struggling to figure out who. There was a lot of code to hunt through.
<br />
<br />
If only I could set a breakpoint on <span style="font-family: "courier new" , "courier" , monospace;">stopPropagation()</span><span style="font-family: inherit;"> ... and I could!
</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">If you want to play along, you'll need the following three files:</span>
<br />
<span style="font-family: inherit;"><br /></span>
<script src="https://gist.github.com/davidpcaldwell/3753f89e2d013f2e5f3ba4bd98dba950.js"></script>
<br />
If you load the HTML page in a browser, you'll see a simple UI. Clicking the button will change the message to "bubbled!" The click event flows up through the DOM until bubbles up to <span style="font-family: Courier New, Courier, monospace;">expectingClick</span>; it is handled by the event handler added to <span style="font-family: Courier New, Courier, monospace;">expectingClick</span> by <span style="font-family: Courier New, Courier, monospace;">script.js</span><span style="font-family: inherit;"> and changes the message.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">But if the page is loaded with </span><span style="font-family: Courier New, Courier, monospace;">?mischief</span><span style="font-family: inherit;"> as the query string (you can click on the "Make mischief" link to do this), an intervening event handler stops the propagation of the event. So the message is changed to "clicked!" by the inner-most listener, but then never changes to "bubbled!" That's the situation I had to try to figure out.</span><br />
<br />
I was using Google Chrome's Developer Tools to debug the issue. So I could set an event listener breakpoint on the event.<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNbKWNtUHtgDpEIJyt1QhuV7XMjG75cG2yvTAF6v5w9Jv0e9Pv01Wf683mcWmFaCNY3tlLYWh1z1V8yBC5i2QeLYGZsacIiujiKc8cj3PB7yTIptZogPukUF47e-ytLX1yJzuxYBi2zmT4/s1600/stopPropagation-1.png" imageanchor="1"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNbKWNtUHtgDpEIJyt1QhuV7XMjG75cG2yvTAF6v5w9Jv0e9Pv01Wf683mcWmFaCNY3tlLYWh1z1V8yBC5i2QeLYGZsacIiujiKc8cj3PB7yTIptZogPukUF47e-ytLX1yJzuxYBi2zmT4/s320/stopPropagation-1.png" width="142" /></a></div>
<br />
Once I did that, I generated the event and the debugger paused on the entry point of the event listener (line 2 of <span style="font-family: Courier New, Courier, monospace;">script.js</span>, in our example). I then created the following function by typing into the Chrome console:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">window.breakBefore = (function(was) { return function() { debugger; return was.apply(this,arguments); } })</span></blockquote>
This function takes an existing function as an argument and creates an equivalent function that adds the <span style="font-family: Courier New, Courier, monospace;">debugger</span> keyword before invoking the original.<br />
<br />
At that point, I could replace the <span style="font-family: Courier New, Courier, monospace;">stopPropagation</span> method of the event with my version (while paused at the breakpoint):<br /><br />
<span style="font-family: Courier New, Courier, monospace;">e.stopPropagation = window.breakBefore(e.stopPropagation)</span><br />
<br />
Now, if I unset the <span style="font-family: Courier New, Courier, monospace;">click</span> breakpoint and continue using the continue button:<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2VzdvhHMGTk9sgmL8FUGLkdwfM0YHQ6gesV04tIBaIKfOscaWxKSqCkh-w-6rvx_lhLm6hl-D1moUL7fEYReIYnSUUu8bOqGLxjuM2Cr1C5TVKldxkt1FoO_Wx1aqYL2tjm8PUWkBu_sv/s1600/stopPropagation-2.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2VzdvhHMGTk9sgmL8FUGLkdwfM0YHQ6gesV04tIBaIKfOscaWxKSqCkh-w-6rvx_lhLm6hl-D1moUL7fEYReIYnSUUu8bOqGLxjuM2Cr1C5TVKldxkt1FoO_Wx1aqYL2tjm8PUWkBu_sv/s400/stopPropagation-2.png" /></a></div>
<br />
I will reach my <span style="font-family: Courier New, Courier, monospace;">breakBefore</span> function, showing the call to stopPropagation, <i>and</i> the stack trace showing the route to the invocation will be displayed!<br />
<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_7LzLGPZbQ4Z3DPehVgiK2Y3zBz_DaRUbtoxs9CWyjHBa4stpQf3hk6H4Kn1lIPn4UPI002kNhDrcOHiq2zdXOgavOAV_DduWCmxz3vI-Na0QFnnU7nXDO0dPcwYe1eGaaP0VhU2AteQR/s1600/stopPropagation-3.png" imageanchor="1"><img border="0" height="63" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_7LzLGPZbQ4Z3DPehVgiK2Y3zBz_DaRUbtoxs9CWyjHBa4stpQf3hk6H4Kn1lIPn4UPI002kNhDrcOHiq2zdXOgavOAV_DduWCmxz3vI-Na0QFnnU7nXDO0dPcwYe1eGaaP0VhU2AteQR/s320/stopPropagation-3.png" width="320" /></a> </div>
<br />
I was surprised it worked, and I'm sure it saved me hours. Hopefully it will do the same for you!David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com0tag:blogger.com,1999:blog-276839886295605713.post-48990023144095154312013-06-08T15:48:00.001-07:002013-06-08T15:48:10.098-07:00When VirtualBox keeps re-setting your Windows 7 host-only networking IP address to the autoconfiguration addressI've had this problem intermittently over the life of my VirtualBox installation, and others have reported it too.<div>
<br /></div>
<div>
Basically, on every host reboot Windows 7 would re-set the IP address of my host-only network interface to the autoconfiguration address, which caused virtual hosts to be unable to see it (and unable to get their own host-only IP address, which, at least on FreeBSD guests, basically caused a very long pause during the boot process, perhaps because I was also mounting host directories on the guest machines).</div>
<div>
<br /></div>
<div>
Solutions people have proposed for this are all over the map, so my solution may not work for everyone.<br /><div>
<br /></div>
<div>
For me, I came up with an easy fix that worked.</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">VBoxManage list hostonlyifs</span></div>
<div>
<span style="font-family: inherit;">to get the name of the host-only network interface.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">VBoxManage hostonlyif delete <i><name></i></span></div>
<div>
<span style="font-family: inherit;">to delete that interface</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Then:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">VBoxManage hostonlyif create</span></div>
</div>
<div>
<span style="font-family: inherit;">to create a new one</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Then:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">VBoxManage list hostonlyifs</span></div>
<div>
to get the name of the new network interface</div>
<div>
<br /></div>
<div>
Then:</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">VBoxManage hostonlyif ipconfig <i><name></i> --ip <i><ip></i></span></div>
<div>
to set the IP address to the address I wanted.</div>
<div>
<br /></div>
<div>
Now it works. I hope it's this easy for you!</div>
David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com1tag:blogger.com,1999:blog-276839886295605713.post-62086934207967652662013-01-10T18:43:00.000-08:002013-01-10T18:43:11.827-08:00A more rigorous redistricting analysisW.D. McInturff, who apparently is a Republican pollster, today published <a href="http://msnbcmedia.msn.com/i/MSNBC/Sections/A_Politics/_Today_Stories_Teases/NoCryinginRedistricting.pdf" target="_blank">an analysis</a> that is so misleading, so simplistic, I can't believe people would take it seriously. Yet Chuck Todd, a smart person, <a href="https://twitter.com/chucktodd/status/289354099244285952" target="_blank">tweeted about it approvingly</a>. NBC News <a href="http://firstread.nbcnews.com/_news/2013/01/09/16432181-gop-pollster-theres-no-crying-in-redistricting" target="_blank">published an article</a> about it. If <a href="http://www.fivethirtyeight.com/" target="_blank">Nate Silver</a> got his hands on it, he'd eviscerate it. But he hasn't yet done that, so it falls to me.<br />
<br />
McInturff's basic mistake is simple: he compares the share of votes a party got in an election to the percentage of seats it won to determine whether a party had an advantage in that election. But that's stupid. Ronald Reagan, while winning 59% of the vote in 1984, didn't win 59% of the states. He won 49/50, or 98%. Is that because the <i>state lines</i> were drawn unfairly in 1984? That Reagan gained a 39% advantage because of state lines? No. It's because when you aggregate votes, of course the leader will win a higher percentage of districts than votes. Comparing the percentage of votes to the percentage of seats is like comparing a sports team's winning percentage to the percentage of points it scores in its games. They're not comparable.<br />
<br />
It's more insulting that he then takes such a snide tone -- titling his essay "There's No Crying in Redistricting" -- for such misleading analysis. Whether it's intentionally misleading or just slothful, I have no idea. McInturff's analysis basically argues that, sure, Republicans might have had an advantage in the recent House election due to redistricting, but it's nothing special. He mocks anyone who might be concerned that voters' will is being frustrated by poorly drawn district lines, portraying them as a bunch of whiners. He leaves out seven of the 21 elections during the period he analyzes (1972-2012).<br />
<br />
But the truth is, a reasoned analysis shows that the 2012 advantage enjoyed by the Republicans is very unusual, and clearly the most significant frustration of voters' will in the last 40 years (the period McInturff analyzes). He's dead wrong. Let's go to the numbers.<br />
<br />
First, let's look at the period preceding 2010. McInturff starts his analysis in 1972. Unlike him, I look at all elections since 1972 (he inexplicably leaves out seven of them). Here's the data:<br />
<br />
<table>
<thead>
<tr>
<td>Election</td>
<td>GOP 2-Party Vote Share</td>
<td>GOP 2-Party Seat Share</td>
</tr>
</thead>
<tbody>
<tr><td>1972</td><td>47.3</td><td>44.2</td></tr>
<tr><td>1974</td><td>41.5</td><td>33.1</td></tr>
<tr><td>1976</td><td>43.1</td><td>32.9</td></tr>
<tr><td>1978</td><td>45.6</td><td>36.3</td></tr>
<tr><td>1980</td><td>48.6</td><td>44.2</td></tr>
<tr><td>1982</td><td>44.5</td><td>38.2</td></tr>
<tr><td>1984</td><td>47.4</td><td>41.8</td></tr>
<tr><td>1986</td><td>44.9</td><td>40.7</td></tr>
<tr><td>1988</td><td>46</td><td>40.2</td></tr>
<tr><td>1990</td><td>45.8</td><td>38.5</td></tr>
<tr><td>1992</td><td>47.3</td><td>40.6</td></tr>
<tr><td>1994</td><td>53.5</td><td>53</td></tr>
<tr><td>1996</td><td>49.8</td><td>52.2</td></tr>
<tr><td>1998</td><td>50.5</td><td>51.4</td></tr>
<tr><td>2000</td><td>50.2</td><td>51</td></tr>
<tr><td>2002</td><td>52.1</td><td>52.9</td></tr>
<tr><td>2004</td><td>51.4</td><td>53.5</td></tr>
<tr><td>2006</td><td>45.9</td><td>46.4</td></tr>
<tr><td>2008</td><td>44.5</td><td>41</td></tr>
<tr><td>2010</td><td>53.4</td><td>55.6</td></tr>
</tbody>
</table>
<br />
You can see the problem I pointed out above. Whichever party wins an election, in terms of votes, wins a bigger share of seats than votes. There are twenty elections above, and this is true in seventeen of them. Obviously these numbers are not directly comparable.<br />
<br />
In fact, a basic statistical analysis notes that the best predictor, using data from 1972-2010, of the percentage of seats Republicans won is the following formula:<br />
<br />
(Percent of Republican vote) X 1.9682 - 0.4943 = Percentage of Republican seats<br />
<br />
Let's have a look at what this relationship looks like:<br />
<br />
<table>
<thead>
<tr><td>GOP Vote %</td><td>GOP Seat %</td></tr>
</thead>
<tbody>
<tr><td>60</td><td>68.7</td></tr>
<tr><td>55</td><td>58.8</td></tr>
<tr><td>53</td><td>54.9</td></tr>
<tr><td>52</td><td>52.9</td></tr>
<tr><td>51</td><td>50.9</td></tr>
<tr><td>50</td><td>49</td></tr>
<tr><td>49</td><td>47</td></tr>
<tr><td>48</td><td>45</td></tr>
<tr><td>47</td><td>43.1</td></tr>
<tr><td>45</td><td>39.1</td></tr>
<tr><td>40</td><td>29.3</td></tr>
</tbody>
</table>
<br />
You can see that if Republicans win more than half the vote, their seat share generally exceeds their vote share, and vice-versa.
<br />
<br />
You can also see something else: that in a 50-50 election, Republicans are only projected to win 49% of the seats! This does suggest that Republicans suffered from a slight disadvantage during the 40 years in question, on the average. This part McInturff has right, although he calls it a "huge structural advantage," and as we'll see, it's smaller than what Republicans have now. I have no doubt that the party in control of redistricting loads the dice in their favor. But there's reason to believe it's never been done as effectively or thoroughly as it was after the 2010 census. Let's see why.<br />
<br />
If we're looking for what would happen with "fair" district lines, and other considerations, we should adjust the formula a little bit to make it fair to Republicans. Let's change the intercept -- the 0.4943 above -- to what it would need to be to make a 50-50 election even in terms of seats, or 0.4841. This yields the following table:<br />
<br />
<table>
<thead>
<tr><td>Party Vote %</td><td>"Fair" Party Seat %</td></tr>
</thead>
<tbody>
<tr><td>60</td><td>69.7</td></tr>
<tr><td>55</td><td>59.8</td></tr>
<tr><td>53</td><td>55.9</td></tr>
<tr><td>52</td><td>53.9</td></tr>
<tr><td>51</td><td>52</td></tr>
<tr><td>50</td><td>50</td></tr>
<tr><td>49</td><td>48</td></tr>
<tr><td>48</td><td>46.1</td></tr>
<tr><td>47</td><td>44.1</td></tr>
<tr><td>45</td><td>40.2</td></tr>
<tr><td>40</td><td>30.3</td></tr>
</tbody>
</table>
<br />
So now we see how this might work, if everything were fair. A party winning 60% of the vote should control 70% of the seats; 55% of the votes is about 60% of the seats, and so forth.<br />
<br />
So <i>now</i> let's look at the recent elections in context. Did any party have an "advantage" -- in which they won more seats than expected -- in any election? And what does it show about 2012?<br />
<br />
We'll look at the two-party vote share over the period in question, and look at both the expected percentage of seats won and the actual percentage of seats won, and express the difference as a number of seats (just to make it easier to understand).<br />
<br />
<table>
<thead>
<tr>
<td>Year</td>
<td>GOP Vote %</td>
<td>Expected GOP Seat %</td>
<td>Actual GOP Seat %</td>
<td>Difference (seats)</td>
</tr>
</thead>
<tbody>
<tr><td>1972</td><td>47.3</td><td>44.8</td><td>44.2</td><td>-2.3</td></tr>
<tr><td>1974</td><td>41.5</td><td>33.2</td><td>33.1</td><td>-0.5</td></tr>
<tr><td>1976</td><td>43.1</td><td>36.5</td><td>32.9</td><td>-15.9</td></tr>
<tr><td>1978</td><td>45.6</td><td>41.3</td><td>36.3</td><td>-21.7</td></tr>
<tr><td>1980</td><td>48.6</td><td>47.3</td><td>44.2</td><td>-13.2</td></tr>
<tr><td>1982</td><td>44.5</td><td>39.3</td><td>38.2</td><td>-4.8</td></tr>
<tr><td>1984</td><td>47.4</td><td>44.8</td><td>41.8</td><td>-13.1</td></tr>
<tr><td>1986</td><td>44.9</td><td>40</td><td>40.7</td><td>2.9</td></tr>
<tr><td>1988</td><td>46</td><td>42.1</td><td>40.2</td><td>-8.2</td></tr>
<tr><td>1990</td><td>45.8</td><td>41.8</td><td>38.5</td><td>-14.4</td></tr>
<tr><td>1992</td><td>47.3</td><td>44.6</td><td>40.6</td><td>-17.6</td></tr>
<tr><td>1994</td><td>53.5</td><td>56.9</td><td>53</td><td>-17.1</td></tr>
<tr><td>1996</td><td>49.8</td><td>49.7</td><td>52.2</td><td>10.9</td></tr>
<tr><td>1998</td><td>50.5</td><td>50.9</td><td>51.4</td><td>2</td></tr>
<tr><td>2000</td><td>50.2</td><td>50.4</td><td>51</td><td>3</td></tr>
<tr><td>2002</td><td>52.1</td><td>54.2</td><td>52.9</td><td>-5.5</td></tr>
<tr><td>2004</td><td>51.4</td><td>52.7</td><td>53.5</td><td>3.3</td></tr>
<tr><td>2006</td><td>45.9</td><td>41.9</td><td>46.4</td><td>19.8</td></tr>
<tr><td>2008</td><td>44.5</td><td>39.1</td><td>41</td><td>8.3</td></tr>
<tr><td>2010</td><td>53.4</td><td>56.8</td><td>55.6</td><td>-4.9</td></tr>
<tr><td>2012</td><td>49.4</td><td>48.9</td><td>53.8</td><td>21.4</td></tr>
</tbody></table>
<br />
So now we can see how dramatic the advantage to the Republicans was in the last election. This was only the second election in the period -- 1996 was the other -- in which the party which won fewer votes controlled the House. (McInturff erroneously <a href="http://firstread.nbcnews.com/_news/2013/01/09/16432181-gop-pollster-theres-no-crying-in-redistricting" target="_blank">concedes to NBC</a> that this has never happened before, because 1996 was apparently one of the elections he was too lazy to include in his study, or because it undercut his thesis that Republicans do not have an advantage.)<br />
<br />
Was it the largest deviation recorded, using this model? Not in number of seats. The Democrats had a slightly larger advantage in 1978. But in that election, Democrats were winning a major victory over Republicans, and the deviation caused them to win by a larger margin. The model predicted they'd have something like a 255-180 majority, and instead, they had a 277-158 majority. Even using the absolute measure, it's the second-largest in the past 21 elections, so it's obviously not normal, as McInturff would have you believe. (And 1978 is one of the elections he chose not to include, for whatever reason.) But 2012 is clearly the larger deviation from voters' will.<br />
<br />
And there are good reasons to believe the 2012 election advantage is even <i>more</i> extreme and durable, by historical standards, than this simple model shows.<br />
<br />
First, by most accounts, the polarization of districts has been increasing. If that's true, the slope coefficient should be decreasing, and the number of votes necessary to swing a seat should be increasing. The Republican structural advantage of 21 seats will be harder to overcome than in the past -- it will take more votes. There is a bit of support in the data for this -- from 2002-2010, the winning party underperformed the model in four of the five elections. Only in 2004 did the winner overperform -- and it should be noted that this followed the unusual mid-cycle redistricting in Texas, leading to GOP seat gains in the 2004 election. Other than that the GOP overperformed in 2006 and 2008, when they lost, and underperformed in 2002 and 2010, when they won.<br />
<br />
Second, the model above may omit a factor -- something having to do with incumbency, or new incumbency. After the two biggest wave elections -- the Watergate election in 1974, and the Gingrich takeover in 1994 -- the <i>next </i>election sees the beneficiaries appear to improve their performance relative to their vote share, and that advantage appears to persist for several elections. Because I don't yet have a conceptual mechanism to explain this, I'm not building it into the model -- but there may well be something I'm missing.<br />
<br />
Third, redistricting just occurred, and was thoroughly controlled by Republicans. We might expect that Republicans would show an advantage with the new district lines. Let's look at the <i>average</i> difference by redistricting cycle:<br />
<br />
<table>
<thead>
<tr><td>Decade</td><td>Average GOP advantage</td></tr>
</thead>
<tbody>
<tr><td>1972-1980</td><td>-10.7</td></tr>
<tr><td>1982-1990</td><td>-7.5</td></tr>
<tr><td>1992-2000</td><td>-3.8</td></tr>
<tr><td>2002-2010</td><td>4.2</td></tr>
<tr><td>2012-2020</td><td>21.4</td></tr>
</tbody>
</table>
<br />
No pattern? Nothing going on here, eh, Mr. McInturff? The data are moving in one direction. And there is every reason to believe that we've achieved historic levels of partisan advantage. There's no obvious reason to disbelieve what the model finds for 2012 and beyond. A <a href="http://fivethirtyeight.blogs.nytimes.com/2012/12/27/as-swing-districts-dwindle-can-a-divided-house-stand/" target="_blank">completely different methodological approach</a> undertaken by Nate Silver shows a marked decline in the number of swing districts, just since 1992 -- from 103 in that year to 35 in 2012 -- and further shows that the tipping point district -- the district that would determine control of the House if partisan voting followed presidential patterns -- is now a district that is 5-10 points more Republican than the nation as a whole.<br />
<br />
So, nice try. Perhaps a cursory glance at the data let you believe that nothing special was happening. Or perhaps you were just trying to justify an unjustifiable perversion of voters' will in your partisan direction. But a deeper look shows you're wrong -- we've reached a highly unusual level of partisan advantage in House elections. And it's bad for the country, making it harder for voters to exercise their will on matters of public policy.David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com1tag:blogger.com,1999:blog-276839886295605713.post-42440124529961275942012-04-09T05:35:00.000-07:002012-05-16T03:09:30.504-07:00Deploy it as a service!I used to make fun of people who were so in love with service-oriented architecture (SOA) that they would grandly want to deploy every general-use piece of code in the entire organization as a web service (rather than, for example, creating a Java class or something).<br />
<br />
But I just had to create a web service to CALCULATE THE LOCAL TIME because Google Chrome -- which seems to be a pretty mature product -- has some sort of catastrophic time zone bug that somehow causes its time zone handling to get confused.<br />
<br />
The debugger console shows the following ridiculous output (obviously today at 5:44 EDT):<br />
<br />
<code>> new Date()<br />
Mon Apr 09 2012 10:44:42 GMT+0100 (Eastern Standard Time)</code><br />
<br />
A quick <a href="http://code.google.com/p/chromium/issues/list?can=2&q=timezone+OR+%22time+zone%22&colspec=ID+Pri+Mstone+ReleaseBlock+Area+Feature+Status+Owner+Summary&cells=tiles">search</a> of the Chromium bug database reveals lots of users reporting bugs that are probably caused by this.<br />
<br />
I seriously hope they don't introduce a bug into JavaScript mathematics and make me write the AddNumbers service from my fictional SOA-infested dystopia ...<br />
<br />
P.S. Even as I write this, all the timestamps on the Blogger edit screen show incorrectly...
<br /><br /><strong>Update 2012 May 16:</strong>It's a bug in how Chrome deals with the TZ environment variable on Windows. See the Chromium <a href="http://code.google.com/p/chromium/issues/detail?id=125614">issue</a>.David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com20tag:blogger.com,1999:blog-276839886295605713.post-43134729637722490692010-10-23T15:20:00.000-07:002010-10-24T13:23:25.707-07:00Easier way to run Mercurial hgk (or hg view) on Windows (and Cygwin)<code>hgk</code>, the Mercurial extension that allows the <code>hg view</code> command, is the graphical viewer for Mercurial repositories.<br />
<br />
It's a bit messy to run it on Windows. The solution I came up with was easier than the others I found on the web, so ...<br />
<br />
I downloaded the <a href="http://mercurial.selenic.com/downloads">Mercurial</a> 1.6.4 main binary for Windows (making sure to install the "contributed scripts" so that I got <code>hgk</code>), and ActiveState's <a href="http://www.activestate.com/activetcl">ActiveTcl</a> 8.4. I installed them. I then modified my Mercurial configuration as follows. You need to create one batch file in a directory of your choosing, in addition to installing these packages and modifying your configuration. <br />
<br />
Added to <code>Mercurial.ini</code> (user or systemwide; probably would work with <code>$HOME/.hgrc</code> as well):<br />
<hr /><pre>[extensions]
hgext.hgk =
[hgk]
path=C:\wherever\you\want\hgk.bat</pre><hr />Created <code>hgk.bat</code> (at path indicated above):<br />
(Note that this is a two-line script: <code>wish.exe</code> takes the <code>hgk</code> path as an argument. Not sure how to get Blogger to format this better.)<br />
<hr /><pre>@echo off
set HG=C:\path\to\mercurial\hg.exe
start C:\path\to\tcl\bin\wish.exe C:\path\to\mercurial\contrib\hgk %*
</pre><hr />And that's it! I don't know why <a href="http://mercurial.selenic.com/wiki/HgkExtension">the official instructions</a> are so hard. And in any case, they did not work for me. YMMV.David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com0tag:blogger.com,1999:blog-276839886295605713.post-91540179695844733322010-10-21T18:01:00.000-07:002010-10-21T18:03:40.551-07:00Ephemeral ports<p>Just learned about the so-called "ephemeral port range," which for years has been causing my servers on my local Windows machine to not start. Even after killing the process that has captured the server port, for whatever reason, I can't get a Java application to be able to listen on the newly closed port. This problem - not being able to use ports even when the <code>netstat</code> command reports them usable - seems to be a pretty common problem, and not Java-specific: see <a href="http://forums.oracle.com/forums/thread.jspa?threadID=707573">one</a> <a href="http://www.1060.org/forum/topic/79">of</a> <a href="http://stackoverflow.com/questions/3714957/address-already-in-use-jvm-bind">these</a> <a href="http://forums.sun.com/thread.jspa?threadID=5044757">five</a> <a href="http://community.jboss.org/thread/59995">articles</a> for more.</p><p>Anyway, the "traditional" (who knew? After running BSD all these years, I had no idea) "ephemeral port" range is 1024-4999. I knew ports below 1024 were essentially reserved for <code>root</code> on Unix systems, but I didn't know there were any other allocations. In the 1024-4999 range, applications (often client applications) claim ports for their own use.</p><p>Someone generously took the time to compose a very detailed <a href="http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html">overview of, and reference guide for, ephemeral ports on many operating systems</a>. It certainly was helpful for me.</p><p>It is possible to <a href="http://www.jroller.com/dschneller/entry/windows_tcp_port_conflicts_above">reconfigure the ephemeral port range on Windows</a> by hacking the registry. But simpler for me to just change my port numbers.</p>David P. Caldwellhttp://www.blogger.com/profile/11124583251867617440noreply@blogger.com0tag:blogger.com,1999:blog-276839886295605713.post-48103966697092561692009-07-19T23:14:00.000-07:002009-07-19T23:28:38.281-07:00I will never understand regular expressionsNot at this rate, anyway. Consider the following code snippet (tested in Firefox 3.5). You can probably see it's an attempt to search for empty HTML tags. It ... does not work.<br /><br /><code>var pattern = /\<([a-zA-Z0-9_\:]+)((?: [a-zA-Z0-9_\:]+=".*?")*?)\/>/;<br />var match = pattern.exec('<span class="noread nodeleted"><input class="edit" size="40" ui:id="set_title" value="awake"/></span>');<br />inonit.debug.debug("Match: " + match[2]);<br /></code><br /><br />The output is:<br /><code>class="noread nodeleted"><input class="edit" size="40" ui:id="set_title" value="awake"</code><br /><br />Why?!? Shouldn't the non-greedy quantifier prevent us from capturing everything between the first and last quotation marks?<br /><br />I messed with this for far too long, until I stumbled across a solution:<br /><br /><code>var pattern = /\<([a-zA-Z0-9_\:]+)((?: [a-zA-Z0-9_\:]+="<strong>[^"]</strong>*?")*?)\/>/;<br />var match = pattern.exec('<span class="noread nodeleted"><input class="edit" size="40" ui:id="set_title" value="awake"/></span>');<br />inonit.debug.debug("Match: " + match[2]);<br /></code><br /><br />The output for this?<br /><code>class="edit" size="40" ui:id="set_title" value="awake"</code><br /><br />Which is, of course, what I'm looking for. But why do I have to specify that I'm not matching the double quote character?<br /><br />Maybe I'm just dumb and I'm missing something about non-greedy quantifiers. But then why does <em>this</em> work?<br /><br /><code>var pattern = /"(.*?)"/;<br />var match = pattern.exec('"Hello" "World"');<br />inonit.debug.debug("Match: " + match[1]);</code><br /><br />Output:<br /><code>Hello</code>, of course.<br /><br />Makes no sense to me.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-276839886295605713.post-75884744340638891462009-07-15T20:17:00.000-07:002010-11-16T17:20:17.220-08:00Verbalizing<div>My name's David P. Caldwell. I'm a software developer, among other things. I've been actively involved in developing software for a really long time -- since I was a pre-teen, in fact. I use the middle initial in my name professionally because my name is not uncommon.</div><div><br />
</div><div>I don't enjoy self-credentialing, but I've learned in my professional career that it's a necessary evil. So: I'm probably best known in the software world as the author of the <a href="http://en.wikipedia.org/wiki/ECMAScript_for_XML">E4X</a> support in <a href="http://www.mozilla.org/rhino/">Mozilla Rhino</a>. I also gave <a href="http://developers.sun.com/learning/javaoneonline/sessions/2008/watch/TS-6606/index.html?">a talk at JavaOne</a> last year on various approaches for integrating dynamic languages with Java.</div><div><br />
</div>I've resisted actually publishing a technical blog. There have been a number of stages of resistance.<div><br />
</div><div>At first, it seemed to me that blogs were multi-topic personal soapboxes on which people could read all kinds of interesting, unrelated, eclectic things about the author's life. But history hasn't been kind to this view -- it turns out this concept is no longer called "blog." It's called "Facebook."</div><div><br />
</div><div>The problem is, one would have to be pretty fascinated by me to adopt all of my interests. And I have a lot of interests. Some of my interests are quite narrow, and have few people who share them -- even fewer of whom (none?) would share my <i>other </i>narrow interests.</div><div><br />
</div><div>Time has passed. It seems like people have figured out what blogs are. Effective, valuable ones cover some sort of topic other than the author's life.</div><div><br />
</div><div>There's another reason I resist writing. Writing is permanent. Sometimes I'm wrong. I don't like to be wrong -- at least not in an unchangeable way. I try not to commit to a view unless I'm really confident. When I'm not confident, I'm indecisive. If forced to adopt or express a view before I'm ready, I couch it with layer upon layer of hedging to make it clear that my advice shouldn't be relied upon.</div><div><br />
</div><div>This approach probably isn't the best approach for writing any kind of commentary.</div><div><br />
</div><div>But I've been doing a lot of thinking about software development lately. Judging by what I've found in my Internet research, some of it is related to topics that are actively under discussion. Besides, while researching and learning about various topics I've run across <a href="http://www.crockford.com/">opinionated</a> <a href="http://www.fivethirtyeight.com">people</a>. Not everything they say is appealing. Sometimes I think they're wrong. Sometimes they take a position and later decide they're wrong. But I know I benefit from reading their thoughts; I've benefited recently as I've tried to sort out my own.</div><div><br />
</div><div>One other part of my background encourages me to opine. I know I sometimes get big things right. A lot of times the problems I'm working on are being actively pursued by other people, and my solutions resemble theirs. In 1997, when I first started as a professional software developer ... well, without telling my life story, let's just say I wasn't ideally positioned to break into the field. But I was smart enough to see Java coming, and invested heavily in learning it. It's hard to remember just how newfangled Java was seen to be at the time. </div><div><br />
</div><div>That bet paid off. I ended up being on the leading edge of a wave that swept over the industry. Of course, I wasn't some sort of psychic. Java had captured a good deal of mindshare already. Part of the reason I did well here was that people don't really like change. Even if everyone sees innovation coming, many will try to deny it and resist the innovation. They'll say that the new change isn't really a change at all. Or that the old ways will win out after the fad passes. They'll seize on any perceived weakness of the innovation as evidence it won't work, or won't be a big deal. Inevitably someone will overhype the innovation, and they'll argue that the innovation won't justify the hype -- which is sort of beside the point, but makes them feel better about their resistance to change.</div><div><br />
</div><div>One of the things I've realized about myself is that even though I'm slow to change -- I think of myself as a <a href="http://www.nytimes.com/2008/03/12/technology/12inertia.html">late adopter</a> (at least as technologists go) -- I benefit professionally from the fact that most IT professionals fiercely resist change. Specifically, they resist the depreciation of their body of knowledge brought on by technical innovation. My self-critical personality helps me here: I, in contrast, am always wondering whether there isn't some better way to do what I'm trying to do -- or a better way to do what I just did. This characteristic has always made me enthusiastic about <a href="http://en.wikipedia.org/wiki/Code_refactoring">refactoring</a>. But it also helps me stay current as I age, in a field dominated by the young (who have the further advantage of being inexpensive).</div><div><br />
</div><div>Back to the main point. In my career, I've had a pretty decent ability to see into the future. Some of this might be wisdom or intelligence. Some of it may be dumb luck. But I think a good part of it is <i>willingness</i> -- keeping my eyes open for what's happening, even if it will mean I'll have to change. Even if it means I'll have to stop doing things I really enjoy doing (e.g., bit twiddling).</div><div><br />
</div><div>I guess I feel good enough about my sense of direction about the road ahead that I'm willing to rely on it as I think about my own life and career. So why not write about what I see? Even if I'm wrong sometimes (and have to deal with the shame), the worst that can happen is that someone reading will help me see things I don't see. I'd rather be publicly wrong today and learn enough to be right tomorrow than be wrong today <i>and</i> tomorrow.</div><div><br />
</div><div>That seems like a perfect note on which to close this self-introduction. Hello, World!</div>Unknownnoreply@blogger.com1