<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>A Few Thoughts</title>
	<atom:link href="http://gleneivey.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://gleneivey.wordpress.com</link>
	<description></description>
	<lastBuildDate>Sat, 20 Aug 2011 06:29:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='gleneivey.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>A Few Thoughts</title>
		<link>http://gleneivey.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://gleneivey.wordpress.com/osd.xml" title="A Few Thoughts" />
	<atom:link rel='hub' href='http://gleneivey.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Generating a (Google) Sitemap from Ruby-on-Rails</title>
		<link>http://gleneivey.wordpress.com/2010/03/30/generating-a-google-sitemap-from-ruby-on-rails/</link>
		<comments>http://gleneivey.wordpress.com/2010/03/30/generating-a-google-sitemap-from-ruby-on-rails/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 20:35:53 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=66</guid>
		<description><![CDATA[So, I tried to do this really simple thing, and ended up spending way too much time on a tiny little detail of it. Here&#8217;s how I set up my Ruby-on-Rails application to generate a Sitemap (suitable for submitting to Google and lots of other search engines), how easy all the easy parts were, and [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=66&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So, I tried to do this really simple thing, and ended up spending <em>way</em> too much time on a tiny little detail of it.  Here&#8217;s how I set up my Ruby-on-Rails application to generate a Sitemap (suitable for submitting to Google and lots of other search engines), how easy all the easy parts were, and the one trick that ate half a day.</p>
<p>First, background:  A &#8220;<a href="http://www.sitemaps.org/">Sitemap</a>&#8221; is a file or set of files that list the URLs of pages in a web site that you want to be sure get indexed by search engines.  You can also use them to provide hints that help page indexing, like when a page was last changed, an anticipated average frequency of change, relative &#8220;priority&#8221; (importance) of content, etc.  Sitemaps are simple XML files that will be fetched from a site by search engines as part of their spidering process, and while they could be pre-generated and then served as a static file, it seemed to me that a Rails web app ought to generate its own on demand.</p>
<p>Moving to implementation, while you can theoretically choose any name and location for your sitemap file, it really isn&#8217;t practical.  In particular, URLs pointed to from a sitemap must be contained in the same directory or a sub-directory on the server where it is located.  So, if your Sitemap is going to describe your whole site, it has to be served from the root of the server&#8217;s path hierarchy.  Which means that you can&#8217;t use a RESTful route.  So, we add the following in <code>config/routes.rb</code>:</p>
<pre>
  map.sitemap '/sitemap.xml', :controller =&gt; :admin, :action =&gt; :sitemap
</pre>
<p>This maps request for the Sitemap (called <code>sitemap.xml</code>, which is the default name that search engines will look for if you don&#8217;t explicitly specify a name in your <code>robots.txt</code> file or through a specific engine&#8217;s web UI) to the Rails controller <code>admin</code>.  (I&#8217;m not the only one who has a catch-all controller for all the odd stuff in their Ruby-on-Rails application, right?)</p>
<p>Next is the actual implementation of the sitemap action.  For this example, I&#8217;ve assumed that we&#8217;re build a sitemap for the <code>comment</code> model that we&#8217;re all familiar with from the Rails <a href="http://guides.rubyonrails.org/getting_started.html">Getting Started Guide</a>.</p>
<pre>
  def sitemap
    result_text = &lt;&lt;PLAIN_XML
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;
  &lt;url&gt;
    &lt;loc&gt;#{comments_url}&lt;/loc&gt;
    &lt;changefreq&gt;monthly&lt;/changefreq&gt;
    &lt;priority&gt;0.2&lt;/priority&gt;
  &lt;/url&gt;
PLAIN_XML

    Comment.all.each do |comment|
      result_text += "  &lt;url&gt;\n"
      result_text += "    &lt;loc&gt;#{comment_url(comment)}&lt;/loc&gt;\n"
      result_text += "    &lt;lastmod&gt;#{comment.updated_at.to_s(:db) }&lt;/lastmod&gt;\n"
      result_text += "    &lt;changefreq&gt;monthly&lt;/changefreq&gt;\n"
      result_text += "    &lt;priority&gt;0.5&lt;/priority&gt;\n"
      result_text += "  &lt;/url&gt;\n"
    end

    result_text += "&lt;/urlset&gt;\n"
    render :text =&gt; result_text
  end
</pre>
<p>The first few lines, dealing with the here-document <code>PLAIN_XML</code> generate the fixed file header for the Sitemap, as well as the fixed block that points to the <code>index</code> action (page) in the <code>comment</code> controller.  For my sitemap, I didn&#8217;t bother trying to figure out a modification time for it, and assume that the content of the index page will be a less-good match for any search query than the page for a specific comment (<code>comments/show</code>).</p>
<p>Then the block starting from <code>Comment.all.each</code> loops over all the <code>comment</code> model instances stored in the database, and generates the XML package that describes the URL for each.  The XML schema is very simple:  each URL is represented by the content of a <code>url</code> tag, the <code>loc</code> tag contains the URL itself, and the remainder of the tags within the <code>url</code> provide metadata associated with the URL.</p>
<p>The last modification time value, which goes into the <code>lastmod</code> tag, is generated by Rails&#8217; automatic model (database record) update time tracking widgetry.  If you aren&#8217;t already using it, you simply have to add a <code>datetime</code> column named <code>updated_at</code> to your database schema, and Rails will take care of the rest.  (If you&#8217;ve got a running system, make sure your migration fills in an initial value for the new <code>updated_at</code> column or you ensure your code handles <code>nil</code> <code>updated_at</code> values.)</p>
<p>Finally, the end of the method generates the closing XML tag for the sitemap, and then outputs everything.  It&#8217;s important to use <code>render :text</code> to avoid having the intended content of the sitemap wrapped inside of one of your application&#8217;s Rails layouts.</p>
<p>So, there it is, nothing to it.  Didn&#8217;t take any longer to write the code than it did to write the post to this point.  Alas, the code is wrong.  It turns out that, once you&#8217;re past the year/month/day part of the modification time, the date format generated by <code>:db</code> isn&#8217;t compatible with the spec for a Sitemap, which requires a <a href="http://www.w3.org/TR/NOTE-datetime">W3C Datetime</a> date.  Now a quick web search will turn up a couple of things that are related.  First, from <a href="http://swik.net/XML/del.icio.us%2Ftag%2Fxml/Ruby+W3C+Datetime+Format+(Google+Sitemaps+with+Ruby+on+Rails)/b1hvy">http://swik.net/XML/del.icio.us%2Ftag%2Fxml/Ruby+W3C+Datetime+Format+(Google+Sitemaps+with+Ruby+on+Rails)/b1hvy</a>, comes the snipet:</p>
<pre>
  def w3c_date(date) date.utc.strftime("%Y-%m-%dT%H:%M:%S+00:00") end
</pre>
<p>Which works just great, but as a method, putting it into the above code block is kind of ugly.  And I seem to be willing to invest an inordinate amount of time to avoid &#8220;ugly.&#8221;  Then, from <a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Date/Conversions.html">the Rails RDoc</a> comes:</p>
<blockquote><p>
  <u>Module ActiveSupport::CoreExtensions::Date::Conversions</u></p>
<p>  <b>Adding your own time formats to to_formatted_s</b></p>
<p>You can add your own formats to the Date::DATE_FORMATS hash. Use the format name as the hash key and either a strftime string or Proc instance that takes a date argument as the value.</p>
<pre>
    # config/initializers/time_formats.rb
    Date::DATE_FORMATS[:month_and_year] = "%B %Y"
  </pre>
</blockquote>
<p>And that ought to be that, right?  Just stuff the format string from one into the <code>DATE_FORMATS</code> hash and everything should be fine.  But no.  The trick, which took twice as long to figure out as implementing everything else, is that <code>Date::DATE_FORMATS</code> is the wrong hash.  That may be the right hash for classes that have the <code>...Date::Conversions</code> module mixed in, but not here.  The <code>updated_at</code> attribute returns a Rails <code>TimeWithZone</code> object, which is no surprise given that this is Rails&#8217; preferred time class.  What is a surprise, revealed only after you read the source for <code>TimeWithZone</code> is that the hash that <em>it</em> uses for formatting is <code>Time::DATE_FORMATS</code>.  So, in my project, I&#8217;ve got the file <code>config/initializers/extensions.rb</code> that I use for little Rails customizations like that, and it now includes:</p>
<pre>
  Time::DATE_FORMATS[:w3c] =
    lambda { |date| date.strftime( "%Y-%m-%dT%H:%M:%SZ" ) }
</pre>
<p>Which lets me generate the <code>lastmode</code> tag&#8217;s content with:</p>
<pre>
  result_text += "    &lt;lastmod&gt;#{comment.updated_at.to_s(:w3c) }&lt;/lastmodd&gt;&gt;\n"
</pre>
<p>Which is clear, and pretty, and if enough of you read this post, might even be worth the time it took for me to figure it out.</p>
<p>Oh, one more thing:  I know pretty much nothing about time-zone handling in Rails.  The Sitemap format wants last-modification times in UTC, and the format string constant I include above <em>states</em> that the time is UTC (the ending &#8220;Z&#8221; character), and the above works for me.  But, perhaps it wouldn&#8217;t work for someone that had different time-zone settings in Rails or their database.  Anyway, if this produces timestamps that seem off to you, change the content of the <code>lambda</code> to &#8220;<code>date.utc.strftime()</code>&#8221; and all should be well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/66/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/66/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=66&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2010/03/30/generating-a-google-sitemap-from-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Lori Garver: Not every hero at NASA is an astronaut</title>
		<link>http://gleneivey.wordpress.com/2010/03/24/lori-garver-not-every-hero-at-nasa-is-an-astronaut/</link>
		<comments>http://gleneivey.wordpress.com/2010/03/24/lori-garver-not-every-hero-at-nasa-is-an-astronaut/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 03:36:49 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Space]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=54</guid>
		<description><![CDATA[(This post is for Ada Lovelace Day, March 24th, a day to commemorate women in technology and science. You can find a List of other ALD posts at FindingAda.com, and a community-contributed listing of notable women in technology and science at AdasDaughters.org, including the entry I made for Lori Garver, which includes some links I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=54&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignright" style="width: 210px"><a href="http://commons.wikimedia.org/wiki/File:Lori_Garver_at_confirmation_hearing.jpg"><img title="Lori Garver" src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Lori_Garver_at_confirmation_hearing.jpg/477px-Lori_Garver_at_confirmation_hearing.jpg" alt="Lori Garver" width="200" /></a><p class="wp-caption-text">Lori Garver</p></div>
<p>(This post is for Ada Lovelace Day, March 24th, a day to commemorate women in technology and science.  You can find a List of other ALD posts at <a href="http://findingada.com/">FindingAda.com</a>, and a community-contributed listing of <a href="http://adasdaughters.org/">notable women in technology and science at AdasDaughters.org</a>, including <a href="http://adasdaughters.org/LoriGarver">the entry I made for Lori Garver</a>, which includes some links I didn&#8217;t get to use here.)</p>
<p>Lori Garver is the Deputy Administrator of NASA, and one of the shapers of NASA&#8217;s change in direction from the too-slow and too-expensive one-shot &#8220;<a href="http://en.wikipedia.org/wiki/Constellation_program">Constellation program</a>&#8221; toward fostering a sustainable industrial base that will provide for ongoing and continuous manned space missions within the budget NASA has historically received.</p>
<p>Garver rejoined NASA as Deputy Administrator in July of 2009, after leading the Obama Administration&#8217;s NASA &#8220;transition team.&#8221;  Within NASA there is only one Deputy, a position analogous to a corporate CEO (in comparison to the Administrator which is currently similar to a commercial President/Chairman).  <a href="http://www.nasa.gov/about/highlights/garver_bio.html">NASA says</a>:</p>
<blockquote><p>As deputy administrator, Garver is NASA&#8217;s second in command. She is responsible to the administrator for providing overall leadership, planning, and policy direction for the agency. Garver represents NASA to the Executive Office of the President, Congress, heads of government agencies, international organizations, and external organizations and communities. She also oversees the work of NASA’s functional offices, including the Office of the Chief Financial Officer, Office of General Counsel and Office of Strategic Communications.</p></blockquote>
<p>Garver&#8217;s work on space policy began after she was employed in the John Glenn Presidential campaign (1983-84).  Later she started with the American &#8220;National Space Society&#8221; at its founding, and served as its second Executive Director from 1987 to 1996.  She then worked in NASA&#8217;s administration, finishing as Associate Administrator of the Office of Policy and Plans, and leaving NASA in 2001.  Between ending her first tenure at NASA and rejoining as an Obama appointee, she worked in a series of space policy and consultancy organizations (Capital Space, Avascent Group, and DFI Corporate Services), was an active advocate for space exploration, and served as the space policy advisor to the John Kerry, Hillary Clinton, and Barack Obama Presidential campaigns.</p>
<p>And somewhere amid all that, she also worked to assemble a sponsor-funded private trip to the International Space Station, served on the NASA Advisory Council, was a guest lecturer at the International Space University, was both president and board member of Women in Aerospace, and was president of the American Astronautical Society.</p>
<p>When I first heard about Ada Lovelace Day, I immediately wanted to write about Lori Garver, although I&#8217;ve neither met her nor been fortunate enough to hear her speak in person.  As I started researching for this piece, I realized that I didn&#8217;t know exactly why she resonated so much with me.  (She isn&#8217;t even the first woman to be NASA Deputy Administrator.  That was <a href="http://en.wikipedia.org/wiki/Shana_Dale">Shana Dale</a>, her immediate predecessor.)  But I think I&#8217;ve figured it out, and it has to do with both our agreement on technical and policy issues, and on how what she&#8217;s gone through in public the last few years mirrors the struggles I&#8217;ve seen in female colleagues.</p>
<h2>Campaign &#8217;08</h2>
<p>After serving as the space policy advisor to the John Kerry campaign in 2004, Lori Garver held essentially the same position in Hillary Clinton&#8217;s campaign in 2007/08 until Clinton was defeated in the primaries.  In May of 2008, she spoke for the Clinton campaign in a &#8220;debate&#8221; between representatives of Clinton, Obama, and McCain (<a href="http://www.thespacereview.com/article/1142/1">The so-so space debate</a>).  After Clinton&#8217;s loss, Garver became the Obama campaign&#8217;s space advisor (they hadn&#8217;t really had one previously, which had been evident in May).  In August, another debate-of-proxies was held, this time with Garver representing Obama, and again she &#8220;won&#8221; (<a href="http://www.thespacereview.com/article/1192/1">Space policy heats up this summer</a>, <a href="http://climateprogress.org/2008/08/22/whos-advising-mccain-on-energy-and-climate/">Who&#8217;s advising McCain on energy and climate?</a>).</p>
<p>I don&#8217;t know how much of the similarity between the Kerry, Clinton, and Obama space policy positions was due to the candidates own similarities which then caused them to select someone that agreed with them, or to the fact that Garver presumably gave them all similar (sound) advice.  In any event, the cores of the different policies were similar both to each other and to my own views:  NASA is important, but it&#8217;s unrealistic to imagine it getting significantly more resources in the future than it has in the past (after Apollo).  Manned space flight is important, but unless costs are reduced, it is unlikely to be more frequent or to go farther than the Space Shuttle did.  NASA may be a federal government agency, but that doesn&#8217;t mean it&#8217;s acceptable for the number-one concern to be maximizing the number of Congressional districts in which it spends money.</p>
<p>In short, Garver advocated for a space program that would actually do interesting, worth-while, and exciting things.  As opposed to the program we&#8217;ve had for decades, which operated as if it&#8217;s primary goal was to maintain NASA&#8217;s &#8220;workforce&#8221; and cost-plus contractors.</p>
<h2>Obama Presidential Transition</h2>
<blockquote><p>She has been underestimated many times, but has maintained a laser-like focus in her determination to affect change in the U.S. space program.</p></blockquote>
<div style="text-align:right;"><i><a href="http://www.aviationweek.com/aw/blogs/space/index.jsp?plckController=Blog&amp;plckBlogPage=BlogViewPost&amp;newspaperUserId=04ce340e-4b63-4d23-9695-d49ab661f385&amp;plckPostId=Blog%3a04ce340e-4b63-4d23-9695-d49ab661f385Post%3a1d464f70-ac82-428f-b701-83b60899e37b&amp;plckScript=blogScript&amp;plckElementId=blogDest">Obama&#8217;s NASA</a></i>&mdash;Jeffrey Manber</div>
<p>As part of the &#8220;transition&#8221; effort, starting after his election and continuing into the first few months of his administration, Obama had fact-finding teams visit virtually all of the agencies and departments of the federal government.  Lori Garver headed the small &#8220;Agency Review Team&#8221; that was responsible for assessing the current state of NASA and making recommendations to the Presidential transition.</p>
<p>At the beginning of President Obama&#8217;s term, NASA had been working on the Constellation Program for three and a half years.  &#8220;Constellation&#8221; was a combination of new rockets and spacecraft with a plan for how they would be used for flights to Earth orbit and subsequent Moon landings.  It was formulated under NASA Administrator <a href="http://en.wikipedia.org/wiki/Michael_D._Griffin">Michael Griffin</a> in order to implement George W. Bush&#8217;s NASA policy, the &#8220;<a href="http://en.wikipedia.org/wiki/Vision_for_space_exploration">Vision for Space Exploration</a>&#8221; (itself conceived under Griffin&#8217;s predecessor, <a href="http://en.wikipedia.org/wiki/Sean_O%27Keefe">Sean O&#8217;Keefe</a>).  Setting aside the question of whether Constellation was or was not a faithful execution of The Vision, by the time the new administration was coming in, it was clear that NASA was not receiving the budget increases that had been assumed when Constellation was planned, that it was suffering from the same organizational failures that had increased the cost and reduced the performance of the Space Shuttle and International Space Station, and that the hardware systems it was developing would have neither cost nor capability improvements over the Space Shuttle or the Apollo-era Saturn V.</p>
<p>Given all of this, and his own hopes to remain as NASA Administrator under President Obama, Griffin responded somewhat defensively to Garver&#8217;s team&#8217;s efforts to ascertain the real state of affairs within NASA.  As reported in <i><a href="http://blogs.orlandosentinel.com/news_space_thewritestuff/2008/12/nasa-has-become.html">NASA has become a transition problem for Obama</a></i>:</p>
<blockquote><p>NASA administrator Mike Griffin is not cooperating with President-elect Barack Obama’s transition team, is obstructing its efforts to get information and has told its leader that she is “not qualified” to judge his rocket program, the Orlando Sentinel has learned.</p>
<p>In a heated 40-minute conversation last week with Lori Garver, a former NASA associate administrator who heads the space transition team, a red-faced Griffin demanded to speak directly to Obama, according to witnesses.</p></blockquote>
<p>And <em>this</em> is one of the reasons I wanted to write about Lori Garver.  Not just that I admire the work she&#8217;s done and positions she&#8217;s taken, but that her experiences underline both what has improved, and what has <em>not</em>, in the way our culture treats &#8220;women in technology and science.&#8221;  Now, it is clear to me that Griffin would have opposed the efforts of any transition team, whether led by a woman or not.  But the <em>form</em> of that opposition in this case is identical to what I&#8217;ve seen repeatedly happening to women I&#8217;ve worked with.  Time and again I&#8217;ve seen people duck the merits of a technical argument and retreat into attacking a woman&#8217;s right to be in the argument in the first place.  Especially in the case of women who find themselves &#8220;in technology&#8221; without having the proper pedigree and certificates.  After all, Garver&#8217;s degrees (yes, more than one) are &#8220;only&#8221; in Political Science and in Science, Technology and Public Policy.  With credentials like that, and having only worked in space policy for 25 years, how could she possibly be qualified to review the progress of a government technology program?</p>
<p>As disappointing as it is to see this kind of thing still happening, overall I think that Garver&#8217;s role here is a positive sign:  she got and carried out the assignment, she clearly influenced Obama and the transition team, and in the end I believe that Griffin&#8217;s behavior toward her and the transition process are part of the reason that he did <em>not</em> continue on as NASA Administrator.  And there&#8217;s plenty of coverage on the web that looks at it this way (<a href="http://blog.nss.org/?p=1008">[1]</a> <a href="http://www.transterrestrial.com/?p=15333">[2]</a>).  But it is still disappointing.  And, corners of the Internet being the cesspools that they are, it can still be <em>really</em> disappointing:</p>
<blockquote>
<h4>Obama is flooding NASA with annoying &amp; incompetent women and men</h4>
<p>Is Mike Griffin supposed to pretend that he believes that Ms Lori Garver can tell him whether it is a good idea to replace some rockets by Ares I or by the Orion crew capsule? Isn&#8217;t it a little bit over the edge?</p></blockquote>
<p>(I&#8217;m not including a link to this and some other quotes below on purpose.  I&#8217;m sure Google will help you out if you&#8217;re masochistic enough to want the full versions.)</p>
<h2>The Obama NASA FY11 Budget</h2>
<blockquote><p>&#8220;We&#8217;ve been trying to relive Apollo for 40 years, unsuccessfully. For too long NASA over-promised and under-delivered, and now we will be doing things differently.&#8221;</p></blockquote>
<div style="text-align:right;">&mdash;Lori Garver, quoted in <i><a href="http://www.ablueview.com/2010/02/for-human-spaceflight-can-measured-beat-bold.html">&#8220;For Human Spaceflight, Can Measured Beat Bold?&#8221;</a></i></div>
<p>At the conclusion of the NASA transition, President Obama nominated Lori Garver as NASA Deputy Administrator along with ex-astronaut <a href="http://en.wikipedia.org/wiki/Charles_F._Bolden,_Jr.">Charles Bolden</a> as Administrator.  And in the interim, the Obama Administration had chartered the <a href="http://en.wikipedia.org/wiki/Review_of_United_States_Human_Space_Flight_Plans_Committee">Review of Human Space Flight Committee</a>, which identified options for NASA including several alternatives to continuing with Constellation.  (During hearings Jeff Greason, one of the Committee members, concluded &#8220;If Santa Claus gave us [the Constellation] system fully developed tomorrow, the first thing we&#8217;d have to do is cancel it, because we can&#8217;t afford to fly it.&#8221;)</p>
<p>So, I was pleased and hardly surprised when the Obama administration&#8217;s proposals for changes at NASA, which were announced as part of the overall 2011 budget proposal, called for shutting down Constellation and having NASA procure flights to space (crewed and cargo) competitively from commercial enterprises.  But many in NASA and Congress, unable to conceive of non-business-as-usual at NASA, were surprised.  And many senators and representatives from &#8220;the Space Coast&#8221; reacted to save their astro-pork.  In particular:</p>
<blockquote><h4><a href="http://blogs.orlandosentinel.com/news_space_thewritestuff/2010/02/senators-attack-on-nasa-deputy-chief-lori-garver-backfires.html">Senator&#8217;s attack on NASA deputy chief Lori Garver backfires</a></h4>
<p>Vitter accused Garver — who was not present at the hearing — of orchestrating the cancellation of Constellation. He also seemed to suggest that Garver was running the agency, and not Administrator Charlie Bolden. Bolden later called Vitter&#8217;s comment &#8220;unfair.&#8221;</p>
<p>Not only were administration officials outraged by Vitter&#8217;s remarks but several female civil servants and women executives in aerospace companies who have known Garver for years felt compelled to send their complaints to Senate staff Wednesday afternoon.</p></blockquote>
<p>and</p>
<blockquote><h4><a href="http://www.parabolicarc.com/2010/02/25/attacks-lori-garver-backfiring/">Attacks on Lori Garver Backfiring</a></h4>
<p>Garver has become a target of critics of the proposal. Homer Hickam, author of October Sky and the subject of the motion picture Rocket Boys, called Garver a “gadfly” who should resign. He said nothing about Bolden.</p></blockquote>
<p>But comments on blog posts seem to always be more vitriolic than the original content. This is from a comment posted in response to the above blog:</p>
<blockquote><p>&#8220;The problem with Lori Garver is that she is not qualified for the position that she is in. The fact that the recommendations she makes are given the weight that they are is going to be very destructive to the ability of the United States to get to LEO and beyond.&#8221;</p></blockquote>
<p>As with Griffin earlier, there&#8217;s plenty of support for and defense of both Garver and the changes at NASA from (what I consider to be) the reasonable side of the argument (<a href="http://www.spacepolitics.com/2010/02/19/in-defense-of-commercial-spaceflight/">[3]</a> <a href="http://www.spacenews.com/civil/100305-garver-battle-obama-plan-imperils-nasa-budget.html">[4]</a> <a href="http://nasawatch.com/archives/2010/03/fact-checking-i.html">[5]</a>).  As well as more sludge.  In the comments posted on a newspaper article:</p>
<blockquote><p>A journalist with any ounce of integrity and interest should investigate NASA Deputy Administrator Lori Garver&#8217;s unseemly and unethical connections to the very space start-up companies she&#8217;s now benefitting by cancelling Constellation programs. They once funded her quest to become a Russian cosmonaut. She&#8217;s a political appointtee with a dearth of actual space experience. She should be fired for recommending the nuclear-like damage to our NASA manned space program for the next two decades, allowing the Russians, Chinese and India to take-over space pre-eminence. Yea, thanks a lot Obama. Hope and change, allright.</p></blockquote>
<p>On the one hand, this is just another case of Griffin&#8217;s attempts to avoid an argument he can&#8217;t win by attacking his opponent personally, albeit on a grander scale.  On the other, I think the fact that the attackers ignored both Obama and Bolden, both theoretically &#8220;more responsible&#8221; for the changes than Garver, is telling.  It is another sad fact about today&#8217;s culture in America that it has become common to argue against a policy by attacking the character of someone associated with it.  And while it can&#8217;t be the way that anyone wants to have their importance validated, if Garver weren&#8217;t perceived to be playing a significant role in shaping NASA&#8217;s future, she wouldn&#8217;t be worth attacking.  So, while the grounds her attackers are using are far too familiar and unquestionably chauvinistic, I think that it&#8217;s a good sign that she&#8217;s in the game.  And it&#8217;s an even better sign that so far, she&#8217;s winning.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/54/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=54&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2010/03/24/lori-garver-not-every-hero-at-nasa-is-an-astronaut/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>

		<media:content url="http://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Lori_Garver_at_confirmation_hearing.jpg/477px-Lori_Garver_at_confirmation_hearing.jpg" medium="image">
			<media:title type="html">Lori Garver</media:title>
		</media:content>
	</item>
		<item>
		<title>Faster display of web pages with ads (from Amazon or Google)</title>
		<link>http://gleneivey.wordpress.com/2010/03/17/48/</link>
		<comments>http://gleneivey.wordpress.com/2010/03/17/48/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 04:00:59 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby-on-Rails]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=48</guid>
		<description><![CDATA[As I&#8217;ve mentioned, I&#8217;m hoping to make a little money from adding advertising to a web site I&#8217;m putting together. A while ago I added both Amazon Associates ad &#8220;widgets&#8221; and Google AdSense ad &#8220;units&#8221; to my pages. The addition process we quite straight-forward and painless. I even put together a little MediaWiki extension for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=48&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://gleneivey.wordpress.com/2009/11/04/enabling-and-extending-mediawiki-external-images-for-amazon-ad-links/">As I&#8217;ve mentioned</a>, I&#8217;m hoping to make a little money from adding advertising to a web site I&#8217;m putting together.  A while ago I added both Amazon Associates ad &#8220;widgets&#8221; and Google AdSense ad &#8220;units&#8221; to my pages.  The addition process we quite straight-forward and painless.  I even put together a little <a href="http://www.mediawiki.org/wiki/Extension:AmazonWidget">MediaWiki extension for embedding Amazon widgets</a> in wiki pages.</p>
<p>But since then, I&#8217;ve been frustrated at how slowly my pages have loaded.  Both Amazon and Google ads integrate into web pages by having &#8220;the publisher&#8221; (you and me) include a block of HTML/JavaScript that they generate into our pages at the locations where the ads are supposed to appear.  Unfortunately, when most browsers run into a tag that tells them to fetch a remote JavaScript file in the middle of the page, they stop laying out that page on the screen until they&#8217;ve finished fetching the requested JavaScript.  So, even though my pages are relatively small and download quickly, only a tiny bit of them was actually being drawn to the screen before the browser tried to fetch an ad.  It was especially bad in pages where I&#8217;d tried to &#8220;float&#8221; an ad into the upper-right corner:  the screen would blank (my page had been received from my server) and then not a single character of text would be shown for the half-second or second it took for the ad to be fetched.  And to compound problems, a page containing multiple ads would be blocked in its rendering separately for each ad&mdash;the browser wouldn&#8217;t fetch them in parallel.</p>
<p>So, eventually I got frustrated, decided that ads wouldn&#8217;t do me any good if their delays drove people from my site, and got down to the business of trying to restructure things so that I wouldn&#8217;t pay the ad-fetch penalty until my page&#8217;s actual content had been displayed.  This turned out to be trickier that I&#8217;d planned.  I spent quite a while messing around with techniques where I&#8217;d cause the ads to be downloaded by adding their HTML tags to the page&#8217;s Document Object Model (DOM) only after the basic structure of the page was done.  I got several versions of this that <em>almost</em> worked, but it seemed that there were scoping problems caused by the difference between a JavaScript node being inserted into a web page after the fact rather than being parsed on the first pass through, and though they downloaded, I couldn&#8217;t get either Amazon&#8217;s or Google&#8217;s ad code to run when inserting it into the page &#8220;late.&#8221;</p>
<p>Eventually, I found a trick that did work:  putting the ad code in HTML <code>&lt;div&gt;</code> blocks at the very <em>end</em> of the page.  Of course, this isn&#8217;t where I actually wanted the ads to appear, so I also put empty <code>&lt;div&gt;</code>s at the places within my pages where I <em>did</em> want the ads to appear.  Also at the bottom of the page, right between the actual ads and the <code>&lt;/body&gt;</code> tag, I included a little bit of JavaScript that takes each ad, removes the DOM object representing the <code>&lt;div&gt;</code> that contains the ad from the page, and then re-inserts the ad&#8217;s <code>div</code> object within the empty place-holder <code>div</code> that I&#8217;d put earlier in the page.  With a tiny bit of polish (setting <code>display:none</code> on the ad-loading <code>div</code>s, and setting the <code>height</code> and <code>width</code> on the place-holder <code>div</code>s so that the page wouldn&#8217;t re-layout when they were moved up), I had a solution that had my pages being displayed in full as quick as they were before the ads were included, <em>and</em> with the ads popping into view even quicker.</p>
<p>As for the details, I ended up with a single standard piece of JavaScript for moving ads around within a page, regardless of how many there are or where they&#8217;re located:</p>
<pre>
    function moveAndDisplayDelayedDivs(){
      if (typeof divsToMove !== 'undefined')
	for (var c =0; c &lt; divsToMove.length; c++){
	  var targetDiv = document.getElementById( divsToMove[c] );
	  var divWithAd = document.getElementById( divsToMove[c] + &#39;-content&#39; );

	  // remove the ad div from the main document
	  var parent = divWithAd.parentNode;
	  parent.removeChild( divWithAd );
	  // put the ad div into its target location on the page
	  targetDiv.appendChild( divWithAd );
	  // and make it visible
	  divWithAd.style.display = &#39;block&#39;;
	}
    }
</pre>
<p>This code relies on a couple of conventions.  First, somewhere earlier in the pages, there must have been code that made <code>divsToMove</code> an array containing the IDs of the HTML <code>div</code> tags into which the ads must be moved.  To avoid having to have to arrays, I established the convention that if <code>id="foo"</code> is the <code>div</code> where an ad is ultimately supposed to be displayed, then the <code>div</code> containing the third-party markup for that ad would always be <code>id="foo-content"</code>.  After that, it&#8217;s a straight-forward bit of DOM manipulation to move the <code>-content</code> <code>div</code>s up the page into their intended display locations.</p>
<p>I chose to build up the <code>divsToMove</code> array incrementally, making one addition to it in each place in the page where I wanted an ad to be located.  So, I made sure the following trivial function is defined at the top of my pages:</p>
<pre>
    function addToDivsToMove(divId){
      if (typeof divsToMove === 'undefined')
	divsToMove = new Array();
      divsToMove[ divsToMove.length ] = divId;
    }
</pre>
<p>And then the declaration of a point that will <em>eventually</em> display an ad looks like:</p>
<pre>
    &lt;div id="google-ad" style="width: 160; height: 600px;"&gt;&lt;/div&gt;
    &lt;script&gt;
      addToDivsToMove('google-ad');
    &lt;/script&gt;
</pre>
<p>With the third-party ad code itself appearing near the bottom of the page like this:</p>
<pre>
    &lt;div id="google-ad-content" style="display: none;"&gt;
      &lt;script type="text/javascript"&gt;&lt;!--
	google_ad_client = "my publisher_id";
	google_ad_slot = "my page_slot";
	google_ad_width = 160;
	google_ad_height = 600;
	//--&gt;&lt;/script&gt;
      &lt;script type="text/javascript"
	      src="http://pagead2.googlesyndication.com/pagead/show_ads.js" &gt;
      &lt;/script&gt;
    &lt;/div&gt;
</pre>
<p>The one thing that is worth repeating/noting is that, in order to avoid the page&#8217;s layout being changed when the browser reaches the bottom of the page and executes the code to move the ads up to their final locations, the <code>div</code>s that the ads are going to be moved into need to have their size explicitly set to match the ad.  I don&#8217;t find this to be problematic, as both Amazon and Google require you to choose from a handful of fixed sizes for their advertisements, anyway.  So, as long as the size is fixed anyway, it&#8217;s only a minor inconvenience to have to repeat it between the first <code>div</code>&#8216;s declaration and the third-party markup.</p>
<p>And that&#8217;s that.  But, I have the great good fortune to be implementing my web application in Ruby-on-Rails.  So, while people unlucky enough to be putting their page templates together by hand might have a problem making sure that the &#8220;moving parts&#8221; of the two <code>div</code>s that the ads are split between match up, I can actually put those parts in the same source file right next to each other, and depend on Rails to separate them out for me.  Below is the equivalent source for including an Amazon &#8220;Omakase&#8221; ad block into my Rails-generated pages:</p>
<pre>
    &lt;% unless @this_is_non_information_page or ENV['RAILS_ENV']=='test' %&gt;
      &lt;% if WontoMedia.ads.amazon and
	    WontoMedia.ads.amazon.associate_id %&gt;

	&lt;div id="block-amazon-ad" class="box"
	    style="width: 99%; height: 600px; text-align: center;"&gt;&lt;/div&gt;
	&lt;script&gt;
	  addToDivsToMove('block-amazon-ad');
	&lt;/script&gt;

	lt;% content_for :last_bottom_page_js do %&gt;
	  &lt;div id="block-amazon-ad-content" style="display: none;"&gt;
	    &lt;script type="text/javascript"&gt;&lt;!--
	      amazon_ad_tag = "&lt;%= WontoMedia.ads.amazon.associate_id -%&gt;";
	      amazon_ad_height = "600";
	      amazon_ad_height = "160";
	      //--&gt;
	    &lt;/script&gt;
	    &lt;script type="text/javascript"
		    src="http://www.assoc-amazon.com/s/ads.js"&gt;&lt;/script&gt;
	  &lt;/div&gt;
	&lt;% end %&gt;
      &lt;% end %&gt;
    &lt;% end %&gt;
</pre>
<p>(Note that this code comes from my live project, <a href="http://github.com/gleneivey/wontomedia">WontoMedia</a>, and is licensed under <a href="http://www.fsf.org/licensing/licenses/agpl-3.0.html">AGPLv3</a>.)</p>
<p>There are several bits of Rails coolness that this takes advantage of or relates to.  First, this blob of code and markup is the sole content of a Rails layout partial, so I can incorporate an Amazon ad into any location of any of my pages by rendering that partial into the desired <em>display</em> location within a page layout.  Second, Rails allows multiple independent <em>streams</em> of information that will eventually make up a page to be composed in parallel.  Most people don&#8217;t take advantage of this, and all their templates are composed together linearly in the order in which different parts include each other.  However, by using <code>content_for</code> and having a matching <code>yield</code> in my top-level layout, this one file can generate HTML that is part of Rails&#8217; default content flow (the <code>div</code> that the ad will eventually display in when it&#8217;s loaded) <em>and</em> part of the flow I&#8217;ve labeled <code>last_bottom_page_js</code>.  (Yes, I do have other <code>..._bottom_page_js</code> flows, so what?)</p>
<p>I also use the embedded-Ruby (ERB) that Rails provides in page layouts and partials to:</p>
<ul>
<li>
manage which of my pages actually have ads displayed (only those that don&#8217;t have the Ruby variable <code>@this_is_non_information_page</code> set for them)
 </li>
<li>
suppress the inclusion of ads when my pages are loaded during unit testing (yes, the ad-loading delays were a pain when visiting my site, but adding a few seconds per page to a few hundred pages loaded during regression testing nearly made me walk off a pier)
 </li>
<li>
allow for customization of my web application:</p>
<ol>
<li>
The <code>WontoMedia</code> object is a Ruby <code>OpenStruct</code> which I use to hold configuration information for a particular installation of my web application.  When I install my app on sites I run, I fill in the advertising config info with the values associated with my Amazon and Google accounts.  If someone else installs WontoMedia, they can run it with no advertising (simply by not including these constants in their config file) or set it up to point to their own advertising accounts.
  </li>
<li>
The actual configuration values are then inserted into the boiler-plate code provided by the ad vendor using Rails&#8217; ERB notation for including the result of evaluating a Ruby expression into the output page:  <code>&lt;%= expr -%&gt;</code>.
 </li>
</ol>
</li>
</ul>
<p>All-in-all, a relatively satisfying solution to my problems with slow page loading due to external ads.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/48/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/48/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/48/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=48&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2010/03/17/48/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8220;uninitialized constant ActionController (NameError)&#8221;: The Stupidest Thing I&#8217;ve Done in Ruby-on-Rails</title>
		<link>http://gleneivey.wordpress.com/2010/03/16/uninitialized-constant-actioncontroller-nameerror-the-stupidest-thing-ive-done-in-ruby-on-rails/</link>
		<comments>http://gleneivey.wordpress.com/2010/03/16/uninitialized-constant-actioncontroller-nameerror-the-stupidest-thing-ive-done-in-ruby-on-rails/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 04:36:09 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Ruby-on-Rails]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=45</guid>
		<description><![CDATA[The short version: yes, every one of your Rails test files needs to start with require 'test_helper'. Even though things might be just fine for a while if you leave it out of a few tests, eventually it will bite you. Rails contains plenty of magic, but it isn&#8217;t actually supernatural. And when you run [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=45&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The short version:  yes, <em>every</em> one of your Rails test files needs to start with <code>require 'test_helper'</code>.  Even though things might be just fine for a while if you leave it out of a few tests, eventually it will bite you.  Rails contains plenty of magic, but it isn&#8217;t actually supernatural.  And when you run your tests with <code>rake</code> the test runner that is used (<code>rake_test_loader.rb</code>) is generic, with no inherent knowledge of Rails.  If your test doesn&#8217;t start with the <code>require</code> statement, none of Rails will be loaded.  So if you try to run the test in isolation, you&#8217;ll get &#8220;uninitialized constant&#8221; errors on the <code>class</code> declaration where you try to inherit your test class from one of Rails&#8217; base test classes.</p>
<p>Before I&#8217;d paid attention to <code>test_helper</code> to the extent that I&#8217;ve added stuff to it, and knew I needed to <code>require</code> it at the top of those files that used my additions.  But back when I started with Rails, figuring out the magic included in the boiler-place created in <code>test_helper</code> by scaffolding wasn&#8217;t my most pressing issue.  I mostly stopped thinking about it, and all of my tests have been just running, and all was well.</p>
<p>But then I tried running my project&#8217;s automated tests on a new system.  And they just wouldn&#8217;t.</p>
<p>At first, I looked in lots of the wrong places, because this wasn&#8217;t the first time I&#8217;d moved my project between systems, and platform issues weren&#8217;t my first suspects.  I still don&#8217;t know what caused things to be reliable on my first development systems, but it turned out that the difference that caused my problem to be revealed was deep under the hood in <code>rake</code>:  on my original system, <code>rake</code> chose to run my tests in an order that coincidentally placed one of the files that <em>did</em> have <code>require 'test_helper'</code> first in its execution order.  And because all of the tests that <code>rake</code> executes run within the same Ruby interpreter, all of the subsequent tests get the benefit of that one original <code>require</code>.  And I continued to get lucky in running my project&#8217;s tests on different systems, right up until the last one.  On that one, <code>rake</code> picked a different order to execute the tests&mdash;an order in which a test that I left the <code>require</code> out of was run first.  And it failed.  Duh.</p>
<p>Of course, <code>ActionController</code> isn&#8217;t the only &#8220;uninitialized constant&#8221; error you might get if you&#8217;ve had this particular brain-fade.  The class named could be any Rails class, but if you&#8217;re having problems running tests, then they&#8217;ll likely by a Ruby or Rails base test class like <code>Test</code>, <code>ActiveSupport</code>, <code>ActionView</code>.</p>
<p>I&#8217;m a bit embarrassed to admit to this error, to having gotten this far along without understanding that <code>test_helper</code> was the sole link between my tests and the rest of Rails.  On the other hand, if someone else had written this post and Google had found it, I&#8217;d have solved my problem in a few minutes instead of the three hours that it did take.  So, here it is, and my best to you if you&#8217;ve happened onto this because you&#8217;re having the same problem.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=45&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2010/03/16/uninitialized-constant-actioncontroller-nameerror-the-stupidest-thing-ive-done-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Weakening Copyright is Weakening Free Software (Conclusion)</title>
		<link>http://gleneivey.wordpress.com/2010/03/12/weakening-copyright-is-weakening-free-software-conclusion/</link>
		<comments>http://gleneivey.wordpress.com/2010/03/12/weakening-copyright-is-weakening-free-software-conclusion/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 21:40:34 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Copyright]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=37</guid>
		<description><![CDATA[This is the last part in my series on the importance of maintaining copyright protection for software. The earlier parts were Background and Copyleft and Embrace-and-Extend. Types of Free and Open Source Licensing Bruce Perens argues that there are basically only three types of Free or Open Source software license: the gift license &#8212; essentially [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=37&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is the last part in my series on the importance of maintaining copyright protection for software.  The earlier parts were <a href="http://gleneivey.wordpress.com/2009/11/03/weakening-copyright-is-weakening-free-software-part-1-background/">Background</a> and <a href="http://gleneivey.wordpress.com/2009/11/08/weakening-copyright-is-weakening-free-software-part-2-copyleft-embraceextend/">Copyleft and Embrace-and-Extend</a>.</p>
<h3>Types of Free and Open Source Licensing</h3>
<p><a href="http://itmanagement.earthweb.com/osrc/article.php/3803101/Bruce-Perens-How-Many-Open-Source-Licenses-Do-You-Need.htm">Bruce Perens argues</a> that there are basically only three types of Free or <a href="http://en.wikipedia.org/wiki/Free_and_open_source_software">Open Source</a> software license:</p>
<ul>
<li>the gift license &mdash; essentially any non-copyleft free license, giving others the right to modify, redistribute, and incorporate in any context</li>
<li>sharing-with-rules &mdash; is Perens&#8217; term for copyleft licenses, emphasizing that they effectively create a collaboration between original author and modifiers</li>
<li>the &#8220;in-between&#8221; license &mdash; a category that encompasses the <a href="http://en.wikipedia.org/w/index.php?title=GNU_Lesser_General_Public_License">GNU Lesser General Public License</a>, which was created to provide copyleft licensing for the body of a reusable software component, while allowing that component to be incorporated into other, non-copyleft, software.</li>
</ul>
<p>As an example, the <a href="http://www.blackducksoftware.com/oss/licenses/">most popular</a> gift license is the <a href="http://www.opensource.org/licenses/bsd-license.php">BSD License</a>.  And for the balance of this post, I&#8217;ll ignore the distinctions between the non-gift license types (<i>e.g.,</i> GPL vs. LGPL).  Both of these licenses serve to mandate a population of re-publishing modification authors, which is the significant difference between copyleft and gift licenses.</p>
<p>While the original authors of free software are certainly members of the same community as other authors, users, and &#8220;modifiers&#8221;, they continue to have a special legal relationship with their creations.  The author (technically, the copyright owner) of a piece of software is not bound by the license terms that apply to others.  An author of software released under a copyleft license could keep some modifications private, can re-release the software under another license, and can sell non-free licenses to the software if they choose.</p>
<p>A number of companies based on the development of free software use their special relationship with the software&#8217;s copyright as a key element of their business models.  These companies use &#8220;dual licensing&#8221;, where the software is made available simultaneously under different licensing terms to different audiences.  Most commonly, the source is publicly released using a copyleft license, but the owner also makes another license available for a fee, that doesn&#8217;t require the licensee to republish modifications.  A variation of this is where the copyright owner does not publish all of the software they have available, keeping the source code for a few &#8220;value added&#8221; features private.  Then the commercially-licensed (fee-based) alternative to the free software version of the package may be valuable to customers who don&#8217;t plan to make their own modifications.</p>
<p>In a dual-licensing case, the people using the free software version/license to a package benefit by not having to pay the fee, and the company benefits by being able to incorporate modifications published by others into the free version.  Companies paying for private licenses to the package can also benefit from the availability of the free-software version:  the overall quality of the package is typically higher than a closed-source alternative, and the license cost is typically lower.  (Lower license costs are enabled by the contributions of the free software community to the package, and enforced by the fact that any sufficiently-motivated developer could create their own implementation of privately-licensed features.)</p>
<h3>A World Without Copyleft</h3>
<p>If copyright were abolished without the simultaneous creation of a new legal basis for copyleft licensing, the software industry would be shifted into an environment where all of the published source code in the world was effectively &#8220;gift licensed&#8221;.  By comparison, today 65%+ of the open-source software in the world is licensed with a GNU Public License, with perhaps 75% being under some type of copyleft license, GNU and non-GNU combined.  I also believe that copyleft licensing&#8217;s effect on the community is even higher than would be expected from that percentage.  Given the percentage of key software infrastructure components and tools (from the Linux kernel and GNU operating system on down) that are used via copyleft licensing, it is unlikely that there is a software developer in the world who isn&#8217;t aware of the terms of copyleft or who uses copyleft&#8217;ed software.</p>
<p>So, in a world without the ability to enforce copyleft, what would change?  First, those companies who rely on dual-licensed software for their economic viability would gradually expire.  No copyleft enforcement would immediately remove the incentive of all customers who are paying for the privilege of not having to republish their modifications to a piece of software.  The profitability of licensing proprietary add-on features would follow soon after, first for those packages written in interpreted languages, and then the rest (as DRM for computer software is notoriously brittle and expensive now, even with the underlying support of copyright law).</p>
<p>The next obvious problem is that the entire corpus of free software would become vulnerable to Embrace-and-Extend.  Without the requirement to republish modifications, the fragile balance of competition that has grown up between the free software community and (especially large) closed-source software publishers would be disrupted.  Every software enhancement a community member publishes would be a direct reduction to the expenses of closed-source companies.</p>
<p>In a sense, without the protections of copyleft, free software would become the victim of a &#8220;<a href="http://en.wikipedia.org/wiki/Tragedy_of_the_commons">tragedy of the commons</a>.&#8221;  At first, this comparison may seem invalid.  After all, how can the common resource of &#8220;free software&#8221; be depleted by more people making copies when (as a copyright abolitionist would argue) making a copy of someone&#8217;s software doesn&#8217;t stop them from still having their copy.  But the &#8220;commons&#8221; isn&#8217;t the <em>software</em>; the important shared resource, that can either be developed or degraded, is the population of <em>free software developers</em>.  Zed Shaw has written a <a href="http://www.zedshaw.com/blog/2009-07-13.html">quite personal essay</a> describing his negative experiences from releasing software under a gift license and defending his exclusive use of the GPL in the future.  I believe that these experiences would become the norm if copyleft licensing were no longer possible, and that without the option Shaw had of moving to copyleft licenses, most developers would abandon publishing free software altogether.</p>
<p>Just because publishers of free software don&#8217;t receive cash payments from the people who use or modify their code, it is wrong to assume that there is no value exchanged, or that eliminating that exchange wouldn&#8217;t have an effect on on publishing.</p>
<p>Finally, in <a href="http://www.amazon.com/gp/product/0596001088?ie=UTF8&amp;tag=wontology-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596001088">The Cathedral &amp; the Bazaar</a> Eric Raymond points out that most software is developed within organizations for their own use or for incorporation into other products.  Development efforts where software is the end product are actually very much in the minority.  Raymond argues that free software is good for most organizations developing internal-use software, as it allows the development costs of the software to be shared among peer and competitor organizations, providing that the software doesn&#8217;t form the primary basis on which competition occurs.  However, even these efforts would be affected if copyright (and copyleft) were eliminated.  Without the guarantee that other organizations will re-publish modifications, the risk that internal-use software <em>will</em> become the basis on which companies compete increases significantly, with a matching reduction in the incentive for an original author to publish.</p>
<h3>When Copyright isn&#8217;t Copyright</h3>
<p>Finally, a quick diversion into the land of people who want to abolish copyright but somehow keep copyleft or other open/<a href="http://creativecommons.org/">commons</a> licenses.  For example, the post <a href="http://questioncopyright.org/copyright_and_open_source">Copyright and Open Source</a> suggests that what copyright abolitionists want is copyright reform so extreme that it would be wrong to call the reformed legal framework &#8220;copyright&#8221; at all.  It seems to me that this is a confusing distinction to make.  That post claims a distinction between &#8220;<em>credit right</em>&#8221; (which is apparently Good&trade; and moral to enforce) and copyright (which is an unreasonable legal fiction).  In particular, there&#8217;s the common argument against copyright:  &#8220;If I steal your bicycle, now you have no bicycle; if I copy your computer program, now we both have it.&#8221;  Unfortunately, the problem of eliminating copyright doesn&#8217;t arise because &#8220;you&#8221; have my computer program.  It arises because Microsoft has it and will turn around resell it as proprietary to thousands of others.</p>
<p>Taking away copyright and replacing it with statues protecting &#8220;creditright&#8221; is not a good trade.  Yes, if copyright disappeared, I suppose it might be an interesting consolation prize for people stealing my work to have to include my name on the mile-long list of everyone they&#8217;ve stolen from.  It might be something (a hypothetical) I could point to in my resume, as I try to find a new job at a closed-source company after the open-source company I was working for collapses.  Credit&mdash;being able to build a reputation from the work a programmer publishes&mdash;is certainly an important part of the value that is exchanged when someone makes free software available.  But it isn&#8217;t the only part, or sufficient to sustain a free software &#8220;ecosystem&#8221; comparable to what we have today.</p>
<h3>In Summary</h3>
<p>So, hopefully I&#8217;ve convinced you that, if you like having access to free and open-source software, you need to defend the GPL (even if you choose not to use it yourself), and you cannot join the ranks of the (software) copyright abolitionists.  If not, perhaps a quick recap will push you over the edge:</p>
<ul>
<li>Copyright law, while having significant flaws in the U.S. at the moment, is necessary to allow authors to set the terms of exchange for their work.  Not all compensation is monetary, and copyright is essential in protecting the in-kind exchanges (software modifications, reputation and acknowledgement, etc.) within the free software community.  And while credit can be part of that compensation, it is far from the only part that needs to be legally protected.</li>
<li>The fact that a fraction of the available free software uses gift licenses does not prove that free software is sustainable without the option of copyleft licensing.  Not only does gift-licensed software make up a minority of the free software &#8220;market&#8221;, but even if it were a small majority, copyleft-licensed software controls the dynamics of that market.
<li>Yes, Richard Stallman and the GNU Project may have political/cultural goals more extreme than yours, but nothing in copyright law or copyleft licenses is coercive.  Just like any other contract, a free software license is an exchange voluntarily entered into by both parties.</li>
</ul>
<p>The terms of copyleft are never forced on anyone&mdash;if you feel like you&#8217;re being &#8220;forced&#8221; to use software distributed under a copyleft-license, look at your assumptions again.  What are your alternatives, really?  Are there other things that you could do, but you&#8217;ve excluded them from consideration because of prohibitive cost or inconvenience?  What if the piece of free software you &#8220;have to&#8221; use didn&#8217;t exist?  If you have any alternative to using a piece of GPL&#8217;ed software besides &#8220;curl up in the corner and die,&#8221; then you&#8217;re not being forced, you&#8217;re being cheap.</p>
<p>Yes, there&#8217;s lots of really good software available under copyleft licenses.  Yes, it&#8217;s really tempting to use it in your projects&mdash;that was one of Stallman&#8217;s original criteria for deciding what packages the GNU Project should work on, in an effort to improve adoption of free software.  But when making a copy of my work deprives me of the benefit that I want to receive in exchange for that work, it seems like theft to me, even if I &#8220;still have my copy.&#8221;  And given the diverse range of values that developers and organizations seek by publishing free software, undermining copyright will allow perceived theft and depress or destroy the production of new free software.</p>
<hr />
<p>Well, thanks for playing&mdash;I hope you found something here to set you thinking.  And if you&#8217;re still interested in this topic, here are a couple of other posts I ran into while researching for this piece:</p>
<ul>
<li><a href="http://saviorodrigues.wordpress.com/2009/07/15/why-open-source-vendors-will-continue-to-select-the-gpl">Why Open Source Vendors Will Continue to Select the GPL</a></li>
<li><a href="http://www.ravenna.com/~forbes/yonk/source/licensing.html">Why I Use the GPL</a></li>
</ul>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/37/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/37/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/37/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=37&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2010/03/12/weakening-copyright-is-weakening-free-software-conclusion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Weakening Copyright is Weakening Free Software (Part 2, Copyleft; Embrace/Extend)</title>
		<link>http://gleneivey.wordpress.com/2009/11/08/weakening-copyright-is-weakening-free-software-part-2-copyleft-embraceextend/</link>
		<comments>http://gleneivey.wordpress.com/2009/11/08/weakening-copyright-is-weakening-free-software-part-2-copyleft-embraceextend/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 18:20:26 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Copyright]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=31</guid>
		<description><![CDATA[In Part 1, I quickly reviewed what copyright is and how the GNU General Public License (the GPL) uses copyright law to allow the original author of a piece of software to make it available for widespread use while simultaneously ensuring that they (and everyone else) receive the benefit of any changes that other people [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=31&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://gleneivey.wordpress.com/2009/11/03/weakening-copyright-is-weakening-free-software-part-1-background/">Part 1</a>, I quickly reviewed what copyright is and how the <a href="http://en.wikipedia.org/wiki/GPL">GNU General Public License</a> (the GPL) uses copyright law to allow the original author of a piece of software to make it available for widespread use while simultaneously ensuring that they (and everyone else) receive the benefit of any changes that other people subsequently make to it.</p>
<h3>For and Against: Copyright Law and Copyleft</h3>
<p>Many people advocate reforming copyright law, many of them from the software industry and related fields.  And, depending on the reform, it would be fair to count me as one of them.  There is also a vocal group who believe that copyright is anachronistic (digital copies have virtually no cost) or contrary to the social good (the free-flow of information is more important than ever in today&#8217;s society).  Anti-copyright advocates will often use the slogan <a href="http://en.wikipedia.org/wiki/Information_wants_to_be_free">&#8220;information wants to be free,&#8221;</a> and maintain that attempts to enforce copyright law are counter to the flow of progress and doomed to failure.</p>
<p>As you may have guessed, I don&#8217;t agree with the copyright abolitionists.  I also don&#8217;t agree with a related set of people, mostly programmers, who are in favor of <a href="">Open Source</a> software, but feel that the copyleft provisions of the GPL are (somehow) &#8220;wrong.&#8221;  Given the subset of these programmers I&#8217;ve known personally, I think that for the majority of them, the objections are relatively shallow:  the fact that some software uses a copyleft license imposes extra work on them (making their modified version available publicly) that they&#8217;d rather not do, or forces them to talk to their employer&#8217;s legal department, or prevents them from using the software entirely because of their company&#8217;s policies/decisions.  I&#8217;ve met virtually no developers who are self-employed, or not employed as programmers at all, who have these objections.</p>
<p>The rest of the anti-copyleft programmers I&#8217;ve known and read make arguments in the same famillies as the justifications for copyright law:  moral and pragmatic/economic.  The moral/ethical arguments against copyleft are much like those of the copyright abolitionists:  &#8220;software wants to be free&#8221; and that it&#8217;s unreasonable to call something completely intangible &#8220;property.&#8221;  Somehow, though, they feel that these arguments apply to software more than they do to other copyrighted works.  Perhaps they see software more as a collection of useful parts than as an integrated whole like a novel or song.  (Although I would imagine that <a href="http://en.wikipedia.org/wiki/Sampling_(music)">sampling</a> musicians would disagree.)</p>
<p>One interesting anti-copyleft argument is that the GPL (and similar licenses) are not &#8220;free&#8221; because they deny other people the &#8220;freedom&#8221; to keep their own modifications to a software package private/proprietary.  At first, this argument might be appealing, but it is essentially analogous to saying that a tolerant person must also tolerate someone else&#8217;s intolerance.  These people are worried about their &#8220;freedoms&#8221; with respect to something that first had to be <em>created by somebody else</em>.  And even though they don&#8217;t have to sign a document before copying the original author&#8217;s work, the license is still a contract between the two.  And if they don&#8217;t want to have their &#8220;freedom&#8221; somehow &#8220;taken away&#8221; by that contract, all they have to do is not copy the other person&#8217;s work in the first place.</p>
<p>Some people who complain about the GPL taking away their freedoms subscribe to the anti-copyright argument that an unsanctioned copy doesn&#8217;t take anything &#8220;real&#8221; away from the original author.  But to them I say &#8220;How can you complain about the GPL requiring you to let other people copy your work if you believe all restrictions on copying are wrong?&#8221;  At which point, we arrive at the root of the matter.  The people concerned over the GPL&#8217;s &#8220;taking of their freedom,&#8221; underneath all of the moral and economic arguments, actual fall into two groups:</p>
<ul>
<li><em>the lazy</em>:  they don&#8217;t actually object to other people copying their work, they object to having to go to all the trouble to <em>publish</em> their work for others.  Yet they want to benefit from the (presumably much greater) work of original authors who did publish.</li>
<li><em>the intellectually dishonest</em>:  they&#8217;re working in a compiled programming language, so they know that even if copyright were abolished, as long as they release only executable binaries, nobody else can build on their work, even though they&#8217;re building on the original author who published their code as source.</li>
</ul>
<p>Finally, the argument against &#8220;depriving people of freedom&#8221; cuts both ways.  If the copyright abolitionists succeed (either completely, or by carving out some kind of software-specific exception), then they will have deprived me of my &#8220;freedom&#8221; to only share software source code with those who will share with me in return.</p>
<h3>Embrace, Extend, Extinguish</h3>
<p>&#8220;<a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish">Embrace, Extend, and Extinguish</a>&#8221; is the alleged internal name of Microsoft&#8217;s strategy for moving existing standards and technology from being competitive to being Microsoft-propriety.  The method is practiced as follows:  (1) wait for somebody else to implement something cool, (2) implement a clone of it yourself, (3) add a handful of minor tweaks so that your clone isn&#8217;t compatible with the original, (4) use your existing dominance to bootstrap your clone into the marketplace.  After step 4, Microsoft&#8217;s market share grows monotonically barring a major success by a competitor, because each customer that changes to the MS-specific version creates for themselves a significant cost to ever change (back) to a competing version.</p>
<p>Clearly, the existence of software licensed using copyleft in a particular technical niche doesn&#8217;t prevent Embrace&amp;Extend entirely.  Any organization large enough to practice this strategy is large enough to implement a clone entirely from scratch.  However, having public, non-copyleft sources certainly gives the &#8220;extender&#8221; a leg up; even more so if the public version of the technology continues to be maintained.  Without a copyleft license, and the underlying copyright law to enforce it, the existence of public sources for a technology is an even greater boon to predators and exploiters than it is to the cooperative community.  Who knows, if the GNU software wasn&#8217;t licensed under GPL, perhaps Microsoft would have started using it as the basis for Windows in the late &#8217;80s or early &#8217;90s?</p>
<p>The article <a href="http://www.linuxjournal.com/article/5935">Why I Don&#8217;t Use the GPL</a> asks the question &#8220;what harm is really done [if a company uses non-copyleft source code] in their product?&#8221;  The author concludes that there isn&#8217;t any harm worth considering (&#8220;The open-source project still exists.&#8221;), and that there would be benefits to the community-at-large if proprietary software contained larger fractions of open-source code.  But in the end, I think that this is a naive analysis.  Perhaps it would be accurate if the biggest software companies were what we now consider mid-size, or if they were less likely to look for opportunities to gain advantage exploitatively.</p>
<p>This concludes in <a href="http://gleneivey.wordpress.com/2010/03/12/weakening-copyright-is-weakening-free-software-conclusion/">Part 3</a>, with a discussion of the different types of Open Source licensing, and what the open-source world might look like in the absence of copyright law.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/31/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=31&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2009/11/08/weakening-copyright-is-weakening-free-software-part-2-copyleft-embraceextend/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Enabling and Extending MediaWiki External Images (for Amazon Ad Links)</title>
		<link>http://gleneivey.wordpress.com/2009/11/04/enabling-and-extending-mediawiki-external-images-for-amazon-ad-links/</link>
		<comments>http://gleneivey.wordpress.com/2009/11/04/enabling-and-extending-mediawiki-external-images-for-amazon-ad-links/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 07:33:36 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=28</guid>
		<description><![CDATA[I&#8217;m building a web application, which I&#8217;m hoping will support itself through advertising. I&#8217;m using planning to use both Google AdSense and Amazon Associates (both links and widgets). Separately, I decided that the most convenient way to serve the &#8220;static&#8221; help pages, documentation, etc. for my application was to run a separate wiki in parallel [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=28&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m building a web application, which I&#8217;m hoping will support itself through advertising.  I&#8217;m using planning to use both Google AdSense and Amazon Associates (both links and widgets).  Separately, I decided that the most convenient way to serve the &#8220;static&#8221; help pages, documentation, etc. for my application was to run a separate wiki in parallel to it, and link from my web app into the wiki using custom page themes (I picked <a href="http://www.mediawiki.org/">MediaWiki</a>).  And finally, it occurred to me that some of my help pages are basically introductions to concepts or technology that (Ah-ha!) people might want to read more about in books.  Which I should suggest to them&#8230;.</p>
<p>So, that&#8217;s the chain of thinking that led me to the point, the other day, when I was trying to add Amazon text-link ads to text I was writing in MediaWiki.  And it turned out to be far trickier than I ever would have guessed.</p>
<p>The HTML that Amazon generates for you to use for a text-link advertisement contains the markup for a link <em>and</em> for the inclusion of a single-pixel image.  The link is displayed to the user and how they go from seeing the ad to Amazon&#8217;s web site, and the image is used by Amazon&#8217;s analytics for impression counting.  Because I wanted to embed these ads into a wiki page, I had to convert the HTML generated by Amazon into MediaWiki wiki markup.  For example, the following is the HTML for a text advertisement generated by Amazon (spacing modified for clarity):</p>
<pre>&lt;a
  href="http://www.amazon.com/gp/product/0132350882?ie=UTF8&amp;tag=wontology-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0132350882"&gt;
    Clean Code: A Handbook of Agile Software Craftsmanship
&lt;/a&gt;
&lt;img src="http://www.assoc-amazon.com/e/ir?t=wontology-20&amp;l=as2&amp;o=1&amp;a=0132350882"
  width="1" height="1" border="0" alt=""
  style="border:none !important; margin:0px !important;" /&gt;
</pre>
<p>The first tag is the anchor creating the link, and the second causes the browser to fetch the invisible image from Amazon&#8217;s servers any time a page containing the link is displayed.  The ad is rewritten in wiki markup as:</p>
<pre>[href="http://www.amazon.com/gp/product/0132350882?ie=UTF8&amp;tag=wontology-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0132350882
  Clean Code: A Handbook of Agile Software Craftsmanship]

http://www.assoc-amazon.com/e/ir?t=wontology-20&#038;l=as2&#038;o=1&#038;a=0132350882
</pre>
<p>The URL in brackets is rendered using the text following it in the brackets.  A bare URL that points to a web page would be displayed using the text of the URL itself as a link, but bare URLs for images are handled differently.  By default, MediaWiki requires images that are to be displayed within its pages to first be uploaded to the wiki server, and then incorporated in pages using wiki markup like [[File: ...]] or [[Image: ...]].  However, copying the single-pixel image from Amazon&#8217;s servers and uploading it to the wiki would defeat the purpose.  The user isn&#8217;t supposed to <em>see</em> the image, the important part is that the image be fetched by a user&#8217;s browser <em>every time</em> the page containing the image is shown.  So, MediaWiki must embed the image into the wiki page with a URL that points to a server other than itself.  The MediaWiki documentation refers to this as an &#8220;external image.&#8221;</p>
<p>When MediaWiki is installed external images are disabled by default.  Turning support for them on is accomplished, like most other MediaWiki customizations, by modifying the <code>LocalSettings.php</code> source file.  There are two settings that can be added to enable external images in a MediaWiki installation, <a href="http://www.mediawiki.org/wiki/Manual:$wgAllowExternalImages"><code>$wgAllowExternalImages</code></a> and <a href="http://www.mediawiki.org/wiki/Manual:$wgAllowExternalImagesFrom"><code>$wgAllowExternalImagesFrom</code></a>.  The former is simply set to <code>true</code> to enable inline images fetched from any external server, while the latter can be initialized with an array listing the domains from which external image fetches should be permitted.  (The preceding links are to the respective MediaWiki manual pages.)</p>
<p>So, I modified my MediaWiki server&#8217;s configuration, put my modified ad link into my text, and instead of my pages containing an invisible single-pixel image following each ad link, they displayed the full text of the image&#8217;s URL.  Hmmmm&#8230;.</p>
<p>For a while I was puzzled, but eventually figured out that my problem wasn&#8217;t that I hadn&#8217;t enabled external images correctly, it was that MediaWiki couldn&#8217;t identify Amazon&#8217;s URL as pointing to an image.  When MediaWiki parses the wiki text of a page, it distinguishes image URLs from page URLs based on the presence of a file name extension matching one of the well-known image formats.  Amazon&#8217;s image link has no extension, and since MediaWiki doesn&#8217;t actually fetch from the link, it doesn&#8217;t receive the MIME type of the image.  It therefore assumes that the URL points to an external web page, and presents it accordingly.</p>
<p>The code that checks this is located in the file <code>includes/parser/Parser.php</code>, and looks like:</p>
<pre>    function maybeMakeExternalImage( $url ) {
        ##snip##
        if ( $this-&gt;mOptions-&gt;getAllowExternalImages()
             || ( $imagesexception &amp;&amp; $imagematch ) ) {
            if ( preg_match( self::EXT_IMAGE_REGEX, $url ) ) {
                # Image found
                $text = $sk-&gt;makeExternalImage( $url );
            }
        }
        ##snip##
</pre>
<p>The set of URLs that are identified as pointing to images is determined by the regular expression <code>EXT_IMAGE_REGEX</code>, defined earlier in the same source file.  Modifying the regular expression to identify the Amazon image URLs would have been prohibitively complex&mdash;the &#8220;or&#8221; terms required to identify a host name as an alternative to a file name extension would have more than tripled the length of the expression.  Instead, I decided to simply modify the detection code, like this:</p>
<pre>    function maybeMakeExternalImage( $url ) {
        ##snip##
        if ( $this-&gt;mOptions-&gt;getAllowExternalImages()
             || ( $imagesexception &amp;&amp; $imagematch ) ) {
            if ( preg_match( self::EXT_IMAGE_REGEX, $url ) ||
                 preg_match( "/assoc-amazon\.com/", $url ) ) {
                # Image found
                $text = $sk-&gt;makeExternalImage( $url );
            }
        }
        ##snip##
</pre>
<p>The regular expression I actually use also checks for my Amazon advertiser ID, and perhaps is too specific.  If I were going to create a change that could be submitted to the MediaWiki project based on this fix, I&#8217;d create a new configuration variable that would contain the regular expression to be used, so that it could be set by wiki site administrators from <code>LocalSettings.php</code> without having to hack a source file.</p>
<p>So, if you&#8217;ve been having problems getting external images to work in your MediaWiki installation, whether they&#8217;re ads or not, this might be the fix you need.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=28&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2009/11/04/enabling-and-extending-mediawiki-external-images-for-amazon-ad-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Weakening Copyright is Weakening Free Software (Part 1, Background)</title>
		<link>http://gleneivey.wordpress.com/2009/11/03/weakening-copyright-is-weakening-free-software-part-1-background/</link>
		<comments>http://gleneivey.wordpress.com/2009/11/03/weakening-copyright-is-weakening-free-software-part-1-background/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 07:50:09 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Copyright]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[Opinion]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=24</guid>
		<description><![CDATA[This is going to be a defense of copyright law, on the grounds that it is the primary enabler of the open-source software ecosystem. I actually believe that there are lots of things wrong with the current state of copyright law, that most recent &#8220;reforms&#8221; have made things worse, and that the DMCA is a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=24&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is going to be a defense of copyright law, on the grounds that it is the primary enabler of the open-source software ecosystem.  I actually believe that there are <em>lots</em> of things wrong with the current state of copyright law, that most recent &#8220;reforms&#8221; have made things worse, and that the <a href="http://en.wikipedia.org/wiki/DMCA">DMCA</a> is a disaster. However, efforts to push back copyright protections, especially by technically minded people and the &#8220;information wants to be free&#8221; crowd, are misdirected and could well produce effects against their interests.</p>
<h3>Copyright In Brief</h3>
<h4>What It Is</h4>
<p>First, a quick review: &#8220;copyright&#8221; is the legal basis allowing the author/creator of a &#8220;work&#8221; to control and limit the creation of copies of that work.  Copyright pertains to lots of things (writing, music, computer software, video, art, etc.), but protects only the <em>form</em> of those things and not the <em>ideas</em> that they contain.</p>
<p>For example, you and I could both sit down right now and write physics text books.  Assuming we both did a good job, the ideas communicated by the two books would be very similar or identical.  But we&#8217;d almost certainly have created a different presentation and used different words, and both our books would be protected by copyright.  Other people couldn&#8217;t copy your book without your permission, but I could make copies of mine because I created it myself and didn&#8217;t copy you, even though both books describe the same things.  (Technical ideas, rather than particular presentations of ideas, are protected by <em>patents</em>, a completely separate <a href="http://en.wikipedia.org/wiki/Patent">field of law</a> complementary to, but not connected to, copyright law.)</p>
<p>Though there are procedures and reasons to register your authorship of a work, it isn&#8217;t actually necessary in the U.S.  Your right to control the copying of your work exists simply because you created it.  There are limits to copyright.  First, it eventually expires.  Second, there are limited types of copying and excerpting described as &#8220;fair use&#8221; that cannot be prevented by asserting copyright, such as brief quotations or use of portions for the purpose of satire.</p>
<h4>Why We Have Copyright Law</h4>
<p>Copyright is so ubiquitous most people don&#8217;t think about why it exists or why it is enforced by the government.  But there actually are reasons.  One family of reasons are basically moral/ethical.  People argue that people automatically own what they create, even if what&#8217;s created is more idea than object, and that making an unauthorized copy of something is essentially theft.  And just like other thefts, it is the government&#8217;s place to establish the precise definition of the crime and to protect each of us from everyone else.  This is a fine argument as far as it goes, but other people argue that it isn&#8217;t reasonable to equate taking a loaf of bread form someone with making a loaf of bread from someone else&#8217;s recipe without their permission.</p>
<p>Another set of arguments is more pragmatic, and looks at the question from the perspective of how the existence of copyright for an individual contributes to the public good as a whole.  In this line of reasoning, by protecting an author&#8217;s ability to limit and control the number of copies of their work, it makes it easier for the author to make a living, and hopefully authors will therefore (on average, across society) produce more works than they would otherwise.  Counter arguments here primarily question the degree to which creative works would actually fail to be created in the absence of copyright, and whether the restrictions on distribution of information that copyright creates damage society more than the actual benefits from enforcing it.</p>
<h3>Copyright&#8217;s Part in Free Software</h3>
<p>A computer program is <a href="http://en.wikipedia.org/wiki/Free_software">Free Software</a> if it is (1) publicly available for use <em>and modification</em>, and (2) people modifying it are <em>obligated</em> to also make their changes publicly available.  Making software publicly available is something the author would do, and isn&#8217;t at all difficult today. Imposing the obligation to redistribute on people who author modifications to the software was the unique contribution that <a href="http://en.wikipedia.org/wiki/Richard_Stallman">Richard Stallman</a> when he coined the phrase Free Software and started writing and distributing his own Free Software as part of the <a href="http://en.wikipedia.org/wiki/GNU_Project">GNU Project</a>.</p>
<p>The obligation of modification authors to redistribute their work (and under the same terms as the original) is accomplished using copyright law.  Because the original software is copyrighted by its original author (under U.S. law, whether the author wants it to be or not), the author must explicitly grant others the right to copy that software through a license before they can use it.  Whether or not something falls under the name Free Software depends on the terms of that license.</p>
<p>Stallman created the <a href="http://en.wikipedia.org/wiki/GPL">GNU General Public License</a> (the GPL) and uses it for the software he writes.  The GPL obligates people who are modifying their copies to in turn publicly distribute and license their modifications under the same license as the original.  He refers to this license as a <em>copyleft</em>, because while copyright law allows authors to restrict access to their work, the GPL mandates that the authors of modifications share their work.</p>
<p>Not all Free Software licenses are copyleft licenses.  As long as a license gives people the freedom to redistribute copies of software (modified or not), it is a Free license.  It is only if the license <em>mandates</em> distribution of modifications that it is a copy-left license.</p>
<p>Next the is <a href="http://gleneivey.wordpress.com/2009/11/08/weakening-copyright-is-weakening-free-software-part-2-copyleft-embraceextend/">Part 2</a> for some arguments against copyleft specifically, and a description of the &#8220;Embrace, Extend, and Extinguish&#8221; product strategy and <a href="http://gleneivey.wordpress.com/2010/03/12/weakening-copyright-is-weakening-free-software-conclusion/">Part 3</a> addresses different licenses and summarizes.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/24/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/24/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/24/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=24&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2009/11/03/weakening-copyright-is-weakening-free-software-part-1-background/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Obligatory Meta Post</title>
		<link>http://gleneivey.wordpress.com/2009/11/02/obligatory-meta-post/</link>
		<comments>http://gleneivey.wordpress.com/2009/11/02/obligatory-meta-post/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 07:10:23 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Posts about posts]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=20</guid>
		<description><![CDATA[OK, I was hoping to wait longer for this, but here it is: the Obligatory NaBloPoMo Meta Post! Hi, I&#8217;m Glen, this is November 2009, and I&#8217;ve committed to the &#8220;National Blog Post Month&#8221; (nablopomo.com) and am going to write 30 blog posts in the 30 days this month. I&#8217;d planned to write a post [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=20&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>OK, I was hoping to wait longer for this, but here it is:  the Obligatory NaBloPoMo Meta Post!</p>
<p>Hi, I&#8217;m Glen, this is November 2009, and I&#8217;ve committed to the &#8220;National Blog Post Month&#8221; (nablopomo.com) and am going to write 30 blog posts in the 30 days this month.  I&#8217;d planned to write a post about writing posts after I was a few more days in.  When I got up this morning, I was planning to write about copyright, Free Software, and information &#8220;wanting to be free.&#8221;  But, it&#8217;s gotten late, and I don&#8217;t have time to do that justice tonight.  So, instead, a quick introduction to me, why I&#8217;m doing this, and what you migth find here in the next few weeks.</p>
<p>I&#8217;m a programmer.  Actually, a lot more things than a programmer.  But you know the saying &#8220;when the only tool you have is a hammer, all your problems look like nails&#8221;?  Well, when I bump into a problem, my first impulse it to try to figure out how to solve it with a new piece of software.  So:  I&#8217;m a programmer, or at least an engineer.</p>
<p>I&#8217;m a bit over 41, married, have three cats and no kids.  I&#8217;ve been in computers professionally since I left college (note that I didn&#8217;t say &#8220;graduated&#8221;), first in chip design but mostly in software.  If my wandering career is somehow of interest, you can find the details <a href="http://www.linkedin.com/in/gleneivey">on LinkedIn</a>.  Up until this past February I&#8217;ve always been a regular employee&#8211;occasionally I&#8217;ve done some contracting on the side, but the most &#8220;entrepreneurial&#8221; I&#8217;ve been is working for start-up companies.  But early this year, I struck out on my own:  I resigned from my full-time job, and I&#8217;ve been developing a web application since.</p>
<p>Which brings us to the double-edged sword of this whole blog-post-a-day thing.  On the one hand, there are probably &#8220;better&#8221; things I could be doing with the time I&#8217;m writing this.  On the other, there are a number of things I&#8217;ve bumped into during my work that I&#8217;ve &#8220;been meaning to&#8221; write up.  And I think I need some structure.  It&#8217;s been almost nine months that I&#8217;ve been working on my idea of The Next Medium-Sized Thing, and I still don&#8217;t have it to a point where I think it would be useful to others (although I am getting close).  So I&#8217;m really hoping that getting one of these out each day will restore a missing sense of completing short-term things.</p>
<p>I&#8217;m probably also doing it a tiny bit out of envy for all of the people doing National Novel Writing Month.  Now that&#8217;s something that <em>definitely</em> isn&#8217;t justifiable for someone self-&#8221;employed&#8221; and living out of savings.  But it sure would be fun&#8230;.</p>
<p>But, I think this will be fun too.  There are going to be a fair number of technical/programming articles, stuff on copyright and patents and software (oh, my!), and almost certainly more thoughts on space travel.  Probably also some stuff about the way the world works (systems thinking, emergence, process control, sense making, etc.), education, or maybe sustainability (Permaculture, anyone?).  Perhaps a personal anecdote or two.  And if I absolutely can&#8217;t resit, maybe a touch of politics.  So, if some of that sounds like it might be interesting to you, then come on back later in the month.  If not, well, at least fair warning has been given.</p>
<p>And that brings me happily to the end of Day Two.  (Oh, by the way, the timezone in WordPress was miss-set when I posted yesterday, it was actually 11:45pm here.  But, I don&#8217;t plan to hold myself to a midnight cut-off.  All else being equal, I&#8217;m both a procrastinator and a night-owl, and as far as I&#8217;m concerned the blog-posting day ends when I go to sleep, regardless of what the clock says.)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/20/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=20&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2009/11/02/obligatory-meta-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
		<item>
		<title>Loading &#8220;Seed&#8221; Data in Rails</title>
		<link>http://gleneivey.wordpress.com/2009/11/02/loading-seed-data-in-rails/</link>
		<comments>http://gleneivey.wordpress.com/2009/11/02/loading-seed-data-in-rails/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 07:45:14 +0000</pubDate>
		<dc:creator>gleneivey</dc:creator>
				<category><![CDATA[Ruby-on-Rails]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://gleneivey.wordpress.com/?p=14</guid>
		<description><![CDATA[&#8220;Seed data&#8221; is information an application needs to exist before it can be run. This isn&#8217;t necessarily the name I&#8217;d have chosen, but the web searches I did on the wahy to my solution seemed to use it predominantly. In particular, in a Ruby-on-Rails web application that sits on top of a relational database, the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=14&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>&#8220;Seed data&#8221; is information an application needs to exist before it can be run.  This isn&#8217;t necessarily the name I&#8217;d have chosen, but the web searches I did on the wahy to my solution seemed to use it predominantly.  In particular, in a <a href="http://rubyonrails.org">Ruby-on-Rails</a> web application that sits on top of a relational database, the seed data is database records that need to be loaded into the database, likely during installation.</p>
<p>In building <a href="http://wontomedia.rubyforge.org/">my Rails application</a>, I needed to pre-load data into the same tables that it uses to store user-created objects in operation.  The data had to be pre-loaded, because there had to be special records that the application could have hard-coded references to, and I didn&#8217;t want to risk re-creating them wrong by hand after database wipes, or on new installations.  Here I describe the thrashing around I went through, and the solution that I finally came up with.  Which I think are pretty good.  But since I originally implemented it, an alternative has started to be build into Rails itself.  This is described in places like <a href="http://afreshcup.com/2009/05/11/seed-data-in-rails-3/">Seed Data in Rails 3</a>, <a href="http://railscasts.com/episodes/179-seed-data">Railscasts #179: Seed Data</a>, and <a href="http://www.google.com/search?q=rails+seed+data+%2B%222.3.4%22&amp;ie=utf-8&amp;oe=utf-8&amp;aq=t&amp;rls=com.ubuntu:en-US:unofficial&amp;client=firefox-a">Google&#8217;s results for the release of Rails v2.3.4</a>.</p>
<p>Prior to v2.3.4, most Rails applications that needed seed data used static inserts in a database migration file to put the database records in place.  This approach has a number of problems.  First, the preferred Rails way for loading a database in a new installation is by loading the <code>db/schema.rb</code> file, instead of by loading all of an applications historic migration files.  This is not only more efficient, but often as a Rails application evolves its older migrations can no longer be run (they have become incompatible with the current application source).  Encapsulating seed data in migrations requires that new installations be initialized by re-running the migrations, which may eventually stop being possible.  In addition, if the database schema is updated after the seed data creation statements are created (a virtual certainty), the seed data will have to be updated, either by editing the older migrations (a version-control nightmare) or by creating migrations that alter the seed data (effectively scattering the data across multiple migration files, a significant barrier to comprehension if anyone ever needs to read the data).</p>
<p>Another problem with using migrations is that, unlike Rails mechanism for loading <em>fixture</em> data, there is no support for creating IDs that create associations between database records in different tables (database table foreign keys).  Given that my seed data needed to go into two tables, with records from one referring to records in the other, not having fixture-like automatic generation of association IDs would have made maintaining my seed data very difficult.</p>
<p>So, what I really wanted was something that worked without using migrations, and with ID creation/mapping like fixtures.  Which led me to find a fixture- and rake-based solution posted in a couple of different places on the web.  The code I wrote based on their ideas starts with a couple of rake tasks:</p>
<pre>namespace :db do
  desc "Load YAML seed data from db/fixtures"
  task :seed =&gt; :environment do
    load_all_YAML_globbed_from(
      File.join( RAILS_ROOT, 'db', 'fixtures', '**', '*.yml' ))
  end

  desc "This drops the db, builds the db, and seeds the data."
  task :reseed =&gt; [:environment, 'db:reset', 'db:seed']
end
</pre>
<p>I keep the do-it method and its dependencies along with these tasks in <code>lib/tasks/db.rake</code>.  The &#8220;seed&#8221; task will load al of the YAML files located in <code>db/fixtures</code>.  In the common case where there is a uniqueness constraint on one or more database columns that are populated from the fixture data, it won&#8217;t be possible to execute &#8220;seed&#8221; more than once on the same database.  Therefore, the &#8220;reseed&#8221; task is provided to empty the database, rebuild its schema from the current, and then load the seed data.</p>
<p>The rest of the code to implement this task isn&#8217;t that complicated.  It builds on Rails&#8217; built-in database connection and fixture loading:</p>
<pre>require 'active_record'
require 'active_record/fixtures'

def load_all_YAML_globbed_from(pattern)
  ensure_ActiveRecord_available
  Dir.glob(pattern).each do |path|
    load_YAML_from path
  end
end

def ensure_ActiveRecord_available
  unless ActiveRecord::Base.connected?
    ActiveRecord::Base.establish_connection(
      ActiveRecord::Base.configurations[RAILS_ENV] )
  end
end

def load_YAML_from(path)
  path =~ %r%([^/_]+)\.yml$%
  table = $1
  path.sub!(/\.yml$/, "")

  begin
    f = Fixtures.new( ActiveRecord::Base.connection, table, nil, path )
    f.insert_fixtures
  rescue ActiveRecord::StatementInvalid
    # must have already loaded this data
  end
end
</pre>
<p><code>ensure_ActiveRecord_available</code> makes sure that the current execution context has a valid database connection, and that it matches thee current Rails environment (e.g., <code>production</code>, <code>development</code>, or <code>test</code>).  The biggest difference between this code and the portions of Rails that are responsible for loading YAML test fixtures are the first three lines of <code>load_YAML_from</code>.  Rails uses the entire base name of the YAML file (that is, everything but the ending file extension &#8220;<code>.yml</code>&#8220;) as the name of the database table to load.  Rails also loads fixtures only from a single directory (not recursively from an entire directory tree, as the <code>File.join()</code> in the &#8220;seed&#8221; task does).  This has the cumulative effect of requiring all of the data that is to be loaded into the same table to come from a single file.  Allowing YAML files to be distributed between multiple files, and for multiple files to load into the same database table, allows large sets of seed data to be broken up across multiple files.</p>
<p>Having a Rake task that loads seed data solves the problem for installing new application instances and for interactive development.  Unfortunately, Rails&#8217; built-in machinery for setting up the database used for automated tests knows how to clone the schema from the development database, but not its content.  And if an application really needs its seed data to operate, then its unit tests shouldn&#8217;t pass if the database is empty.</p>
<p>To load the seed data into the <code>test</code> database, a mechanism similar to the above is necessary when running unit tests, and the preferred way to hook into this is using the standard <code>test_helper</code> file.  For cleanliness, I chose to put most of the seed-related code outside the test helper and require it:</p>
<p><code>test/test_helper.rb</code>:</p>
<pre>class ActiveSupport::TestCase
  require File.join( File.dirname(__FILE__), 'seed_helper' )
  setup :load_app_seed_data
end
</pre>
<p><code>test/seed_helper.rb</code>:</p>
<pre>require 'active_record'
require 'active_record/fixtures'

# define method in any context where 'require'ed; no fixed namespace/class
def load_app_seed_data
  ensure_connection

  Dir.glob(File.join( File.dirname(__FILE__), "..", "db", "fixtures",
                      "**", "*.yml" )).each do |path|
    path =~ %r%([^/_]+)\.yml$%
    table = $1
    path.sub!(/\.yml$/, "")

    begin
      f = Fixtures.new( @helper_db_connection, table, nil, path )
      f.insert_fixtures
    rescue ActiveRecord::StatementInvalid
      # must have already loaded this data
    end
  end
end

def ensure_connection
  unless ActiveRecord::Base.connected?
    ActiveRecord::Base.establish_connection(
      ActiveRecord::Base.configurations['test'])
  end
end
</pre>
<p>This code is essentially the same as the content of the Rake task (and, now that I look at it again, perhaps with a bit of refactoring I could require it from <code>db.rake</code> instead of duplicating, hmmm&#8230;.).  The key here is the <code>setup</code> call in <code>test_helper.rb</code>.  This connects the method that loads the seed data to the setup-phase callback Rails (<code>Test::Unit</code>) provides in the flow of running unit tests.</p>
<p>Note the <code>rescue</code> that catches <code>StatementInvalid</code> exceptions.  This is present/duplicated in the Rake task above, but is most important here.  It prevents attempts to reload the same fixtures from causing a test run to fail in the event that the callback is repeated.</p>
<p>Alas, a Rails project is likely to use additional test frameworks beyond the built-in <code>Test::Unit</code> and its derivatives.  For my project, I use <a href="http://wiki.github.com/aslakhellesoy/cucumber">Cucumber</a>, a Ruby automated functional test framework, and <a href="http://github.com/relevance/blue-ridge">Blue Ridge</a>, a Rails plugin for JavaScript testing.  In order to support running tests through these frameworks via Rake individually, they also need hooks to load the seed data into the <code>test</code> database if it hasn&#8217;t been already.  The code for these two frameworks are given as examples, both for themselves and to guide integration into other frameworks.</p>
<p>For Blue Ridge, I created a locally-modified version of their rake tasks in <code>lib/tasks/javascript_testing_tasks.rake</code>:</p>
<pre>require File.join( RAILS_ROOT, 'test', 'seed_helper' )

begin   # don't force Blue Ridge dependency on non-developers
  namespace :test do
    task :javascripts =&gt; [ :environment ] do
      prepare_and_load_database

      Dir.chdir("#{RAILS_ROOT}/test/javascript") do
        begin
          load_app_seed_data
          # rest of the rake task was here
        ensure
          # shutdown/cleanup here
        end
    end
  end

  def prepare_and_load_database
    # ensure that we start with a clean database
    Rake::Task["db:test:prepare"].invoke
    # plus our test "fixture" data
    Rake::Task["db:test_fixtures"].invoke
  end

  def cleanup_database
    # ensure that we *leave* a clean database, too
    Rake::Task["db:test:prepare"].invoke
  end

rescue LoadError
  puts "WARNING: Missing development dependency.  'Blue Ridge' or a dependency is not available."
end
</pre>
<p>At this point, there isn&#8217;t much to say about the call to <code>load_app_seed_data</code>.  However, the other two <code>*_database</code> calls are new.  These are present not because the seed data loading needs them, but because I wanted to have the same <em>test</em> fixture data present for reference by my JavaScript tests as I use in my Ruby/Rails unit tests.</p>
<p>For Cucumber, the hooks to load seed data are placed into a standard extension file that Cucumber supports, <code>features/support/local.rb</code>.  In fact, the entirety of my project&#8217;s <code>local.rb</code> are the two lines:</p>
<pre>require File.join( File.dirname(__FILE__), 'seed_helper' )
load_app_seed_data
</pre>
<p>For Cucumber, I use special <a href="http://wiki.github.com/aslakhellesoy/cucumber/step-definitions">steps</a> in each <a href="http://wiki.github.com/aslakhellesoy/cucumber/feature-introduction">scenario</a> to create any non-seed data needed for the test, so there is no code to load the test fixture data.</p>
<p>So, even with Rails incorporating an &#8220;official&#8221; seed-data mechanism for Rails 3, you may find this code useful if you too want to use multiple YAML files per database table, or to have your seed data available to tests running in add-on frameworks.  Please comment with any questions.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gleneivey.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gleneivey.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gleneivey.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gleneivey.wordpress.com&amp;blog=2294082&amp;post=14&amp;subd=gleneivey&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://gleneivey.wordpress.com/2009/11/02/loading-seed-data-in-rails/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/da1b97f241692b8260fededf15c28b6b?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">gleneivey</media:title>
		</media:content>
	</item>
	</channel>
</rss>
