Conference organizer extraordinaire and general all-around good guy Chad Fowler interviewed me via email last week as part of a series of preparatory posts he's doing in the run up to RubyConf in November. He just posted the interview here: RubyConf Speaker Interview: Greg Borenstein.

Meanwhile, my rewrite of the RAD compiler is progressing smoothly. It successfully ran hello world over the weekend and today I got it working with all sketches that don't use plugins. I'm hoping to get it fully up-to-speed before my trip up to Seattle this weekend for a RAD hackfest with JD. We're hoping to push out an official 0.3 version that pulls together all the great changes we've added the last few months. You can already get that code (along with all the other bleeding edge changes) from the RAD GitHub repo, but the official release will be pushed to Rubyforge and made available elsewhere for the less adventurous.

Speaking at RubyConf

| | Comments (0) | TrackBacks (0)

I found out this week that my talk was accepted for this year's RubyConf! I'm very excited as this will be the first time I've spoken to a group this size.

The conference will be held November 6-8, which is the weekend immediately after the presidential election so I'm sure the mood will be extreme one way or another. You can check out the RubyConf schedule to see what else will be going down — I'm excited about a lot of the other talks, especially Ben Bleything, Giles Blowkett, and Yosseff Mendelssohn's Two Turntables And A Git Repo, about using Ruby to generate music.

Here's the description of my talk. For more details, see its page on the RubyConf site and the RubyConf schedule. Hope to see some of you there!

Ruby Arduino Development: Physical Computing for Everyone

In the past few years, microcontrollers -- the chips that control all the beeping, blinking, and buzzing devices in our world -- underwent a revolution in price and accessibility that parallels the transformation of microcomputers in the early 70s. Where that first revolution brought the personal computer this new one brings physical computing: the ability to sense and control the physical world as easily and cheaply as today's PCs process and store information.

The most useful product of this revolution is the Arduino development board. The Arduino combines a hardware design that emphasizes easy experimentation with a set of intuitive software libraries that mask many of the ugly details of microcontroller work. Just as the early personal computers offered information processing tools to diverse new groups, Arduino opens physical computing to artists, social workers, scientists, and even simple web programmers who lack electrical engineering degrees.

The Ruby Arduino Development project attempts to extend these virtues by bringing the beauty and power of Ruby to the Arduino platform. RAD compiles Ruby scripts for execution on the Arduino. In addition to the syntactic elegance and simplicity gained by getting to program in Ruby instead of C++, RAD provides a set of declarative Rails-like conventions and helpers that reduce boilerplate and simplify often-byzantine hardware APIs. Further, RAD takes advantage of Ruby's dynamic nature to offer sophisticated tools unavailable in the default Arduino distribution such as a testing framework and a graphical simulation environment (built with _why's Shoes GUI toolkit).

In this talk I'll conduct a comprehensive tour of RAD. Starting with the obligatory physical computing 'hello world' of blinking a single LED, I'll progress through increasingly sophisticated demonstrations including serial communication, inline assembly, movement detection, temperature sensing, and motor control. Lights will blink, things will spin, music will play.

I'll proceed to describe some of the design challenges RAD faces in integrating a diverse set of technologies (including RubyToC, Shoes, Rake, Makefiles, and avr-gcc) as well as balancing the constraints of concise compilation output that fits the Arduino's minimal program memory with the virtues of higher-level abstractions and rich interfaces that make a friendly environment for newbie hardware hackers.

I'll end with a call of encouragement. As a newcomer to electronics myself, RAD lets me build on the basis of my existing Ruby chops to create playful and useful projects even with very limited knowledge of the intimidating world of data sheets, circuit diagrams, and long-forgotten physics lectures. If I can build cool physical computing projects, you certainly can too.

Tagged: , , , , ,

What is Songbird?

Songbird is an iTunes-style music player that contains an integrated web browser. Songbird detects rich media on pages you visit and integrates them into itself in a number of ways: making them navigable through a "web playlist" reflecting the current page, remembering them in a "web media history" that you can browse and search, and, finally, providing a bridge between the music player and the web browser itself that allows web pages to interact with the playing song and the user's music library.

Why does Songbird matter?

Songbird is to iTunes what Firefox is to Internet Explorer: it provides an open source alternative to an application built as part of a vendor's extremely successful lock-in strategy. And, following in Firefox's footsteps, Songbird aims to introduce a raft of technical innovations into a stagnant space.


The bird. Shown here in a rare non-farting moment.

