<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns="http://purl.org/rss/1.0/">
  <channel rdf:about="http://times.usefulinc.com/tagsoftware">
    <title>Edd Dumbill's Weblog: 'software' articles</title>
    <description>Articles tagged as 'software' from Edd Dumbill, technology writer and free software hacker.</description>
    <link>http://times.usefulinc.com/tagsoftware</link>
    <dc:date>2008-01-12T13:49:42Z</dc:date>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://times.usefulinc.com/2008/01/12-rspec-stories"/>
        <rdf:li rdf:resource="http://times.usefulinc.com/2007/06/01-expectnation"/>
        <rdf:li rdf:resource="http://times.usefulinc.com/2006/11/24-searchxml"/>
        <rdf:li rdf:resource="http://times.usefulinc.com/2005/11/22-opinions"/>
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="http://times.usefulinc.com/2008/01/12-rspec-stories">
    <title>Telling stories with RSpec</title>
    <link>http://times.usefulinc.com/2008/01/12-rspec-stories</link>
    <description>Using RSpec's Story runner to describe integration testing for Rails applications.</description>
    <dc:subject>software</dc:subject>
    <dc:subject>rails</dc:subject>
    <dc:subject>ruby</dc:subject>
    <dc:subject>agile</dc:subject>
    <dc:creator>Edd Dumbill</dc:creator>
    <dc:date>2008-01-12T13:14:43Z</dc:date>
    <foaf:maker>
      <foaf:Person>
        <foaf:mbox rdf:resource="mailto:edd@usefulinc.com"/>
      </foaf:Person>
    </foaf:maker>
    <content:encoded>         &lt;p&gt;For a while now I've been writing &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; specifications to test &lt;a href="http://expectnation.com/"&gt;Expectnation&lt;/a&gt;, rather than &amp;quot;traditional&amp;quot; Rails unit tests. Although I don't completely get the Behaviour Driven Development hype around RSpec, I do find that it helps in writing more literate and maintainable test suites.&lt;/p&gt;                 &lt;p&gt;Until very recently, however, &lt;a href="http://rspec.info/documentation/rails/index.html"&gt;RSpec for Rails&lt;/a&gt; had no decent answer to Rails' &lt;a href="http://www.oreillynet.com/pub/a/ruby/2008/01/02/cookin-with-ruby-on-rails---integration-tests.html"&gt;integration tests&lt;/a&gt;. Integration tests enable the testing of compete scenarios, as opposed to the specific testing of methods or single HTTP operations that unit and functional testing provide.&lt;/p&gt;  &lt;p&gt;For instance, our integration test suite for Expectnation tests things such as &amp;quot;a user tries to submit a proposal, is redirected to the account sign up page, signs up, and then is redirected to the proposal submission page&amp;quot;. This involves multiple steps, and the whole suite of tests necessitates a lot of reuse.&lt;/p&gt;                 &lt;p&gt;The need for reuse resulted in trying to construct a &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language"&gt;DSL&lt;/a&gt;-like set of methods for each step, such as &amp;quot;user logs in with email X and password Y&amp;quot;. It has gotten a bit tangled, especially when looking at test failures to see what's really gone wrong.&lt;/p&gt;      &lt;div style="text-align: center"&gt;&lt;img width="160" height="240" src="/asset/name/41/2098453701_9a8d1e9f19_m.jpg" alt="Tangled wires" /&gt;&lt;br /&gt;    &lt;br /&gt;   &lt;em&gt;After a while, unravelling the test suite starts to feel like unpacking Christmas lights.  (Photo: &lt;a href="http://flickr.com/photos/leecullivan/2098453701/"&gt;shoothead&lt;/a&gt;)&lt;/em&gt; &lt;/div&gt;                        &lt;h3&gt;RSpec Story Framework&lt;/h3&gt;           &lt;p&gt;My problems with integration tests made the Story Framework, newly available in RSpec 1.1, look very interesting. Based around plain text descriptions of application behaviour, it lets you write integration tests with good reuse and good diagnostic reporting.&lt;/p&gt;                 &lt;p&gt;For example, here's a story I wrote to check the login process.&lt;/p&gt;             &lt;p&gt;Story: login as an existing user&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As an unauthenticated user&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; I want to log in to Expectnation&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; So I can see my account details&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Scenario: login details are correct&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Given an event provider&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And my test@example.org account&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; When I log in with email test@example.org and password foofoo&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Then I will be logged in&lt;br /&gt;       &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; And I will be shown the account page&lt;/p&gt;            &lt;p&gt;The words such as &amp;quot;Given&amp;quot;, &amp;quot;When&amp;quot; and &amp;quot;Then&amp;quot; are cues to the story runner to execute some code. Behind the story sits a collection of steps. Here's a couple of steps from this test:&lt;/p&gt;           &lt;p&gt;&amp;nbsp; Given &amp;quot;my $email account&amp;quot; do |email|&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp; @user = find_or_create_user_by_email({:email =&amp;gt; email,&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :password =&amp;gt; 'foofoo',&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :password_confirmation =&amp;gt; 'foofoo'})&lt;br /&gt;      &amp;nbsp; end&lt;/p&gt;          &lt;p&gt;&amp;nbsp; When &amp;quot;I log in with email $email and&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; password $password&amp;quot; do |email, password|&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp; post '/user/account/authenticate',&lt;br /&gt;      &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :user =&amp;gt; {:email =&amp;gt; email, :password =&amp;gt; password}&lt;br /&gt;      &amp;nbsp; end&lt;/p&gt;          &lt;p&gt;Notice how a clever bit of string matching allows you to pass parameters from the story prose. &lt;br /&gt;      &lt;/p&gt;           &lt;p&gt;With a small bit of bolting together, the prose stories are then run as code and the tests executed. One nice touch is that if you write a story which doesn't yet have code behind it, it is marked not as a pass or fail, but as pending, which means you can sit down and write all your stories and then get to coding the steps later. This beats writing empty tests which transparently pass.&lt;/p&gt;           &lt;p&gt;To conclude, the RSpec Story Framework offers these advantages over Rails' integration tests:&lt;/p&gt;           &lt;ul&gt;      &lt;li&gt;Text-only stories makes it very easy to write and understand tests&lt;/li&gt;           &lt;li&gt;The construction of steps for each line makes it easy and maintainable to construct reusable components for the tests&lt;/li&gt;      &lt;/ul&gt;      &lt;h3&gt;Further reading&lt;/h3&gt;      &lt;ul&gt;      &lt;li&gt;&lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; web site&lt;/li&gt;           &lt;li&gt;&lt;a href="http://jbehave.org/"&gt;JBehave&lt;/a&gt; for Java, of which RSpec's Story Framework is a port&lt;/li&gt;           &lt;li&gt;&lt;a href="http://behaviour-driven.org/"&gt;Behaviour-Driven Development&lt;/a&gt;&lt;/li&gt;      &lt;/ul&gt;      &lt;p&gt;&lt;a href="http://times.usefulinc.com/2008/01/12-rspec-stories#disqus_thread"&gt;Join the conversation about this post&lt;/a&gt;&lt;/p&gt;</content:encoded>
  </item>
  <item rdf:about="http://times.usefulinc.com/2007/06/01-expectnation">
    <title>Launching Expectnation</title>
    <link>http://times.usefulinc.com/2007/06/01-expectnation</link>
    <description>For the last 18 months, I've been hard at work with Expectnation. Now it's live!</description>
    <dc:subject>software</dc:subject>
    <dc:subject>web</dc:subject>
    <dc:subject>expectnation</dc:subject>
    <dc:subject>conferences</dc:subject>
    <dc:creator>Edd Dumbill</dc:creator>
    <dc:date>2007-06-01T15:04:46Z</dc:date>
    <foaf:maker>
      <foaf:Person>
        <foaf:mbox rdf:resource="mailto:edd@usefulinc.com"/>
      </foaf:Person>
    </foaf:maker>
    <content:encoded> &lt;p&gt;I'm very pleased to announce the launch of &lt;a href="http://expectnation.com/"&gt;Expectnation&lt;/a&gt;, a web application for managing conferences.&lt;/p&gt; &lt;p style="float: right; margin-left: 15px"&gt;&lt;img width="218" height="46" src="http://times.usefulinc.com/asset/name/37/enation-logo.png" alt="Expectnation logo" /&gt;&lt;/p&gt; &lt;h3&gt;What does it do?&lt;/h3&gt; &lt;p&gt;Expectnation is intended to replace the ad-hoc collection of emails, spreadsheets, documents and hacks that hold together the organization of most conferences. The aim is to improve the quality and reliability of communication between the organizers, speakers and attendees.&lt;/p&gt; &lt;p&gt;But it doesn't stop there. What I'm really excited about is the chance to enhance the conference experience through the web. Expectnation is capable of managing the complete web site for a conference, which provides many opportunities for bringing the best of the social software world to augment events.&lt;/p&gt; &lt;p&gt;Our tagline is &amp;quot;build your conference into a community&amp;quot;, which underpins a key aim: to help organizers make events more relevant and useful to attendees, and to live on beyond the event itself. We do this in two ways: saving time, so you can spend it on improving your conference, and providing online tools to support community building.&lt;br /&gt; &lt;/p&gt; &lt;p&gt;Right now Expectnation is able to manage the proposal, review, scheduling and publication of presentations, along with the conference web site and smart emailing to speakers, reviewers and chairs. Over the next two months we'll be introducing our registration module, with optional online payments, and working on extending the social software features available for attendees.&lt;/p&gt; &lt;h3&gt;Take a look&amp;nbsp;&lt;/h3&gt; &lt;p&gt;I'm really excited about letting users get started with Expectnation, and seeing the uses it gets put to. We believe Expectnation will be just as handy for organizing events inside an organization as for traditional conferences.&lt;/p&gt; &lt;p&gt;So, if you organize, speak at, or attend conferences of any sort, please check out &lt;a href="http://expectnation.com/"&gt;Expectnation&lt;/a&gt; and recommend it to a conference organizer near you!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Related links&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://expectnation.com/public/content/website"&gt;Expectnation tour&lt;/a&gt; complete with screenshots &lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://times.usefulinc.com/tag/expectnation"&gt;Previous posts&lt;/a&gt; I've written about Expectnation&lt;/li&gt;&lt;li&gt;&lt;a href="http://2007.xtech.org/"&gt;XTech 2007&lt;/a&gt; was completely managed inside Expectnation&amp;nbsp;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a href="http://times.usefulinc.com/2007/06/01-expectnation#disqus_thread"&gt;Join the conversation about this post&lt;/a&gt;&lt;/p&gt;</content:encoded>
  </item>
  <item rdf:about="http://times.usefulinc.com/2006/11/24-searchxml">
    <title>New release of  XmlIndexer search server</title>
    <link>http://times.usefulinc.com/2006/11/24-searchxml</link>
    <description>A bug-fixed version of my Mono-based XML search server.</description>
    <dc:subject>software</dc:subject>
    <dc:subject>xml</dc:subject>
    <dc:subject>mono</dc:subject>
    <dc:creator>Edd Dumbill</dc:creator>
    <dc:date>2006-11-24T15:24:34Z</dc:date>
    <foaf:maker>
      <foaf:Person>
        <foaf:mbox rdf:resource="mailto:edd@usefulinc.com"/>
      </foaf:Person>
    </foaf:maker>
    <content:encoded>&lt;p&gt;About 18 months or so ago I &lt;a href="http://times.usefulinc.com/2005/02/27-xmlindexer"&gt;released the first version&lt;/a&gt; of XmlIndexer, a general purpose XML indexing web service based on Mono and &lt;a href="http://incubator.apache.org/lucene.net/"&gt;Lucene.Net&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I'm happy to announce now version 0.4 of this software which, thanks to improvements in Lucene.Net and &lt;a href="http://cvs.gnome.org/viewcvs/beagle/beagled/Lucene.Net/upstream-changes/"&gt;patches&lt;/a&gt; from the Beagle hackers, is a lot more stable. Previous versions had some nasty locking issues that could kill the server quite dead.&lt;/p&gt;&lt;p&gt;XmlIndexer is a simple indexer. Given a rulefile that maps XPaths to Lucene keys, it can be taught to index any XML file you should care to give it. I use it to provide search functionality to legacy applications, which then need only to expose their data as XML and call a few simple web services to perform a search.&lt;/p&gt;&lt;p&gt;Of related interest is the new Apache Incubator &lt;a href="http://incubator.apache.org/solr/features.html"&gt;Solr&lt;/a&gt; project, which provides a fancy search server based on Lucene, doing the same as my indexer, and much more.&lt;/p&gt;&lt;p&gt;XmlIndexer requires Lucene.Net version 1.9.1. For extra points, apply the locking &lt;a href="http://cvs.gnome.org/viewcvs/beagle/beagled/Lucene.Net/upstream-changes/"&gt;patches&lt;/a&gt; from Beagle to Lucene.Net before building. As a courtesy I include a Lucene.Net DLL I made this way in the download.&lt;/p&gt;&lt;p&gt;Download: &lt;a href="http://downloads.usefulinc.com/searchxml/searchxml-0.4.tar.gz"&gt;searchxml-0.4.tar.gz&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://times.usefulinc.com/2006/11/24-searchxml#disqus_thread"&gt;Join the conversation about this post&lt;/a&gt;&lt;/p&gt;</content:encoded>
  </item>
  <item rdf:about="http://times.usefulinc.com/2005/11/22-opinions">
    <title>Opinions and free software</title>
    <link>http://times.usefulinc.com/2005/11/22-opinions</link>
    <description>Taking an opinionated view to open source software may seem risky, but it pays off.</description>
    <dc:subject>software</dc:subject>
    <dc:creator>Edd Dumbill</dc:creator>
    <dc:date>2005-11-22T09:14:31Z</dc:date>
    <foaf:maker>
      <foaf:Person>
        <foaf:mbox rdf:resource="mailto:edd@usefulinc.com"/>
      </foaf:Person>
    </foaf:maker>
    <content:encoded>&lt;div&gt;
