<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-999954569230139621</id><updated>2011-07-19T07:15:57.777-07:00</updated><category term='Punk-ass Admin'/><category term='Arrgh'/><category term='Professional Ethics'/><category term='heenh'/><category term='Ruby Newbie'/><title type='text'>doppio</title><subtitle type='html'>"Given enough coffee, all bugs are shallow."</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-8565508554676380936</id><published>2011-07-04T16:26:00.000-07:00</published><updated>2011-07-04T16:48:45.894-07:00</updated><title type='text'>Why I Write Software</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;br /&gt;One of my earliest memories:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;It's a hot sunny afternoon and I'm sitting on the ground in our driveway. My dad is sitting next to me, his hands covered with grease, showing me parts from a '58 Aston Martin he's working on. I'm asking him questions. "What's that?" "What does it do?" I want him to explain cars to me in terms I can understand at 5 years old. He does.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I began writing software because it was the most satisfying thing I could do. It was more fun than carpentry or machining or electronics because I could make bigger, more complicated things faster and try them out right away.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The summer of my junior year in college a San Francisco company tried to recruit me out of school. "You don't have to wear a tie," I was told, "but you have to wear shoes. We're in banking, after all." That was when I realized I could make a living at it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Years later I discovered another benefit.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A google search this morning for "+abajian +sputnik +repeat" returns over 800 hits, most of which are citations.  A program that I wrote in my first month at the UW MBT lab seven years ago is still in use by molecular biologists today in hundreds, perhaps thousands of labs around the world (judging by the email).  It's deeply satisfying to know that I've contributed to so many research projects.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;  I try to think about that when it seems like all I do is go to meetings, or the code is getting the best of me.&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I'm very fortunate to have made a career of something I love.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-8565508554676380936?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/8565508554676380936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=8565508554676380936' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/8565508554676380936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/8565508554676380936'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2011/07/lucky-me.html' title='Why I Write Software'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-7811781826620380719</id><published>2010-09-02T09:33:00.000-07:00</published><updated>2010-09-02T09:44:42.985-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><title type='text'>Open Source Democracy (NOT)</title><content type='html'>&amp;nbsp;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;OK, This probably isn't as bad as it sounds, but really.  Email from redhat this morning:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;&lt;br /&gt;Some or all of your votes have been removed from bug 433649.&lt;br /&gt;&lt;br /&gt;You had 50 votes on this bug, but 50 have been removed.&lt;br /&gt;&lt;br /&gt;You have no more votes remaining on this bug.&lt;br /&gt;&lt;br /&gt;Reason:&lt;br /&gt;The rules for voting on this product has changed; you had&lt;br /&gt;too many total votes, so all votes have been removed.&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-7811781826620380719?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/7811781826620380719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=7811781826620380719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/7811781826620380719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/7811781826620380719'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2010/09/open-source-democracy-not.html' title='Open Source Democracy &lt;i&gt;(NOT)&lt;/i&gt;'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-4933384154188410123</id><published>2009-05-20T09:21:00.000-07:00</published><updated>2009-05-20T09:38:50.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Punk-ass Admin'/><title type='text'>Magic NAT Incantation</title><content type='html'>&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;How many times am I going to get bit with this?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Rebuilt the system this weekend.  In addition to the expected hassles of version upgrades, aging hardware and the peculiarities of my configuration there's always one or two things I forget that cause some unnecessary stress.  But this one gets me every single time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;No matter what I did, I couldn't get NAT to work.  The machines on the subnet were pingable, had happy network connections.  But no outside internet.  I could resolve domains using my local internal cacheing nameserver but could not reach those hosts.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;I spent hours staring at the iptables file, starting and stopping the network, checking cables, rebooting machines on the subnet.  No packets, no joy.  Finally I'm sitting at a party on Saturday night, drinking some deadly home-made liqueur (started as vodka, involved lemons) when suddenly I have a flashback to &lt;i&gt;more than ten years ago&lt;/i&gt;, sitting in an office trying to get NAT to work.  A vision appeared in my mind and a blazing hand descended from heaven to write this message across the sky in burning letters:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;echo 1 &gt; /proc/sys/net/ipv4/ip_forward&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;No, I will never learn.  The only hope is write as much stuff down as possible for next time.  Or maybe I should just accept the fact that my faculties have deteriorated past the point of being a small-time linux admin.  Can I still get an account at AOL?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-4933384154188410123?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/4933384154188410123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=4933384154188410123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/4933384154188410123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/4933384154188410123'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2009/05/magic-nat-incantation.html' title='Magic NAT Incantation'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-5910968356392156601</id><published>2009-05-01T11:54:00.000-07:00</published><updated>2009-05-07T14:49:53.644-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Professional Ethics'/><title type='text'>The word you're looking for is "hubris."</title><content type='html'>&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Christopher Buckley's story about the death of his parents (NY Times Magazine, &lt;a href="http://www.nytimes.com/2009/04/26/magazine/26buckley-t.html?ref=magazine"&gt;"Growing Up Buckley,"&lt;/a&gt; April 26, 2009) was funny and sad but in the end it's just another account of the tragic lives of the rich and famous.  It's better written than a typical tabloid piece but fundamentally there's nothing more interesting about this dysfunctional family than a million others.  The audience appeal is in the juicy details.  Was the service really held at St. Patrick's Cathedral?  Where was the reception?  Who was there?  We want (more) names.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;That's not the problem I have with the piece.  I don't give a rat's ass whether they spent Christmas in the Caribbean or Atlantic City.  The offensive part comes at the end, when we're treated to one more salacious, circulation-boosting detail concerning his father's involvement in Watergate and how deeply it troubled him.  Hunt and Nixon were involved in serious crimes, crimes that precipitated a constitutional crisis.  If true this story makes William F. Buckley an accessory.  Ironic or no, the reference to Gethsemane turned my stomach.  Are we supposed to see his father's silence as virtuous? To forgive him because he later became friends with one of the victims?  Because he's rich and famous?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;It's not hard to see a direct connection between the failure to prosecute Richard Nixon's crimes and our situation today, where the members of the same pundit class of which William Buckley was for many years a leading voice dismiss calls for prosecution of the Bush administration for public violations of domestic and international law (and generally shredding the constitution) on the grounds that it represents an &lt;a href="http://www.washingtonpost.com/wp-dyn/content/article/2009/04/24/AR2009042402902_pf.html"&gt; "unworthy desire for vengeance."&lt;/a&gt;  They reveal an unspoken but widely held belief that men and women of high stature, wealth and power are inherently noble and so above the law.  The consequences for the rest of us are severe.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In case Christopher Buckley thinks this is all just petty class resentment, let me call this unspoken belief by another name: &lt;i&gt;hubris&lt;/i&gt;.  Maybe he'll take it more seriously if I say it in Greek.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-5910968356392156601?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/5910968356392156601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=5910968356392156601' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5910968356392156601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5910968356392156601'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2009/05/word-youre-looking-for-is-hubris.html' title='The word you&apos;re looking for is &quot;hubris.&quot;'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-5499400075292790738</id><published>2009-01-22T09:26:00.000-08:00</published><updated>2009-01-22T10:06:00.801-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Punk-ass Admin'/><title type='text'>An XBox, A Fried Router, and Girl Scout Cookies</title><content type='html'>&lt;br&gt;&lt;br /&gt;About six months ago I bought a Linksys WRT54G to replace my DLink wireless router.  The DLink was a horrible POS, with poor signal strength, inexplicably bad bandwidth and requiring power-supply reboots once every few days or so.  It never learned to play nice with the iBook (Crappy network stack? I'd like you to meet broken hardware design...).  So while walking down the aisle of Office Much one day I thought "Hey, I'll pick up a linksys and put Open WRT on it!  Then I'll be a hero hardware hacker for real and I won't have to hear my sweethart cursing a frozen connection as she's trying to meet a publishing deadline anymore..."&lt;br /&gt;&lt;br /&gt;Well, not suprisingly, it sat in the box on my desk for months.  Turns out, the new ones are all Version 8 which has only 2MB of flash memory &amp; replacing the firmware is problematic.  Ugh.  So last weekend I finally decided to give it a go with the original (shipped) software.&lt;br /&gt;&lt;br /&gt;10 hours later, I had it working, sorta.  It has something called "router" mode, but I was unable to get it to work anything like what I would have thought was a router.  It was more like a wireless hub with encryption.  But OK, it worked.  I had the laptop, the SqueezeBox, the XP box and a linux box all on the subnet.  Thought I was home free.&lt;br /&gt;&lt;br /&gt;The XBox couldn't see it.  No way.  Reboot everything, move antennae, wave the bloody chicken.  Nothing.  My SSID was not on the list.  I didn't even get the chance to struggle with the firewall, it just wasn't there.&lt;br /&gt;&lt;br /&gt;Now, it's the Sunday before the Martin Luther King holiday.  My 13-year-old has the next day off and is expecting his friends to come over to play on XBox live.  He's getting worried.  "Dad, the XBox connection is still down."  With lightning-fast fingers he runs through the XBox menus and diagnostics, pointing out with eerie precision where the problem occurs, that the SSID is not appearing, etc.  I've tried everything to no avail.  I'm totally disgusted at having wasted half my weekend on this stupid project.&lt;br /&gt;&lt;br /&gt;Finally, right about dinnertime I decide to give up.  I have another NIC on the server, I can run both routers and dedicate the DLink (which I know worked) to the XBox.  I plug the network cable and power supply in and a moment later... PWAF!  Theres a loud popping sound and a curl of white smoke is coming from the DLink.  I yank the cords and sure enough, I put a 12 volt supply into the 5 volt device.  The stench of ozone and melting plastic wafts through the room.  I grab the box and walk down the hall towards the front door thinking to toss it outside so at least we don't have to breathe whatever evil fumes are coming off it.&lt;br /&gt;&lt;br /&gt;At that moment the doorbell rings.  I open it, the smoldering router still in my hand and there stands the neighbor's 9-year-old daughter.  "Would you like to buy some Girl Scout Cookies?"&lt;br /&gt;&lt;br /&gt;Completely flustered, I answer somewhat irritatedly:  "I'm sorry, but this is really not a good time."&lt;br /&gt;&lt;br /&gt;Her lower lip trembles.  "I'm... sorry..." she says and &lt;span style="font-style:italic;"&gt;runs&lt;/span&gt; away.&lt;br /&gt;&lt;br /&gt;Upstairs I can hear my own kid calling.  "Dad, are you coming to dinner?  And what's that smell?"&lt;br /&gt;&lt;br /&gt;Later, as I explain to kidlet why XBox Live is still not working and it may be a few days I experience the final humiliation:  he's all noble about it.  "That's OK dad.  I spend an awful lot of time on the XBox and you're right, I could read or do something else instead.  And you've already spent a lot of time working on this.  Just relax."&lt;br /&gt;&lt;br /&gt;Now I am truly the World's Lamest Dad.  My &lt;span style="font-style:italic;"&gt;kid's&lt;/span&gt; taking care of &lt;span style="font-style:italic;"&gt;me&lt;/span&gt;.  I officially give up and go to dinner.&lt;br /&gt;&lt;br /&gt;Days later (Wednesday, actually) I'm chatting with the network guru at work and tell him the story.  He's puzzled, having an XBox himself, and goes off at lunch to do a bit of searching.  That afternoon he comes back and shows me this link: &lt;a href="http://nowpa2.bravehost.com/"&gt;http://nowpa2.bravehost.com&lt;/a&gt;.  In short, &lt;span style="font-weight:bold;"&gt;Microsoft's wireless adapter for the XBox 360 does not support WPA2&lt;/span&gt;.  The packaging and manual lie.  I go home, knock the encryption down to WPA Personal and &lt;span style="font-style:italic;"&gt;presto&lt;/span&gt;, up she comes.&lt;br /&gt; &lt;br /&gt;All's well that ends well, I suppose.  The only problem I have now is what to do with a case of Girl Scout Cookies.  Oh, and I'd like my weekend back, please?&lt;br /&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-5499400075292790738?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/5499400075292790738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=5499400075292790738' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5499400075292790738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5499400075292790738'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2009/01/xbox-fried-router-and-girl-scout.html' title='An XBox, A Fried Router, and Girl Scout Cookies'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-5931557599046368105</id><published>2009-01-16T12:58:00.000-08:00</published><updated>2009-01-16T13:20:49.176-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Testing Values Returned From ActiveRecord</title><content type='html'>&lt;br&gt;&lt;br /&gt;Be really careful about testing values returned from the db by ActiveRecord.  How you fetch it affects the data type.  ActiveRecord typecasts the column values returned from the database... sometimes.&lt;br /&gt;&lt;br /&gt;This bit me hard today:&lt;br /&gt;&lt;br /&gt;If you get a model back from active record e.g. with a MyClazz.find() ActiveRecord::Base will read the dictionary tables and typecast the returned attribute to what you expect.  If you use one of the connection class methods, it doesn't do this, it just returns everything as a string.&lt;br /&gt;Comparisons to integer, for example, will FAIL.&lt;br /&gt;&lt;br /&gt;Watch this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;# run the console&lt;br /&gt;&lt;br /&gt; [chrisa@ibs-chrisa-ux1 lims_m4]$ script/console&lt;br /&gt; Loading development environment (Rails 2.1.1)&lt;br /&gt;&lt;br /&gt;# fetch an arbitrary slide&lt;br /&gt;&lt;br /&gt; &gt;&gt; s = Slide.find(81247588)&lt;br /&gt; =&gt; #&amp;lt;slide id: 81247588, &lt;br /&gt;     slide_group_id: 81246827, &lt;br /&gt;     ...&amp;gt;&lt;br /&gt;&lt;br /&gt;# now, I'm expecting an integer for slide_group_id, so I test it with the == operator:&lt;br /&gt;&lt;br /&gt; &gt;&gt; s.slide_group_id == 81246827&lt;br /&gt; =&gt; true&lt;br /&gt;&lt;br /&gt;# how nice, principle of least astonishment and all...&lt;br /&gt;# now let's get that same record using the Base.connection method:&lt;br /&gt;&lt;br /&gt; &gt;&gt; hash = ActiveRecord::Base.connection.select_one("SELECT * FROM slides WHERE id = 81247588")&lt;br /&gt; =&gt; { "id"=&amp;gt;"81247588",&lt;br /&gt;      "slide_group_id"=&amp;gt;"81246827",&lt;br /&gt;      ...}&lt;br /&gt; &gt;&gt; sgi = hash['slide_group_id']&lt;br /&gt; =&gt; "81246827"&lt;br /&gt;&lt;br /&gt;# Whoa.  It's a string:&lt;br /&gt;&lt;br /&gt; &gt;&gt; sgi == 81246827&lt;br /&gt; =&gt; false&lt;br /&gt; &gt;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-5931557599046368105?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/5931557599046368105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=5931557599046368105' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5931557599046368105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5931557599046368105'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2009/01/be-really-careful-about-testing-values.html' title='Testing Values Returned From ActiveRecord'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-2169163737271037298</id><published>2008-08-22T17:47:00.001-07:00</published><updated>2008-08-22T18:09:02.956-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='heenh'/><title type='text'>Premature Ejaculization</title><content type='html'>&lt;span style="font-family:arial;line-spacing:4;" &gt;&lt;br /&gt;&lt;i&gt;"Laziness is a virtue."&lt;/i&gt; - Eric S. Raymond&lt;br&gt;&lt;br /&gt;&lt;i&gt;"Premature optimization is the root of all evil."&lt;/i&gt; - Donald Knuth&lt;br&gt;&lt;br /&gt;Word. So, I'm imagining breakfast with Eric and Donald...&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;8:30am&lt;br&gt;&lt;br /&gt;&lt;b&gt;Don:&lt;/b&gt; We're out of eggs. I'm going to the store.&lt;br&gt;&lt;br /&gt;&lt;b&gt;Eric:&lt;/b&gt; O.K. I'll wait here.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;9:15am&lt;br&gt;&lt;br /&gt;&lt;b&gt;Don:&lt;/b&gt; There's no bread. I'm going to the store.&lt;br&gt;&lt;br /&gt;&lt;b&gt;Eric:&lt;/b&gt; Yeah. Whatever.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;10:00am&lt;br&gt;&lt;br /&gt;&lt;b&gt;Don:&lt;/b&gt; Ooops. Out of OJ. I'll be right back.&lt;br&gt;&lt;br /&gt;&lt;b&gt;Eric:&lt;/b&gt; Could you move to one side? I'm watching the game.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;10:45am&lt;br&gt;&lt;br /&gt;&lt;b&gt;Don:&lt;/b&gt; Damn.  No toilet paper.  Breakfast will have to wait a bit longer.&lt;br&gt;&lt;br /&gt;&lt;b&gt;Eric:&lt;/b&gt; Could you pick up some beer?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-2169163737271037298?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/2169163737271037298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=2169163737271037298' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/2169163737271037298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/2169163737271037298'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/08/premature-ejaculization.html' title='Premature Ejaculization'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-4255043561020535382</id><published>2008-06-30T14:07:00.000-07:00</published><updated>2008-06-30T14:40:02.245-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>A word of warning</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;br /&gt;And now a "a word of warning" (sic) from the ActiveRecord API docs:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier;"&gt;&lt;br /&gt;Don‘t create associations that have the same name as instance methods of ActiveRecord::Base. Since the association adds a method with that name to its model, it will override the inherited method and break things. For instance, attributes and connection would be bad choices for association names.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;Reading that was another one of those &lt;i&gt;"No.  Really."&lt;/i&gt; moments.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;The second time an undetected collision of this type got me (note to self: don't name a database column "errors" unless you have an afternoon to spare) I really considered some shell (better yet Perl, heh) scripts to grep out all the method names from all the plugins + my code and check for collisions.  I now instinctively &lt;i&gt;avoid&lt;/i&gt; any obvious or intuitive sounding name for a column or method.  Since we're up to a dozen+ plugins, it's probably in use already.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;The interpreter could issue a warning of some kind when overloading and a test flag was set, I suppose.  HEY!  Agile means no whining.  Suck it up and KEEP TYPING!&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-4255043561020535382?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/4255043561020535382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=4255043561020535382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/4255043561020535382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/4255043561020535382'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/06/word-of-warning.html' title='A word of warning'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-2877492516615174062</id><published>2008-05-07T17:15:00.000-07:00</published><updated>2008-05-09T09:21:47.710-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Ruby Constants Aren't</title><content type='html'>&lt;span style="font-family:arial;"&gt;I don't know how I missed this but I did.  This morning it bit us, hard.&lt;br /&gt;&lt;br /&gt;Ruby constants aren't constant.  Well, actually, the constant is a reference to an object.  That's immutable, but you can use it to change the object it will refer to.  Really.  It's a feature:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Ruby, unlike less flexible languages, lets you alter the value of a constant, although this will generate a warning message."&lt;span style="font-style: italic;"&gt;  - from Programming Ruby&lt;/span&gt;&lt;/span&gt;, by Dave Thomas&lt;br /&gt;&lt;br /&gt;Umm, isn't that what's usually meant by "variable?"   So you mean that...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;  irb(main):001:0&gt; CONST = "foo"&lt;br /&gt;  =&gt; "foo"&lt;br /&gt;  irb(main):002:0&gt; CONST = "bar"&lt;br /&gt;  (irb):2: warning: already initialized constant CONST&lt;br /&gt;  =&gt; "bar"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Yeah.  Well, I vote we get rid of that annoying error message.  It kinda spoils the thrill.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-2877492516615174062?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/2877492516615174062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=2877492516615174062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/2877492516615174062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/2877492516615174062'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/05/constants-arent.html' title='Ruby Constants Aren&apos;t'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-6031217076146661155</id><published>2008-04-09T17:15:00.001-07:00</published><updated>2008-04-09T17:35:32.447-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Tweaking XML Rendering For ActiveScaffold</title><content type='html'>&lt;span style="font-family:arial;"&gt;Another day, another few hours of googling Ruby blogs to figure out how to accomplish some seemingly trivial task.  This time it's making some minor adjustments to the XML rendering of an ActiveRecord model when the controller is being supplied by ActiveScaffold.  Don't get me wrong, I love automagically created applications.  It's just that, sometimes, all you want to do is change... this one... freaking detail...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;API says you can pass options to &lt;span style="font-family:courier new;"&gt;to_xml.  &lt;span style="font-family:arial;"&gt;As in:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;my_model.to_xml :except =&gt; [:ugly_field]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Problem is, the to_xml method is getting called by the ActiveScaffold ApplicationController and you don't really want to edit that.  If you just want to make a small adjustment and not rewrite the entire rendering method the best option you have is to overload this method in the model class, add the options to the passed array and call super()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  def to_xml(options={}) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  &amp;nbsp;&amp;nbsp;options[:methods] = [:get_formatted_value, :other_value]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  &amp;nbsp;&amp;nbsp;options[:except] = [:irrelevant_accession_number]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  &amp;nbsp;&amp;nbsp;super(options)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Should have been obvious, I suppose, but I spent some of my (dwindling) wattage on it.  Oh well, here's hoping the next rubie finds this on a google search for "activescaffold xml rendering."&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-6031217076146661155?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/6031217076146661155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=6031217076146661155' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/6031217076146661155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/6031217076146661155'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/04/tweaking-xml-rendering-for.html' title='Tweaking XML Rendering For ActiveScaffold'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-470901265180565086</id><published>2008-03-19T11:29:00.000-07:00</published><updated>2008-03-19T16:23:18.033-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Ruby Method References In A One-Pass Interpreter</title><content type='html'>&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;Ruby allows for some very clever techniques involving run-time code evaluation.  I find these particularly handy when writing table driven code (e.g. file parsers).  But coder beware.  There's been a lot of discussion about &lt;a href="http://innig.net/software/ruby/closures-in-ruby.rb"&gt;whether Ruby blocks are truly closures&lt;/a&gt; but the fact that it's a one-pass interpreter (at least the reference implementation I'm using, ruby 1.8.5) can cause some unexpected results as well.&lt;br /&gt;&lt;br /&gt;Consider this simple case: initializing a class property using a method reference.  The Object.method call will succeed or fail (return nil) depending on when it's called in the class definition.   First, let's put the initialization at the top of the class (where most of us would normally put it):&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;class TestMeth&lt;br /&gt;&lt;br /&gt;@@method_ref = self.method(:meth)&lt;br /&gt;&lt;br /&gt;def self.meth&lt;br /&gt;&amp;nbsp;&amp;nbsp;puts "executing meth()"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def run_method&lt;br /&gt;&amp;nbsp;&amp;nbsp;@@method_ref.call&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;tm = TestMeth.new&lt;br /&gt;tm.run_method&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Sorry, no can do:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[chrisa@doppio ~]$ ruby t.rb&lt;br /&gt;t.rb:3:in `method': undefined method `meth' for class `Class' (NameError)&lt;br /&gt;   from t.rb:3&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Now move the assignment to the other side of the method definition:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;class TestMeth&lt;br /&gt;&lt;br /&gt;def self.meth&lt;br /&gt;&amp;nbsp;&amp;nbsp;puts "executing meth()"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;@@method_ref = self.method(:meth)&lt;br /&gt;&lt;br /&gt;def run_method&lt;br /&gt;&amp;nbsp;&amp;nbsp;@@method_ref.call&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;tm = TestMeth.new&lt;br /&gt;tm.run_method&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;That works:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[chrisa@doppio ~]$ ruby t.rb&lt;br /&gt;executing meth()&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The behavior is the same if you make @@method_ref a constant (i.e. 'METHOD_REF').   The interpreter hasn't gotten to that line of the file when the assignment is executed.  If you're using method references, you either have to position them correctly in the file or assign them at run-time in an initializer method.  Works, but not as you might expect.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-470901265180565086?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/470901265180565086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=470901265180565086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/470901265180565086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/470901265180565086'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/03/method-references-in-one-pass.html' title='Ruby Method References In A One-Pass Interpreter'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-6804963705354719233</id><published>2008-03-09T13:47:00.000-07:00</published><updated>2008-03-09T14:20:41.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Professional Ethics'/><title type='text'>"Dude, that's what they want."</title><content type='html'>&lt;span style="font-family: arial;"&gt;Like many others, I'm filled with dismay and anger as I watch retroactive immunity for the phone companies make it's inevitable way through the legislature.   I'm also reminded of my own early experience handling "confidential" information and the way in which it helped me develop professional ethics.&lt;br /&gt;&lt;br /&gt;When I was in college I had the best campus job of anyone I knew.  I worked for the adminstration as a programmer doing data processing.  It paid two dollars more than minimum wage, I could work on my own schedule and best of all, it came with a key to the computing center, which in those prehistoric times had an entire air-conditioned room to house the Dec-10.  It can get awfully hot and muggy in Connecticut in the summer and there were places to hide a sleeping bag, so this was no small perk.&lt;br /&gt;&lt;br /&gt;The job also came with some responsibility.  I had unrestricted access to academic, personal, and financial information for the entire student body and alumni.  For a nineteen-year-old, on top of being recognized as an alpha geek, this was heady stuff.&lt;br /&gt;&lt;br /&gt;So one day, just for fun, I printed out a sorted listing of the entire student body and their birthdays.  It seemed a harmless opportunity to show off.  I showed the listing to a friend and she immediately noticed that a roommate of hers had a birthday that week but hadn't mentioned it.  She decided to get a suprise party together.&lt;br /&gt;&lt;br /&gt;The party was a disaster.  It turned out that her roommate was deeply embarrassed about her age, enough to lie about it and never mention her birthday.  When the suprise was announced she was mortified and, crying, asked everyone to leave.&lt;br /&gt;&lt;br /&gt;There are two lesons here.  One, my intention may have been innocent enough but it had unintended consequences that hurt someone.  Two, by breaking the rules about disclosure of this information I had violated the trust placed in me when I took the job.  The consequences were a good illustration of why the rules were there in the first place.&lt;br /&gt;&lt;br /&gt;I was reminded of this story the other day when I came across the affidavit of Badak Pasdar.  &lt;a href= "http://blog.wired.com/27bstroke6/files/Affidavit-BP-Final.pdf"&gt;This statement&lt;/a&gt;, which he made on Feb. 28 of this year tells a very disturbing story.&lt;br /&gt;&lt;br /&gt;Acting as a computer security consultant in the data center for an unnamed wireless telecommunications company, he comes across a large (DS3, 45Mb/s), unaudited, unsecured network connection leading from &lt;i&gt;inside&lt;/i&gt; the wireless telco's secure internal network to undisclosed recipient(s).  This is referred to by telco employees as the "Quantico Circuit" (Quantico VA is the location of a 100 square mile marine corps base, including their research center).  This pipe gives people on the other side access to everything: they can listen in to any client's phone in real time, track the physical location of their GSM phone, billing records (including who they call), everything.  There's no auditing or tracking implemented so no one at the telco can tell precisely what the people at the other end are doing.  When he asks where it goes and objects that this really can't be considered an acceptable practice WRT commonly accepted industry security standards, he's told to shut up or get fired.&lt;br /&gt;&lt;br /&gt;There's been lots of discussion already (but not enough, IMHO) about the current administration's use of eavesdropping, wiretaps, etc. and the legal, constitutional issues involved.  This story affects me in a personal way however because I am (on a smaller scale) often in positions of trust and responsibility with regards to the personal information of other people and I have to make decisions about the specifics of confidentiality all the time.  As someone working in medical research I've been to more &lt;a href="http://www.hhs.gov/ocr/hipaa/"&gt;HIPAA&lt;/a&gt; compliance training classes and confidentiality seminars than I care to remember (I have another one coming next week, in fact).  And I can tell you, there's a lot of thought and work involved in protecting people's information.  Concerns about the identity and medical condition of study participants percolates all the way back up into database schemas and applicaion codes in a "non-trivial" (as we nerds like to say) way.  Think separate, secured database instances.  The question I have to ask all the time is "where's the line?"  How far do I have to go?  How much extra work should I do?  I have a very simple, effective rule for this:&lt;br /&gt;&lt;br /&gt;I follow the law.&lt;br /&gt;&lt;br /&gt;A lot of smart, well informed people put a lot of work into drafting the applicable law.  It may not be perfect but that's where my society has drawn the line for me.  I'm not going to second guess them because I accept the fact that I'm not smarter than the combined efforts of all those administrators, scientists and legislators and because I accept the responsibility that comes with my well-paying, fascinating and enjoyable job.&lt;br /&gt;&lt;br /&gt;So now I'm thinking about the people who work in that data center.  I can only imagine what it must be like to have access, not to the academic records of two thousand or so students, but to the voice and data communication in real time of millions of American citizens.  Intimate conversations, their location, their routines.  Are they calling their stockbroker?  A lover?  A triple X chat line?  Where are they?  What are they doing?  Who else do they talk to?  Knowing as I do (something about) how one could use that data it's a scary, almost vertiginous thing to contemplate.  What are they thinking when they walk past that network interface unit?&lt;br /&gt;&lt;br /&gt;Maybe they're convinced they're doing the right thing.  It may be illegal but it's for the greater good.  They're informed participants in a critical struggle for the nation's secuirty.  The nation has secrets too, and they're trying, to the best of their ability as professionals, to keep those secrets.  I'd expect them to be ready to take responsibility and the consequences.  Perhaps they (quite) reasonably expect a legal pardon if they were to be prosecuted for breaking the law.&lt;br /&gt;&lt;br /&gt;Or maybe not.  Consider this exchange from the affidavit:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;When DS left, I asked C1 again, "Is this what I think it is?"&lt;br /&gt;&lt;br /&gt;"What do you think?," he replied again, smiling.&lt;br /&gt;&lt;br /&gt;I shifted the focus.  "Forgetting about who it is, don't you think it's unusual for some third party to have completely open access to your systems like this?  You guys are even firewallng your internal offices, and they are part of your own company!"&lt;br /&gt;&lt;br /&gt;C1 said, "Dude, that's what they want."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I can almost see the smirk.  They know.  Their bosses know.  They don't want to know the details, and they certainly don't want to be held accountable.  It's one big wink and the folks at the other end of the cable will cover for them.  &lt;i&gt;That's&lt;/i&gt; the part I can't accept.  I understand the terrible necessities of national security and I'm not so stupid or naive as to think we don't need spies or wiretaps.  But this goes over the line that our society has, with considerable debate and effort, defined in law.  You can't break the law and violate the public trust that severely because someone with a badge tells you to.  The people who've done this are not showing any sense of responsiblity or the gravity of what they're engaged in.  There's no sign of remorse.  Hell, they told a visiting consultant where the cable goes.  No, they're just going along to get along.  And maybe showing off a little.&lt;br /&gt;&lt;br /&gt;They should go to jail.&lt;br /&gt;&lt;br /&gt;I'm not saying ruin their lives.  Maybe just for six months.  Maybe for one day, sentence suspended.  But these individuals, from the tech who hooked up the box to the CEO that approved it, should be "film at eleven."  I want to see them perp-walked in handcuffs out of the courthouse by marshalls.  They should stand up in front of the whole society and acknowledge what they've done.  "Yes, I broke the law, and failed to comply with the ethical standards of my profession.  I'm sorry."  They should be ashamed of themselves.&lt;br /&gt;&lt;br /&gt;Not likely.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-6804963705354719233?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/6804963705354719233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=6804963705354719233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/6804963705354719233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/6804963705354719233'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/03/dude-thats-what-they-want.html' title='&quot;Dude, that&apos;s what they want.&quot;'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-7172919787423237002</id><published>2008-03-04T21:51:00.000-08:00</published><updated>2008-03-05T09:40:39.994-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Nil desperandum!</title><content type='html'>&lt;span style="font-family:arial;"&gt;Which means literally, "Despair of Nothing!"  Makes you wonder if Horace ever worked in software.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;When is a null object reference not a null object reference?&lt;/span&gt;  Why, when you can dereference it, of course.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If a Ruby method returns &lt;span style="font-weight: bold;font-family:arial;" &gt;nil&lt;/span&gt; and I try to dereference it thinking I have a valid object reference, it's going to throw, right?  Raise an exception?   Hurl?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Erm, no.  Actually, nil is an object.  Let's have some fun with &lt;span style="font-weight: bold;"&gt;irb&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[chrisa@doppio ~]$ irb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Can I convert it to an integer?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;irb(main):001:0&gt; nil.to_i&lt;br /&gt;=&gt; 0&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Yep.  At least it's 0.  How 'bout a string?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;irb(main):002:0&gt; nil.to_s&lt;br /&gt;=&gt; ""&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Of course, it's an object, silly&lt;span style="font-family:arial;"&gt;!  And an array, etc.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;irb(main):003:0&gt; nil.to_a&lt;br /&gt;=&gt; []&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;This next one is really cool.  Let's say you got this object reference back from ActiveRecord using &lt;span style="font-family:courier new;"&gt;MyModel.find(:first)&lt;/span&gt;.  Since you've dutifully followed the convention, you expect to get it's accession number by dereferencing the automagic property "id":&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;irb(main):004:0&gt; nil.id&lt;br /&gt;(irb):2: warning: Object#id will be deprecated; use Object#object_id&lt;br /&gt;=&gt; 4&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;Love that deprecation warning.  We all hunt down and fix those right away, right?  I spent a pleasant afternoon staring at the source of that one.  Remember to read those web server logs carefully, kids!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-7172919787423237002?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/7172919787423237002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=7172919787423237002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/7172919787423237002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/7172919787423237002'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/03/nil-desperandum.html' title='Nil desperandum!'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-999954569230139621.post-5197272453460712302</id><published>2008-03-04T15:47:00.000-08:00</published><updated>2008-03-05T09:41:07.162-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Arrgh'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby Newbie'/><title type='text'>Fun with Ruby Conditional Evaluation</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;The first in a series of postings for the unwary Ruby Newbie (Rubie?).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Is a numeric value of 0 true or false?&lt;/span&gt;  To a C or Perl programmer it's obviously false.  In Java it's a trick question (try it).  But even those who've never programmed in C or C++ seem to share a general expectation of "false, duh."&lt;br /&gt;&lt;br /&gt;What about Ruby?  It's easy enough to find out.  We'll use &lt;span style="font-weight: bold;"&gt;irb&lt;/span&gt; (for "&lt;span style="font-weight: bold;"&gt;i&lt;/span&gt;nteractive &lt;span style="font-weight: bold;"&gt;r&lt;/span&gt;uby") to put the question to the interpreter directly:&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;[chrisa@doppio ~]$ irb&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;irb(main):001:0&gt; if (0) then puts "true" end&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;true&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;Which is to say that any numeric value will test true.  How about an empty string?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;irb(main):001:0&gt; if ("") then puts "true" end&lt;br /&gt;(irb):1: warning: string literal in condition&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;true&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;&lt;br /&gt;Well, that's a little bit friendlier but still, I can see getting quietly horked by that one.  Contrast this with Perl's behavior.  The interactive debugger is a bit less friendly, so we just execute the test directly from the command line:&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;[chrisa@&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;doppio&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt; ~]$ perl -e 'if (0) {print "true\n"} ;'&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;[chrisa@&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;doppio&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt; ~]$&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;[chrisa@&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;doppio&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt; ~]$ perl -e 'if ("") {print "true\n"} ;'&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;[chrisa@&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt;doppio&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:100%;"  &gt; ~]$&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=";font-family:arial;font-size:100%;"  &gt;Doesn't quite match the &lt;a href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment"&gt; "Principle of Least Astonishment"&lt;/a&gt; pattern...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/999954569230139621-5197272453460712302?l=espressosoftware.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://espressosoftware.blogspot.com/feeds/5197272453460712302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=999954569230139621&amp;postID=5197272453460712302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5197272453460712302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/999954569230139621/posts/default/5197272453460712302'/><link rel='alternate' type='text/html' href='http://espressosoftware.blogspot.com/2008/03/fun-with-ruby-conditional-evaluation.html' title='Fun with Ruby Conditional Evaluation'/><author><name>ChrisA</name><uri>http://www.blogger.com/profile/17574929007155402374</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp1.blogger.com/_ZvhdMyTVCMQ/R83UUXzFWzI/AAAAAAAAACk/Bcm_cM_jC1M/S220/dancing_bear_thumb.jpg'/></author><thr:total>0</thr:total></entry></feed>