While iTunes (and especially the iTunes store) revolutionized the music industry on first release, its rate of innovation is restricted by Apple's ability to imagine and implement new features and, even more tightly, by the constricting legal ties the company has woven with the media conglomerates that provide its content. Songbird, on the other hand, is trying to offer an open platform for anyone to build their own innovative applications or competing business models. If they succeed, these lowered boundaries to participation will mean that Songbird's feature count and available content options will zoom past iTunes', inevitably bringing along an ever-growing number of users and, eventually, breaking Apple's monopoly and forcing them to scramble to compete — just as Firefox has done with Internet Explorer.

What can I do with it?

So, in what ways is Songbird open? What can you do with it as a developer? Well, just like Firefox, Songbird is open in a number of ways. First, the code for the player itself is available for download and licensed under the GPL. This means you can modify it, use it in your own applications, print it on your school binder, whatever you want. Secondly, Songbird has a plug-in architecture against which you can develop. The Songbird team calls applications written on this architecture Add-ons and they have access to everything from the player's appearance (for building skins) to the actual data and UI of the application. Finally, and most importantly for us here, Songbird provides web pages with a javascript API that allows them access to the app's sophisticated playback interface and, with their permission, the user's media library and custom playlists. Since this last is by far the easiest to get started with, I'll spend the rest of this post focusing specifically on it.

Setting up a Songbird Javascript Development Environment

One of the hardest parts of starting development in any new environment is getting all the pieces in place to successfully write and run your first line of code. This is especially true in complex runtime environments like javascript hosted in a web page running against APIs in a rapidly developing client. Here are the steps I followed to get there:

  • Download a nightly build. At the time of this writing, 0.6 was the latest hotness, but things are moving rapidly.

  • Get Firebug lite. Like most Javascript developers, I've become increasingly dependent on Firebug since its introduction. Being able to test out code in its interactive shell and navigate the resulting objects is priceless. Heck, even just being able to log information to the console rather than having to dismiss an endless parade of alert statements is worth the price of admission alone. Unfortunately, because of Songbird's rapid pace of development, there isn't currently a version of Firebug that is compatible with 0.6 (if you come from the future, visit Firebug's page on the Songbird add-on site to see if things have changed). Thankfully, there's another version of Firebug that can reside in the DOM of any given page. It doesn't have all the niceties we'd want (like object navigation) and it's access to the Songbird-specific javascript APIs we'll be spending our time with can be a bit...err...intermittent, but at least it provides a console for logging and some ability to inspect our objects. Once you've downloaded firebug, stick the directory somewhere in your project and create an HTML file with the following in the head tag: <script language="javascript" type="text/javascript" src="/path/to/firebug/firebug.js"></script> You should also set the debug attribute in your opening html tag to "true". Now, when you open your page in Songbird, it'll have a mini version of Firebug running at the bottom of its window. You can log to it and interact with objects (though limits and quirks will abound).

Songbird's Model of the World


Songbird's viewer window explained (full-size version).

The purpose of the Songbird webpage API is to provide the javascript running on a particular page with access to the media-player side of the application. Through it your page can track changes in the currently playing song, manage the "web playlist" (a small iTunes-style song browser that shows up underneath the current web page), and access song listings and metadata for the user's local music library, including reading and creating local playlists — you can even download songs directly to the user's computer. Pretty much the only thing you can't do is delete files.

Songbird presents three main abstractions for working with this functionality: Libraries, Media Lists, and Media Items. Let's start at the bottom with Media Items and work our way up.

Media Items == Songs