&lt;p&gt;Since
&lt;a href="http://www.oreillynet.com/pub/a/network/2005/08/30/ruby-rails-david-heinemeier-hansson.html"&gt;interviewing&lt;/a&gt;
the creator of &lt;a href="http://www.rubyonrails.org"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="http://loudthinking.org"&gt;David
Heinemeier Hansson&lt;/a&gt;, I've been thinking a
little more about what he calls "opinionated software."&lt;/p&gt;
&lt;p&gt;That handy little phrase seems to sum up what attracts me to a lot of
technology, at all levels.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What I like&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Free software--it's not really economics that drew me to free
software, but the principles and aims.  When you release or use free
software, you're exercising your right to free speech and adding your
voice to an argument.&lt;/p&gt;
&lt;p&gt;Desktop environments--&lt;a href="http://gnome.org/about/"&gt;GNOME 2.0&lt;/a&gt;:
The move from GNOME 1.0 to version 2.0 was highly opinionated (Mac
users, think OS 9 to OS X). Complexity of user interface was thrown
out in favour of sensible defaults.&lt;/p&gt;
&lt;p&gt;Web standards--CSS, RDF, XHTML: not only &lt;em&gt;is&lt;/em&gt; there a right way to do
things, but it turns out to be &lt;em&gt;better&lt;/em&gt; too!  I don't automatically
fall in love with everything that emerges from the W3C, but some
things are so obviously the right way it's impossible not to love
them--warts and all.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://muine.gooeylinux.org/"&gt;Muine&lt;/a&gt; music player--this player throws
out the paraphernalia of iTunes clones and gets you close to the
music.  Queue, play.  What I want to do.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.gnome.org/projects/epiphany/"&gt;Epiphany&lt;/a&gt; web browser--a
simple text bar does for bookmark lookup, search and URLs.  The
bookmarks work like del.icio.us tags.  Despite the lure of Firefox
extensions, simplicity and efficiency keeps me with Epiphany.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Make friends and enemies&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The thing about opinions is that people are inclined to disagree with
them. Opinions won't please everybody and, being opinionated, you will
never carry everybody with you.&lt;/p&gt;
&lt;p&gt;But opinions give you something with which to scythe through
indifference. In both my writing and software development work taking
a particular stance enables me to create interest, and gives direction
to my projects.  I tend to get bored easily, and if I'm bored, then my
readers and users will never make it.&lt;/p&gt;
&lt;p&gt;Being opinionated in software development is easier when there's a
strong leader, or it's a one-person project. It's more of a dilemma if
you're running a free software project with multiple contributors.&lt;/p&gt;
&lt;p&gt;Such projects need such contributions, but run a risk of losing focus
and style. I think that there we need to be brave again.  If being
opinionated means losing potential users, it also means losing
potential contributors.&lt;/p&gt;
&lt;p&gt;Opinions help in dealing with users, too.  It's obvious that the mere
act of listening to users isn't good enough.  They often won't say
what they mean, or their requests mask a deeper issue.  How often have
you given your boss exactly what he asked for, to find it wasn't what
he wanted?  A combination of reading-between-the-lines and having
opinions helps cut a way through the noise of user feedback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stirring the pot&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here are a few wishes for some free software projects that I want to
see succeed further, but which really need to get opinionated to be
effective.  These projects aren't failing, but they're not reaching
the potential I know is there.&lt;/p&gt;
&lt;p&gt;Each of them are infrastructural in some way, and that's probably
where the temptation to avoid being opinionated is strongest.  But
here's the genius: the rewards of being opinionated here are high.
Ruby on Rails is the existence proof.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://beaglewiki.org/Main_Page"&gt;Beagle&lt;/a&gt;, live search technology for
  GNOME.  Needs to decide where its primary use will be, and get on
  and hit the 1.0 point for that use only. Choose one or two neat 
  applications for integration, and be so utterly cool that every
  other app author flocks to integrate too.&lt;/li&gt;