A Media Item is a single song or video in your Songbird library (at this point, I'm just speculating about the video part, though the generic name is certainly tantalizing and I know that Songbird does have some form of video support; however, I've only worked with songs, and from here on I'll assume that a Media Item is really a song). Media Items provide access to a raft of metadata such as "trackName", "artistName", "duration", etc. See the full list of Media Item properties for everything that Songbird makes available. You can read these attributes and set them. Interestingly, metadata properties are namespaced so you can create your own solely for use by your application, or even attempt to get a community of developers to standardize around new attributes for a particular domain.

One important thing about Media Items is that they don't necessarily have to correspond to a song with a locally available media file. Just as your iTunes library can contain songs whose actual mp3 files are elsewhere (like on an external backup drive), Media Items can be associated with files that are not currently available or with no file at all. Unlike iTunes, Media Items in Songbird can also be associated URLs that point at online mp3s.

Media Lists == Playlists

The next step up the ladder is Media Lists. These, as you might expect, are collections of Media Items, i.e. playlists. They have a name which is a handle for finding them (and also what shows up in the app's sidebar if you add them to the Main Library). You can find out which Media Items belong to a Media List and you can add and remove them. Media Lists are ordered stacks, so there's some functionality for managing the position, uniqueness, and suchlike of individual Media Items and for iterating through the full set.

Libraries

At the top of this whole shebang are Libraries. Libraries represent the permissions and interaction scope associated with a Media List or group of Media Lists, i.e. in which part of the application they'll be visible and which chunks of code will have access to them. There are three types of Libraries in Songbird — the Main Library, the Web Library, and the Site Library — and one other entity (the "Web Playlist" mentioned above) that sits in the same spot as a Library and behaves almost exactly like a Library, but isn't technically a Library. Things will get clearer quickly if we talk about the purpose of each type of Library, so let's dive right into that.

Libraries: the Main Library

First up, we've got the Main Library. The Main Library contains all the Media Items on the user's computer. Remember, since Songbird can provision audio for Media Items from public URLs and can include local Media Items for which the file is not currently available (the Missing Backup Drive scenario), this is not limited to files actually "physically" present. Reasons to talk to the Main Library include: wanting to create a new playlist on the user's computer that will be available after they browse away from your site, wanting to see what songs the user already has in order to make content recommendations, getting a list of all the local playlists a user has created and what songs are in them, etc. By default websites are blocked from accessing the Main Library at all unless the user has changed their "Web Integration" preferences to allow general access or to allow it for your website in particular. If you attempt to access the Main Library of a user who has limited access to their Main Library, Songbird will prompt them to permit or deny the action; the javascript API includes callbacks to make your code aware of the user's response to this prompt.

Libraries: the Web Library

Next up, we've got the Web Library. The Web Library contains all the Media Items Songbird has extracted from the webpages the user has visited. When you navigate to a URL that contains links to music files, Songbird discovers these links and gives you an iTunes style playlist representation of them at the bottom of your window (the Web Playlist). The Web Library is everything that's ever shown up in this playlist. It's every song from every webpage the user has ever visited within Songbird. This list of songs is made available to the user as the "Web Media History" and is an incredibly useful feature — if you spend any significant amount of time reading mp3 blogs or browsing band sites your Web Library will rapidly become populated with most of the music you've ever heard about, even in passing. This makes it an extremely rich collection to search against and idly browse. I can only imagine all the cool apps you could build if you had access to the entire mp3 blog browsing history of your users...obviously recommendations (for both music and blogs) come to mind, but you could probably also build some kind of very kick ass client-resident distributed spidering operation, or something else extremely neat that I can't think of off the top of my head. As you'd expect, the Web Library is under exactly the same access restrictions as the Main Library.

Libraries: the Web Playlist

Now we start to move into the Libraries that belong more to our individual websites than to the users themselves and over which we therefore have more control. The first and most visible of these is the Web Playlist. In the normal course of events (i.e. while browsing sites that aren't cool enough to use the Songbird API), the Web Player simply reflects any mp3s or other media files Songbird happened to find on the page. However, with the API we can control just about every aspect of the Web Playlist from the tracks that populate it to what pieces of data show up in each of its columns. I mentioned above that the Web Playist is not, strictly speaking, a Library. This means that it doesn't offer quite the same API as other Libraries — it only contains a single Media List; it doesn't have its own access controls separated from those of the Media List assigned to it; etc. — however, I include it in this list because, in the javascript, it lives at the root of the 'songbird' namespace as a sibling to the other Libraries and it offers an API that is largely (though not entirely) parallel to the others.

Libraries: Site Libraries

Lastly, we come to Site Libraries. Unlike the other Libraries we've covered so far, Site Libraries don't directly control the display of tracks to the user. Instead, they are simply an application-specific namespace for storing Media Lists. In other words, they let your javascript build Media Lists that are available only to users visiting particular pages on your domain (controlled via a scoping mechanism much like the traditional robots.txt syntax). Once you've got a Media List safely inside your own private Site Library, you can then display it in a Web Playlist, save it to the user's Main Library, or simply keep it invisible and use it to swap out the currently playing song. In fact, if you don't actually use a Site Library to manipulate any part of Songbird's UI (for example if they're just a convenient way to store your app's internal data), you don't even need the user's permission to create them. Site Libraries are a little harder to grok than the other varieties since they lack visible representation, but you'll quickly get used to working with them as they're the main place you'll be storing all the Media Lists you build. If you're still confused as you come away from this paragraph, you can just think of Site Libraries as a private place to store the Media Lists you compose without having to display them to the user in any way.

Some code samples

Let's make this whirlwind conceptual tour more concrete by looking at some examples. I'll show you the code to accomplish some basic tasks and then explain it in terms of the concepts I've outlined above.

Putting songs in the Web Playlist
songbird.setSiteScope("", "/"); var library = songbird.siteLibrary; var myMediaItem = songbird.siteLibrary.createMediaItem("http://www.example.com/track.mp3"); myMediaList.add(myMediaItem); songbird.webPlaylist.mediaList = myMediaList;

I cribbed this example from the Songbird wiki. It simply creates a media item from an mp3 URL, assigns the item to a media list that is scoped to the domain of the current page, and tells songbird to display the media list in the web playlist. The song won't actually appear anywhere visible to the user until the last line of code in this sample. Once the web playlist receives the media item, it'll scan the URL for metadata and fill in the track display based on what it finds.

Set a property on a media item
var myMediaItem = songbird.siteLibrary.createMediaItem("http://www.example.com/track.mp3"); myMediaItem.setProperty( "http://songbirdnest.com/data/1.0#artistName", "The Rolling Stones" );

If you set a property before adding the media item to a list and displaying it, Songbird will trust your metadata assignment and not override it based on the results it finds on the attached mp3. There are parallel methods for getting the values of any already set properties. You can set properties on media lists in the same way.

Download a media items' file to the user's computer
var library = songbird.siteLibrary("", ""); var mediaItem = library.createMediaItem("http://path/to/item.mp3"); songbird.downloadItem(mediaItem);

In addition to providing access to the various libraries, the songbird object allows you to do a whole raft of useful things such as download an mp3 from the web into a local media item (as shown here), getting access to information about the currently playing track, controlling which track is playing, etc.

Get all the local playlists
var mediaLists = songbird.mainLibrary.getPlaylists(); var results = []; while(mediaLists.hasMoreElements()) { var mediaList = mediaLists.getNext(); results.push(mediaList); } return results; };

This code asks the main library for a list of its playlists. When that first line of code runs, requesting access to the main library for the first time, Songbird will prompt the user for permission. In order to iterate through the results of getPlaylists, we have to call the special enumeration helper, hasMorePlaylists. This is a common pattern with collections of Songbird objects, there's often custom enumeration code that be somewhat counter-intuitive compared to standard array iteration.

Additional Resources

These examples only scratch the surface of what you can do with songbird. For more examples and more documentation, visit the Songbird webpage-api docs and the Songbird wiki entry on Webpage API integration.

The Songbird team hangs out at #songbird on irc.mozilla.org. They are quite friendly and open to helping out if you're confused or run into issues. I'd also like to thank them specifically for answering my large raft of questions as I was learning this API. This guide wouldn't have been possible without them.

Tagged: , , , , , ,

An intro to routing and controllers.

I wrote recently about getting started with Merb. Yesterday, after having refer to my own post to remember how it all worked, I started on a new Merb app as part of the Great Grabb.it Rewrite of 2008. I very quickly ran into another area of Merb that's a bit thin on documentation: Controllers. After some googling, some fiddling, and some brainstorming in the #merb irc channel I managed to figure out enough of the basics to get things up and running.

Right now, Merb's sweet spot seems to be as an API server, which is exactly how we're planning on using it. This usage means that while there might be a little bit of model integration for access control, most of the job is in routing URLs and data formatting. That means we'll be spending most of our effort in config/router.rb and in our controllers. Specifically, we'll need to know a lot about how Merb provides responses in various formats depending on the request url, i.e. it's equivalent to Rails' respond_to method. Let's start by laying out our requirements and then I'll show you how I translated them into Merbish.

For this app, I needed to take URLs within a namespace and route them to a single controller setting various params based on the rest of the request path. In other words, I wanted to provide URLs like: http://myapp.com/music/artist.jspf and http://myapp.com/music/artist/title.mp3 where the first url would give you a playlist of all of an artist's tracks in JSPF (Javascript Shareable Playlist Format) and the second would provide an mp3 of the song with the given title by the given artist.

So, the first thing I needed was a series of routes that would recognize all URLS starting with /music and then grab the path after the first slash into an :artist param and the path after the second slash into a :title param. Finally, it would need to look for a format after the dot and pass that through as well if available.

It turns out the best way to do this in Merb is with nested routes, thusly (inside of the Merb::Router.prepare block in config/router.rb): r.match('/music') do |music| music.match("/:artist.:format").to(:controller => 'music', :action => 'artist') music.match("/:artist/:title.:format").to(:controller => 'music', :action => 'track') end

This is pretty self explanatory if you're familiar with Rails routes, though it is probably worth noting that an early version of this I tried which eschewed the nesting in favor of including the /music part of the path in each route separately seemed to have problems detecting the format correctly (though it is more than likely the cause was driver error on my part rather than anything that Merb might do differently in that situation). There's pretty thorough documentation on Merb routing if you need more specific help and that's definitely not the case for the Controller APIs, so let's tackle those right away.

Now, how do we consume those URLs in our application? We need a controller, thusly: class Music < Application provides :jspf def track display Track.new params[:artist], params[:title] end def artist display Artist.new params[:artist] end end There's two main things going on here that distinguish Merb's controllers from Rails': the 'provides' class method and the 'display' method we're calling in each action. These two methods work together to let us return our data in the right format on every request. And, while they might look confusingly different from the familiar Rails respond_to block at first, they turn out to make things much cleaner, eliminating the need to redeclare common formats over and over in each controller method.

So, here's how it works: provides sets up a list of formats that we're willing to consume and then display makes sure that we provide the right one for each request. When a request comes in ending in .jspf, display calls to_jspf on the object that gets passed to it (in this case new tracks and artists). If we wanted to provide javascript, xml, html, etc. we'd just add those symbols to provides' arguments and then make sure the objects we passed to display could respond to to_xml, to_html, to_etc with the right data (there's an additional option for html of using a template in the views directory that Merb can automatically detect; that case works just like Rails; also: html seems always to be installed as a format regardless of whether or not you pass :html to provides).

While this should be enough to get you up and running writing Merb controllers, there are a few other details worth noting. First of all, if you want to provide alternative formats besides, js, html, xml, and the usual suspects (like we do here with jspf), you'll need to register a mime-type. We configured that by adding a single line to config/init.rb: Merb.add_mime_type(:jspf, :to_jspf, %w[application/jspf+json]) There's lots of other additional information about the request available to your controller actions as well, such as content_type. Secondly there's other options besides display for returning content from your action. Calling "render" will attempt to automatically detect a template with the right format in the appropriate views directory. And you can always just render a raw string. Again, more details are available here.

There's the beginnings of a great open source book being written by some folks on GitHub: Life On The Edge With Merb, DataMapper & RSpec.They've done a pretty solid job covering the basics of app initialization, modeling with the DataMapper ORM, and testing with RSpec so far, but their section on Controllers is blank so far. If someone wants to pick up the thin thread I've laid down here and run with it, that would be a great place for more documentation to accumulate.

Tagged: , , ,


photo by James Duncan Davidson

A few months back Chad Fowler asked me to coordinate the lightning talks for this year's RailsConf. It turned out to be a rolicking good time! We had 36 speakers in three sessions over three days — more than half the number of official talks! Topics ranged from announcements of new plugins (man, there are a lot of these suckers out there!) to demos of cool sites (Shared Copy certainly blew some minds) to rants and harangues (Ryan Davis never disappoints in this regard).

Below, I've attempted to summarize each of the talks and provide appropriate links where I could find them. The results are based on my sketchy notes while keeping time (and preparing my own talk) and so are definitely less than definitive. If you spoke and I got some of your details wrong, drop me a comment and I'll make corrections. If any speakers want to send me links to their slides, I can add those as well.

Thanks to everyone who participated — audience and speakers alike — and thanks to the RailsConf orgnaizers for letting me put this together.

Friday

Saturday

Sunday

Tagged: , , , , ,


Celia Hirschman from KCRW's On the Beat

In the most recent On the Beat, Celia Hirschman advocates for the Musician's Union to take a more active stand for musicians' rights online. In a world where only 42% of internet users say they pay for music, she argues, the Union has a responsibility to advocate for musicians' "right to be paid for their efforts anytime their music is played". She notes the failure of legislative attempts to extract revenue for musicians from peer-to-peer file sharing, mp3 blogs, and CD burning and lays the blame at the feet of the Union as the primary organization that represents musicians.

I agree with half of this argument. The Musician's Union has been embarrassingly lax in fighting the real battles that matter for artists in the modern music distribution landscape. What has the Musician's Union done to stop the labels from cheating artists out of revenue from iTunes downloads? How about to stop them wasting their shrinking budgets on glamorous perks and inflated short-run corporate profits rather than developing new artists with the possibility of long and successful careers? Or what about to force them to hire people who can figure out new business models that fit the new technology?

None of these battles receive the slightest mention in Hirscman's critique of the Union. She ignores the losses artists have suffered by being forced into vastly inequitable relationships with labels and instead highlights the ways in which the industry has failed to fully extract revenue from new forms of music consumption and fandom.

This wrong-headed focus on enforcement over transformation is symptomatic of the problems plaguing the record industry as a whole. Hirschman's catalogue of Union failings closely resembles a punchlist of RIAA complaints and talking points. Focusing on missed revenue from new forms of fandom while the music industry's entire distribution and profit model sinks into irrelevance is like getting upset over a spilled glass of champagne on the deck of the Titanic.

This mistake derives directly from the principle that Hirschman articulates in the piece: that artists "have the right to be paid for their efforts anytime their music is played." This same idea was proposed recently by Peter Kirn at Create Digital Music:

Recorded music has value to consumers. And, in business, if something has value somewhere, it's a business.

This is a core principle of the industry's thinking right now and it is obviously, palpably false. In middle school, when a friend played me Sebadoh off of a walkman that he'd smuggled to school, transforming me in a single moment into a lifelong fan of indie rock, was that "theft"? Should Sebadoh have gotten paid? When I worked at a local patisserie I used to play my favorite CDs throughout my shifts and would often write the band names and album titles down for intrigued customers. Should the shop have had to track and regulate everything we played so they could pay royalties to the artists?

This last is something of a trick question since enforcement of this kind of public performance royalty is something for which Hirschman specifically lauds rights-enforcers like ASCAP:

If you walk into a restaurant, nightclub or boutique and hear music playing, chances are very good a performance-rights organization have demanded compensation. These rights societies literally go door-to-door to insure their members get paid for music

Hirschman could not have this issue more wrong. ASCAP contacted the patisserie while I worked there saying they'd observed us playing music controlled by their members and we had to either cut it out, sign up for a very expensive pay service they were offering, or face a lawsuit. The business owners felt like they'd been shaken down by the mafia. Their response was to stop playing ASCAP music altogether and instead to put together a library of local music which we had explicit permission from the artists to play without royalties. Maintaining this library was a lot of work and we rapidly fell back into the old system of playing whatever we wanted, including ASCAP music, without permission, but now in an environment of greater fear and resentment. I would bet that a similar story holds for most places you actually visit beyond corporate chains: if you walk in and hear good music playing it is either local or in explicit defiance of an ASCAP threat.

And this story is a parable of what's wrong with focusing on enforcement. Enforcement alienates consumers and tastemakers. It tarnishes the reputations of artists and the organizations that should represent them. It forces natural music consumption and sharing patterns underground. Possibly worst, enforcement distracts artists and the industry itself from solving the huge existential issues that they face.

There is one piece of information from Hirschman's piece, however, that does hold out hope for the music industry if they do ever overcome these distractions and decide to face the real challenge of transformation: 42% of internet users pay for music. That's an enormous number. How many internet users pay for news? Or search? Or social networks? I don't hear anyone in these businesses complaining that their industry is in decline. That's an enormous number and it reflects the incredible amount of passion that exists for music online. If the industry can't find a way to transform that passion into a functional profitable business, it won't be because because the users outfoxed their enforcements efforts. They'll have only themselves to blame.

Tagged: , , , , , , ,

On sunday night, I released version 0.2.2 of the Ruby Arduino Development gem. The main focus of this update is compatibility with version 0011 of the Arduino software tools (follow that link for the release notes). While 0010 may still work with this new version of RAD, 0011 is now the default and upgrading is highly encourages. Download it here: Arduino 0011

.

This release also includes a patch to fix a problem with type-compatibility between RAD's var system and some Arduino function return values courtesy of David Michael. David also gave what looks like a great talk about RAD at NYC.rb: Ruby Meets Worlds, which includes a really nice example of using the observer pattern to communicate with an Arduino over a serial port that portends really well for one of the exciting things we've been talking about on the RAD Google Group: an interactive serial console.

Tagged: , , , , , ,

"The enemy isn't Microsoft. The enemy is non-use"
Matt Asay, The Ten Commandments of Open Source

For the past month, watching Hillary Clinton and Barack Obama — two relatively noble politicians who largely want the same good things for this country — say and do silly things to each other over the most superficial of disagreements in an atmosphere of ever-increasing animosity, I've been experiencing a disgust that was strangely familiar. All month I struggled to place where I'd felt this particular variety of nausea before, what other phenomenon oozes this same poison. And then I figured it out: it's the old Open Source vs. Evil Corporation flamewar. It's Slashdot all over again.

I won't alienate 40.4 percent of you by telling you which side I think is which since the key point is this: when two groups with basically the same objectives spend their best energy beating on each other those objectives are guaranteed to stay largely unaccomplished.

And just like every day that Obama and Clinton spend attacking each other leaves less hope for those good goals the two candidates share, every flamewar, every easy attack on Microsoft, every knee jerk reaction against a company that charges for its software leaves less attention available to solve the problems we all share of data interoperability, scaling, user friendliness, etc.

It's a fine thing to stand up for important values like openness and freedom, and, gosh knows, we have real disagreements on some topics that deserve to be debated vigorously, but the constant mutual harassment and posturing actually make these debates harder to resolve.

Both sides are guilty of this and we pay a measurable cost for it.

On the Open Source side, we tend to rule out technologies that reek of big corporate support even when they might be the best choice for the job and on the corporate side they tend to be too cautious, holding off on new ideas until they're blessed by the vendor of choice.

For example, I recently had a good old fashioned geek out with Rory Blyth, a college friend who went on to work at Microsoft. We spent a few hours having two of the oldest, least productive, and most fun coding conversations around: static vs. dynamic typing and SOAP vs. REST, as well as one new one that's shaping up to acquire a similar status: relational vs. document databases. While we seem to have an unbridgeable spiritual divide on the first topic, we each managed to convince each other, at least a little bit, on the last two. Rory did a strong job arguing in favor of the value of SOAP APIs for client implementors because of the strong level of automation and framework/IDE support that they enable and convincing me that at least some of my RESTful bias is inherited unquestioned from my community. Likewise, I managed to overcome Rory's profound SQL Server loyalty to convince him that relational databases, which were designed to perform original relational algebra in order to resolve a query with an unknown answer, are a bad architectural fit for most web applications which simply use them for object persistence. He left eager to check out CouchDB and I left resolved to explore Ruby's SOAP options.

This is exactly the kind of outcome that gets crowded out of most online discourse by the flamewars and name calling. The animosity and ugliness pushes us deeper into our own camps, just as moderate politicians tend to head to the extremes of their own party during a hard fought primary.

Well, the primary's over. I hereby declare it to be the general election. There's a world out there with real problems. From global warming to the growing international food crisis to the war on free speech, the world faces serious challenges that can only be overcome by radically great technology, the license it's released under be damned.

Tagged: , , , , , , , ,

It's been an active few weeks in the world of RAD! First off, RAD 0.2.1 was released last week which includes a bunch of small features and bug-fixes:

The documentation and examples should be lots of help for those of you are just getting started. If you've got successful sketches, send them to me and I'll add them!

I setup a Ruby Arduino Development Google Group for discussion amongst the growing group of contributors and users of the project. We've already got some fun stuff brewing there including someone working on a serial console, so drop by if you've got questions or want to participate.

Also, big thanks to Brian Riley of Really Bare Bones Arduino supplier Wulfden.org. His patch here for SWSerLCDpa support hopefully marks the start of a great collaboration to get a bunch of important Arduino libraries ported to RAD including OneWire and I2C. Plus, he sent me a totally awesome data logging kit to play with! Wulfden Arduino Kit Unboxing: data logging kit

Last, but definitely not least, I presented about RAD at Dorkbotpdx 0x01 last week. I was fortunate enough to be in the good company of Ward Cunningham (who gave an amazing talk about his biologically-inspired Cybords project) and many others. Jared from Dorkbotpdx shot video of the event which is now online. I did two demos, the basic blinky-LED hello world and a more advanced assembler sketch that drove a 7-segment LED and serial output (my segment starts at about 4:46):

Watch the rest of the videos from the event here: Dorkbotpdx 0x01 on Vimeo.

Tagged: , , , , , , , , ,

Spent a while today getting up and running with Merb, the minimalist modular alternative Ruby framework from Ezra and the good people at Engine Yard. Merb has been in a bit of chaos these recent months as it's gone through a major reworking to acheive a whole new level of performance as well as honest-to-goodness modularity, including choosing your own ORM and templating system. I've been watching Merb's development for some time waiting for it to get to a level of stability that looked safe enough to dive in; their most recent release, 0.9.2, combined with pressing needs in a few exciting new Grabb.it features, made today the day.

My first day with Merb has been mostly great, but the one thing I found really sorely missing was a tutorial on how to get started. In all fairness, the Merb team promises left and right that copious documentation will be coming as they settle down to 1.0. In the meantime, I thought I'd pitch in for any brave early adopters out there with this Guide to Installing Merb and ActiveRecord.

Acquire and Install the Source

So, my goal here was to get from 0 (no Merb on my machine whatsoever), to running a hello world for accessing the database from an existing Rails project using ActiveRecord from within Merb. The first step was to acquire the source. One of the downsides to Merb's modular architecture is the complexity involved with installing it (again, all relevant disclaimers here about how the merb team will, I'm sure, be working to simplify and improve the process as they reach 1.0). At least for now, you actually have to get your hands on three different packages: merb-core (the base of the framework, a requirement), merb-more (has more advanced features like the command for actually creating a new app), and merb-plugins (this is where things like ORMs and templating systems live). Let's do that: $ git clone git://github.com/wycats/merb-core.git $ git clone git://github.com/wycats/merb-more.git $ git clone git://github.com/wycats/merb-plugins.git That'll get us the bleeding edge trunk version (about which more here).

Now that we've got the pieces, we need to install them, thusly: $ cd merb-core ; rake install ; cd .. $ cd merb-more ; rake install ; cd .. $ cd merb-plugins/merb_activerecord; rake install; cd ..

Create a New Project and Configure it for Active Record

We've got all the pieces; it's time to create our project and get it setup to use ActiveRecord. Go to the place you want to create your app and do this: $ merb-gen app my_app This is equivalent to the 'rails' command and will create your project directoy with most of what you need. But since a basic project in Merb is assumed to be simpler than a basic project in Rails, you'll quickly notice that you don't have a models directory. Since we're actually going to need a model if we want to connect up to a database with ActiveRecord, go ahead and create that directory and create a file inside if for your model just as you would in Rails, for example my_resourece.rb, which could look like this: class MyResource < ActiveRecord::Base end

We'll probably want a controller as well, so create a new file: controllers/my_resources.rb: class MyResources < Application def show r = MyResource.find :first render r.some_method end end Notice that all Merb controllers inherit from Application just like Rails controllers inherit from Application::Controller. The naming choice there is kind of interesting because it reveals Merb's controller-centric history and philosophy (remember that the framework doesn't assume that we need models by default; it turns out there's a lot you can do with just controllers).

Since we're using ActiveRecord, we'll obviously need to tell Merb that we want it to go ahead and actually load AR as our ORM. Go into config/init.rb in your project and uncomment the line that says "use_orm :activerecord".

We're almost there! These last few steps will feel familiar from setting up a Rails app: letting the framework know about our route and database configuration. To set up your route, open up config/router.rb and, inside the 'prepare' block, add a line like this: r.resources :my_resources Merb's routes work pretty much like Rails's, but with a few more advanced features some of which are explained in the comments at the top of that file. If you need something other than standard RESTful routing, read those.

Finally, all we've got to do is configure database access and we'll be ready to roll. In Merb this looks exactly like Rails, in fact, I simply copied the database.yml file over from the Rails project that usually manages the db I wanted to access, dropped it in config/databse.yml and it worked straight out of the box.

Ok! If you've made it this far, then you're probably more than ready for the big reveal. In you project directory do this: $ merb The server will start and you'll get a few log messages in your terminal that look like this: $ merb ~ Loaded DEVELOPMENT Environment... ~ loading gem 'merb_activerecord' from ... ~ loading gem 'activerecord' from ... ~ Connecting to database... ~ Compiling routes... ~ Using 'share-nothing' cookie sessions (4kb limit per client) ~ Using Mongrel adapter Once that settles down, browse to http://localhost:4000 and you should see the Merb welcome screen. Go to your expected url to see the result of your handiwork: i.e. http://localhost:4000/my_resources/7

If this works, you're officially up and running with Merb and ActiveRecord. If not, you'll see one of Merb's very stylish error screens and it'll be time to go to #merb on irc.freenode.net where all the friendly merbfolk hang out and are more than willing to help.

Tagged: , , , , ,
Powered by Movable Type 4.0
Clicky Web Analytics