&lt;li&gt;Synchronization.  First &lt;a href="http://www.multisync.org/"&gt;MultiSync&lt;/a&gt;, then
  &lt;a href="http://www.opensync.org/"&gt;OpenSync&lt;/a&gt;, have rumbled on for ages,
  without ever being truly effective for any particular device.  My
  take: choose a few "must-have" target devices--say, iPods and Nokia
  phones--and make them work completely.  Nearly-but-not-quite pleases
  nobody.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mono-project.com/"&gt;Mono&lt;/a&gt;.  Mono's great, but where's the
  story?  There's loads of potential in the people and the ideas
  behind the project, but playing catchup with Microsoft isn't very
  inspiring. Early projects like Muine helped Mono's cachet here, but
  we need more.  My personal favourite option would have been a
  completely free alternative to ASP.NET for web applications.  (I've
  seen a project called
  &lt;a href="http://www.castleproject.org/index.php/MonoRail"&gt;MonoRail&lt;/a&gt;, but
  don't know if it's the one...)&lt;/li&gt;

&lt;/ul&gt;
&lt;p&gt;What's better?  A handful of users with the "right" idea about how
fundamentally important you are to everything, or loads of users who
only see a portion of the capabilities of a project?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Copy the experts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It may seem like cheating to copy Apple's lead, but a lot of what
they've done in OS X is to take a stand on what's useful and not.  On
many occasions this has inconvenienced people, but it's not eroded
that special lure that Apple products hold.  There's not harm in
asking "What have Apple done?" with some of our projects.&lt;/p&gt;
&lt;p&gt;Another poster-child for being opinionated is &lt;a href="http://ubuntulinux.org/"&gt;Ubuntu
Linux&lt;/a&gt;.  Technically, it's only marginally
better than other Linux distributions.  Strategically, it's miles
ahead.  Its founder, Mark Shuttleworth, had very solid opinions about
where Ubuntu should go, and pursued them.  Over time, these have
pervaded the product itself, but at the start it was the message and
the style that made the difference.&lt;/p&gt;
&lt;p&gt;Opinions not expressed are rarely effective.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="http://times.usefulinc.com/2005/11/22-opinions#disqus_thread"&gt;Join the conversation about this post&lt;/a&gt;&lt;/p&gt;</content:encoded>
  </item>
</rdf:RDF>
