Custom Attributes And Class Names

Posted almost 7 years back at danwebb.net - Home

At the Rich Web Experience, Alex Russell did a presentation entitled Standards Heresy, In the presentation, which I didn’t attend so forgive me if I’ve gotten the wrong end of the stick, he spoke about how Dojo has been forced to abandon web standards in some cases in order to get the job done. The conversation was furthered by Aaron Gustafson’s response and is a really interesting discussion. However, I’m not going to comment on the politics of the W3C further as I know nothing about that at all. One example in the presentation reminded me of something I’ve wanted to comment on for a while now. Here’s that example:

<div dojoType="dijit.form.HorizontalSlider"
     name="horizontal1"
     onChange="dojo.byId('slider1input').value=arguments[0];"
     value="10"
     maximum="100"
     minimum="0"
     showButtons="false"
     intermediateChanges="true"
     style="width:50%; height: 20px;"
     id="slider1">
  ...
</div>

This is a snippet of code showing how Dojo is going off the standards rails by adding custom attributes that are ‘needed’ to configure a slider widget. This is a really good example of a case where you definitely shouldn’t add custom attributes to HTML. While the W3C/browser vendors/whipping boy of choice might be letting us down what the web standards movement taught us (most importantly in my mind) is that semantic HTML is critically important. Having a <div> with custom attributes that tell Dojo it’s a slider widget is of no use to anything apart from as a crutch to Dojo. It has no semantic value at all. Outside of the context of Dojo it’s just an useless lump of markup.

Although HTML is a pretty limited vocabulary which is very document centric we can still go much further than this in attempting to describe what this is semantically. It’s an input so use an input or a select box as the base element. How browsers and assistive technologies deal with these elements is a lot closer to what we want than a meaningless <div>. Secondly, there’s custom attributes – having attributes containing behavioural information like showButtons and intermediateChanges are equally as semantically useless as the old presentational attributes like bgcolor and border and we’ve all learnt the disadvantages of mixing content and presentation and discarded those…hopefully. There’s got to be a better way.

So we want our semantic HTML and to keep our behaviour data out of our document. Take a leaf out of CSS’s book. We can name and classify objects and use these as our hooks to attach our JavaScript powered behaviour. Eureka! Not quite:

<!-- Created with http://cow.neondragon.net/stuff/reflection/reflectomatic.html  -->
<img src="/reflection/photos/giraffe.jpg" width="132" alt="" class="reflect ropacity71" />

The above code is from a nice little JavaScript effects library called reflection.js which uses class names to hook in it’s behaviour unobtrusively. However, take a closer look at the class names. They aren’t classifying things as such, they are embedding configuration into directly into the class names. In a similar way it’s not a generally thought of as a good idea to give elements class names like ‘bigred’ or ‘width40’ although, depressingly, I’ve seen it done! This is definitely an abuse of class names – its not a ‘bigred’ its a ‘price’ and so on. This is seen not just in reflection.js but a large amount of ‘unobtrusive’ libraries.

So how can we improve on this? We need to provide configuration information to our JavaScript but neither custom attributes or embedding info are looking good. The answer is pretty simple – add another link to the chain and this is were (plug imminent :) projects like behaviour.js and Low Pro come in. They add that other link to the chain. We can say that all inputs with the class ‘date’ should have a date selector attached to them or that selects with the class ‘rating’ should be replaced with a slider that’s range is 0-10 and so on. Here’s a snippet using Low Pro to illustrate this:

Event.addBehavior({
  'select.rating': Slider({ min: 0, max: 10, intermediateValues: true }),
  'input.date': DateSelector
});

In this way we are able to maintain semantic HTML, avoid adding custom attributes and maintain a very loose coupling between our document and it’s behaviour. This, we’ve seen from CSS, is vitally important to maintainability and a real advantage. Via this method you can apply configuration to single items or as a group. If you decided that ‘rating’ selects should in fact all be vertical sliders instead of horizontal then that’s no problem either. It gives you ultimate flexibility.

This methodology is right at the core of Low Pro and I’ve been getting incredible results from it. It’s made what could be really complex JavaScript implementations a breeze. Instead of a huge, fearsome application everything becomes a HTML document with many loosely, coupled smaller components attached to it. If you don’t use Prototype/Low Pro don’t let that stop you from working this way. Bill Burcham wonders whether this can be library agnostic. Well, as an idea, in a sense it already is. All you need is the ability to select by CSS selectors. Dojo and dijit are in fact very well suited.

Many Skinny Methods

Posted almost 7 years back at The Rails Way - all

This refactoring is based on a topic Marcel and I covered at RailsConf Europe.

Before

1
2
3
4
5
6
7
8
9
10
11
12
class Expense < ActiveRecord::Base
  belongs_to :payee
  protected

    # Nice and concise, but what happens as we add more rules
    # and how do we write test cases for the four different possible 
    # validation states?
    def validate
      errors.add("Not enough funds") if payee.balance - amount > 0
      errors.add("Charge is too great") if payee.account.maximum_allowable_charge > amount
    end
end

After

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Expense < ActiveRecord::Base
  belongs_to  :payee

  # Instead of one large validation method, break each individual
  # rule into methods, and declare them here.
  validate      :ensure_balance_is_sufficient_to_cover_amount
  validate      :amount_does_not_exceed_maximum_allowable_charge

  protected

    # These validation callbacks simply add error messages if a particular 
    # condition is met.   Each of them can be tested and understood on their own
    # without having to understand the entire body of the validate method.
    def ensure_balance_is_sufficient_to_cover_amount
      errors.add("Not enough funds") if insufficient_funds?
    end

    def amount_does_not_exceed_maximum_allowable_charge
      errors.add("Charge is too great") if exceeds_maximum_allowable_charge?
    end

    # By defining separate predicate methods we can test each of them individually
    # and new programmers can see the intent of the code, not just the implementation.


    # Instead of subtracting the amount from the balance and checking if the
    # value is greater than 0,  change the implementation to mirror the intent.
    # There was a bug in the before code,  this is more obvious.
    def insufficient_funds?
      amount > payee.balance
    end

    def exceeds_maximum_allowable_charge?
      payee.account.maximum_allowable_charge > amount
    end
end

While the refactored version may have more lines of code, but don’t let that scare you. It’s far more important for code to be human readable than incredibly concise.

Adobe Media Player

Posted almost 7 years back at Liverail - Home

It’s starting to look at lot like Christmas… well for Flash developers anyhow

That comes from Daniel Todd and I think he’s referring to the amount of new goodies Adobe released in the last couple of days. We had the AIR Beta 2 Flex 3 Beta 2 Thermo and Adobe Media Player. Thankfully the new AIR beta fixes my favorite making AIR useless bug synchronous database access

But its Adobe Media Player I’m loving at the moment. It’s an AIR app and it needs the new beta runtime and for those who know nothing about it, basically it’s a cross between iTunes and Joost but for Flash video. With a modified RSS feed video suppliers can create a channel of Flash video for people to watch, favorite and share. It downloads the video so you can watch it offline as well.

Adobe Media Player Interface

So far, so iTunes. But a channel feed can also include branding elements to give every channel a different look. But not too special right. It’s the future of AMP that’s exciting, the ability to embed advertising, pre-rollers, post-rollers, interactive elements. The Buy that shirt the guy in the video has element which makes AMP attractive for content producers and distributers.

Adobe Media Player Branded Channel

But a more interesting future for AMP is allowing companies to white-label it, skinning and modifying the player to create their own iTunes/BBC iPlayer (without the DRM and with the Mac!). A great idea, I’m just surprised Adobe is there first. Normally I would expect to see this kind of thing coming out of a company like Brightcove

Adobe Media Player

Posted almost 7 years back at Liverail - Home

It’s starting to look at lot like Christmas… well for Flash developers anyhow

That comes from Daniel Todd and I think he’s referring to the amount of new goodies Adobe released in the last couple of days. We had the AIR Beta 2 Flex 3 Beta 2 Thermo and Adobe Media Player. Thankfully the new AIR beta fixes my favorite making AIR useless bug synchronous database access

But its Adobe Media Player I’m loving at the moment. It’s an AIR app and it needs the new beta runtime and for those who know nothing about it, basically it’s a cross between iTunes and Joost but for Flash video. With a modified RSS feed video suppliers can create a channel of Flash video for people to watch, favorite and share. It downloads the video so you can watch it offline as well.

Adobe Media Player Interface

So far, so iTunes. But a channel feed can also include branding elements to give every channel a different look. But not too special right. It’s the future of AMP that’s exciting, the ability to embed advertising, pre-rollers, post-rollers, interactive elements. The Buy that shirt the guy in the video has element which makes AMP attractive for content producers and distributers.

Adobe Media Player Branded Channel

But a more interesting future for AMP is allowing companies to white-label it, skinning and modifying the player to create their own iTunes/BBC iPlayer (without the DRM and with the Mac!). A great idea, I’m just surprised Adobe is there first. Normally I would expect to see this kind of thing coming out of a company like Brightcove

Bazaar Project Templates

Posted almost 7 years back at Ryan Tomayko's Writings

Bill de hÓra:

It occurred to me that by setting up a local hg, I had in fact branched, but without the overhead and ceremony associated with branches. Driving the cost of branches to zero is transformational.

Indeed.

I've been experimenting with Bazaar for a little while and had a strange idea: why not use branches as a project template mechanism?

$ bzr branch http://tomayko.com/src/ruby-project devel/hello-bill
$ cd devel/hello-bill
$ cat <<. > lib/hello.rb
#!/usr/bin/env ruby
puts 'Hello, Bill'"
.
$ chmod +x bin/hello
$ bzr add && bzr commit -m "say hi to bill"
added bin/hello-bill
added lib/hello.rb
Committed revision 23.
$ cat <<EOF > Rakefile
load 'misc/asciidoc.rake'
load 'misc/project.rake'
Project.new 'Hello, Bill' do |p|
  p.package_name = 'hello-bill'
  p.version = '3.14159'
  p.summary = 'Just saying hi'
  p.author = 'Ryan Tomayko <rtomayko@gmail.com>'
  p.description = <<-end
    A program that writes "Hello, Bill" to STDOUT and exits.
    Just because.
  end
  p.project_url = "http://tomayko.com/src/#{p.package_name}"
  p.remote_dist_location = "tomayko.com:/dist/#{p.package_name}"
  p.remote_doc_location = "tomayko.com:/src/#{p.package_name}"
  p.remote_branch_location = "tomayko.com:/src/#{p.package_name}"
end
EOF
$ cat <<EOF > doc/index.txt
= Hello, Bill {package-version}

The +hello-bill+ program writes "Hello, Bill" to STDOUT and exits.
EOF
$ bzr ci -m "update project info and docs"
$ rake doc package publish
asciidoc -d article -o ./index.html ./index.txt
asciidoc -d article -o ./license.html ./license.txt
source-highlight -s ruby --line-number-ref='' ... 
Processing 'lib/hello.rb' ... created doc/src/lib/hello.rb.html
Generating RDoc API Documentation.
tar zcvf hello-bill-3.14159.tar.gz hello-bill-3.14159 ...
zip -r hello-bill-3.14159.zip hello-bill-3.14159
rsync -aP ... rtomayko@tomayko.com:/dist/hello-bill
rsync -azP --delete --hard-links .bzr rtomayko@tomayko.com:/src/hello-bill
rsync -azP doc/ rtomayko@tomayko.com:/src/hello-bill
$ sudo gem install hello-bill --source=http://tomayko.com
$ hello-bill
Hello, Bill

Project documentation and bzr branch now here.

Cool, eh?

I've thought through the downside a bit and most of what I come up with is made irrelevant by cheap, distributed branches. For instance, if you want a different doc / test / package / distribution tool, fine: create a branch and make it do whatever you want; then, branch from there instead for your new projects.

I've only merged upstream changes from the template project into a downstream project once or twice but I'm expecting to run into silly and potentially annoying conflicts. So far it’s been smooth sailing but we’ll see.

Ruby-Debug HOWTO and free book

Posted almost 7 years back at poocs.net - Home

Somewhere between the release of my Rails book and now, several things happened. First of all, Ruby 1.8.6 was released in March and quickly became the preferred version to use with Rails application with the release of Rails 1.2.3.

This, however, meant the end to the era of the breakpointer library to debug your Rails application, which relied on a bug in Ruby that had been fixed in Ruby 1.8.5 onwards. The Rails Core group was quick to adopt ruby-debug, Kent Sibilev’s native implementation of a Ruby debugger which was also heavily inspired by more powerful debuggers from other programming languages such as C.

With the preview release of Rails 2.0, available since Sep 30, integration of ruby-debug has been fostered even more.

For this very reason, I recently sat down and wrote a replacement chapter for my Rails book that serves both as a gentle conceptual introduction to ruby-debug (which still somewhat lacks detailed hands-on articles, due to its still fairly young age) and a replacement for the example debugging sessions the printed book has (but relying on the slightly different operation of the breakpointer client).

The article is available through SitePoint.com. Please note, however, that you should have the source code for the sample application from the book available, to give yourself some context and the full scope of the code.

Rails book available for FREE

On a related note, SitePoint, the publisher of Build Your Own Ruby on Rails Web Applications, decided to offer the entire book as a free PDF download for a limited time period of 60 days starting today. Grab your copy of the 474 pages (including the updated chapter on debugging making use of ruby-debug) here.

Bad Code

Posted almost 7 years back at Darwinweb

I caught up with this thread on Joel’s discussion board today. We software developers will take any opportunity to rant about the bass-ackwards code we have to deal with on a regular basis. For passionate developers, it’s understandable that most code wouldn’t live up to our standards—only a select few projects have the amount of resources necessary to truly pursue perfection. Over time the exposure to imperfect code can condition us with unfair knee-jerk reaction to new code.

How bad is the code really?

The world is full of terrible code. Usually that becomes painfully obvious at maintenance time. When an existing project is opened up for the first time by a new team member, I think the instinct is to see the flaws before the brilliance. What kinds of things make code stinky? Well it depends who you ask, but some possible reasons are:

  • Unnecessary duplication of code (under-abstracted)
  • Overly complicated code (over-abstracted or unnecessarily clever)
  • Too many files/classes
  • Giant monolithic classes
  • Wrong design patterns applied
  • Stupid algorithms
  • Failure to use appropriate libraries or framework features (reinventing the wheel)
  • Inconsistency (lack of conventions)
  • Numerous obvious comments
  • No documentation

Anyone whose done their share of code maintenance has probably been annoyed by most of the things on this list one time or another. “If only they had done it this way.” It’s easy to just assume the code sucks based on a first impression. Once you jump to that conclusion, every minor flaw affirms your prejudice.

Pet peeves

Let’s step back a minute and give ourselves an ego check. To an experienced developer there are hundreds of nuances that will stick out like a sore thumb, but they are likely to annoy you far more than they actually impact your productivity were you to consider them objectively.

If you’re not careful, your concern for the code boils over into judgement of the previous programmers. Maybe the last guy wasn’t up to snuff in this language, maybe his pet peeves were different, maybe he was just a blathering idiot. Whatever the case, why dwell on it?

I’ve managed to make it through a lot of bad code without slowing down much. Every once and a while a refactoring or straight-up delete and rewrite was necessary, but most of the time I was able to grit my teeth and get some changes done relatively quickly.

Real reasons code “sucks”

The problem facing you is likely to be different from what the last programmer faced. It would be foolish to assume that the software was designed with the same requirements that you have in front of you today. Who’s to say the business goals haven’t changed drastically since then?

You and the last developer have different information. Even after you’ve spent a lot of time on the code and understand all the intricacies and business goals, you still may not know the history of the project. Maybe the code has grown and shrunk and morphed into something completely different from when it started. If it’s time to refactor, maybe that’s your job.

It’s also quite possible that refactoring is not worth it. Good developers innately want maintainable and aesthetically pleasing code, but there is a cost. We can’t write perfect software before we understand it, and we can’t refactor without spending time. The developer is usually in a better position than the manager to assess the long-term cost of not refactoring, but he also has a vested interested in exaggerating that cost. To make a fair assessment, the developer must have a direct business interest. Even then there’s a great deal of uncertainty. It’s always a gamble.

Cognitive dissonance

Developers are conditioned to be right. Our job requires a fiercely logical thought process and the ability to make absolute assertions. Being wrong means things are broken, sometimes spectacularly so. And because we think so hard about things in this way, our conclusions are usually well-reasoned. But we are still human, and we still have the same defense mechanisms around our belief systems as everybody else. The insidious thing is that our reasoning blinds us to our own subjectivity. Our open-mindedness is a badge of pride, but also a set of subconscious blinders.

The only really objective thing about software is its output.

Software engineering is about making choices. Some choices are pragmatic (C++ for performance), some are philosophical (Ruby vs Python), but most are an intangible mixture of past experience and future expectations. When you see some code for the first time, the chances that it will mesh with your experience and philosophy are pretty slim. Eventually you may come to appreciate it for what it is, but in the meantime every tradeoff that didn’t follow your current line of thought will irk you.

Software is messy

None of this is to say that there aren’t real quality problems in the software industry—of course there are. But I think it’s worth carefully considering our own motivations and biases before judging how bad the problem really is.

We may not like dealing with inadequately-funded balls of mud, but that’s probably where most of the paying work is. Even in relatively clean code bases, reasonable people can disagree on style or architecture points. Regardless of initial code quality, there will always be difficult and inelegant maintenance that needs to be done. My goal is to keep emotion out of it, and just fix problems. Refactoring is great if a business case can be made, otherwise just slog through as fast as possible without complaining.

Easier said than done, I know.

New Version of Rails, Arriving on Track 2.0

Posted almost 7 years back at Alloy Code - Home

OK, title aside, no train puns from me today… this is exciting news!

Rails 2.0 has reached Preview Release status. Despite the Microsoft-esque syntax, the mood is overwhelmingly upbeat. Personally, I’ve been using Edge Rails for all my new development over the past 6 months, but this final drive by the Rails Core team and core contributors has included some great new goodies.

The changes to the Routing system have received plenty of attention elsewhere, but I wanted to pull out one tidbit which I’ve only seen posted one other place, Casper Fabricius’ excellent recap of DHH’s keynote address at Railsconf Europe:

Namespaced Routes are awesome, and a long-overdue addition for any of us who’ve attempted to create an administration section for our sites. There’s a clever bit of form_for syntax for dealing with namespaced routes.

The Old Way
form_for :user, :url => admin_users_path do |f|
  # new user form 
end

form_for :user, :url => admin_user_path(@user), 
                :html => { :method => :put } do |f|
  # edit user form
end
The New Way
form_for([:admin, @user]) do |f|
  # Works for either!
end

Cleaner, more concise, and thoroughly overlooked. Casper, thanks for bringing this out so we could see it!

New Version of Rails, Arriving on Track 2.0

Posted almost 7 years back at Alloy Code - Home

OK, title aside, no train puns from me today… this is exciting news!

Rails 2.0 has reached Preview Release status. Despite the Microsoft-esque syntax, the mood is overwhelmingly upbeat. Personally, I’ve been using Edge Rails for all my new development over the past 6 months, but this final drive by the Rails Core team and core contributors has included some great new goodies.

The changes to the Routing system have received plenty of attention elsewhere, but I wanted to pull out one tidbit which I’ve only seen posted one other place, Casper Fabricius’ excellent recap of DHH’s keynote address at Railsconf Europe:

Namespaced Routes are awesome, and a long-overdue addition for any of us who’ve attempted to create an administration section for our sites. There’s a clever bit of form_for syntax for dealing with namespaced routes.

The Old Way
form_for :user, :url => admin_users_path do |f|
  # new user form 
end

form_for :user, :url => admin_user_path(@user), 
                :html => { :method => :put } do |f|
  # edit user form
end
The New Way
form_for([:admin, @user]) do |f|
  # Works for either!
end

Cleaner, more concise, and thoroughly overlooked. Casper, thanks for bringing this out so we could see it!

Episode 73: Complex Forms Part 1

Posted almost 7 years back at Railscasts

Complex forms often lead to complex controllers, but that doesn't have to be the case. In this episode see how you can create multiple models through a single form while keeping the controller clean.

New Version of Rails, Arriving on Track 2

Posted almost 7 years back at Alloy Code - Home

OK, title aside, no train puns from me today… this is exciting news!

Rails 2.0 has reached Preview Release status. Despite the Microsoft-esque syntax, the mood is overwhelmingly upbeat. Personally, I’ve been using Edge Rails for all my new development over the past 6 months, but this final drive by the Rails Core team and core contributors has included some great new goodies.

The changes to the Routing system have received plenty of attention elsewhere, but I wanted to pull out one tidbit which I’ve only seen posted one other place, Casper Fabricius’ excellent recap of DHH’s keynote address at Railsconf Europe:

Namespaced Routes are awesome, and a long-overdue addition for any of us who’ve attempted to create an administration section for our sites. There’s a clever bit of form_for syntax for dealing with namespaced routes.

The Old Way
form_for :user, :url => admin_users_path do |f|
  # new user form 
end

form_for :user, :url => admin_user_path(@user), 
                :html => { :method => :put } do |f|
  # edit user form
end
The New Way
form_for([:admin, @user]) do |f|
  # Works for either!
end

Cleaner, more concise, and thoroughly overlooked. Casper, thanks for bringing this out so we could see it!

New Version of Rails, Arriving on Track 2

Posted almost 7 years back at Alloy Code - Home

OK, title aside, no train puns from me today… this is exciting news!

Rails 2.0 has reached Preview Release status. Despite the Microsoft-esque syntax, the mood is overwhelmingly upbeat. Personally, I’ve been using Edge Rails for all my new development over the past 6 months, but this final drive by the Rails Core team and core contributors has included some great new goodies.

The changes to the Routing system have received plenty of attention elsewhere, but I wanted to pull out one tidbit which I’ve only seen posted one other place, Casper Fabricius’ excellent recap of DHH’s keynote address at Railsconf Europe:

Namespaced Routes are awesome, and a long-overdue addition for any of us who’ve attempted to create an administration section for our sites. There’s a clever bit of form_for syntax for dealing with namespaced routes.

The Old Way
form_for :user, :url => admin_users_path do |f|
  # new user form 
end

form_for :user, :url => admin_user_path(@user), 
                :html => { :method => :put } do |f|
  # edit user form
end
The New Way
form_for([:admin, @user]) do |f|
  # Works for either!
end

Cleaner, more concise, and thoroughly overlooked. Casper, thanks for bringing this out so we could see it!

Rails 2.0 Preview Release Available

Posted almost 7 years back at zerosum dirt(nap) - Home

Check it out: a Preview Release of Rails 2.0 was made available yesterday. Things are “almost finished” and this is an opportunity for folks (who haven’t been following edge closely) to get a taste of what’s new before the final release. To install the gem:

gem install rails --source http://gems.rubyonrails.org

Or you can freeze edge using the tag “rel_2-0-0_PR”. Make sure to check out that post (linked above) to read about all the good stuff.

Note that 1.2.4 will also be released prior to 2.0 and will include a variety of bugfixes as well as the final deprecation warnings for upgrading an application to 2.0. Big thanks to the whole core team (and all the contributors) for their excellent work.

Presenting @ Ruby East

Posted almost 7 years back at zerosum dirt(nap) - Home

I’m going to be at Ruby East on — oh wow, I’m already here. Hrmm, well nevermind then. Obviously things have been much too busy for pro-active blog entries lately. Sorry about that.

In any case, if you’re here, make sure to hang around until the end to see my Rails Rumble talk, which will include announcing the winners. We’ll also be showing some of the team screencasts, in order to demonstrate just how much you can accomplish with Ruby in a very short amount of time. Should be a fun way to close out the event.

If you’re not lucky enough to be attending this great little regional conference, the winning teams will also be announced on the Rumble Blog sometime later today. Great work everyone.

Bio::Graphics and rails

Posted almost 7 years back at Saaien Tist

As a follow up to my post on Bio::Graphics, I tried integrating this library in a rails application. After all, you'd get your data either from a file (like GFF) or a database. And let me tell you: it took me just 30 minutes or so to get a proof-of-concept running. This included installing rails itself, creating the rails app, creating the database, loading dummy data, and doing the coding itself. That 30 minutes was interrupted for a couple of hours, because I needed some advice from Kouhei Sutou, the author of rcairo, on how to write PNG images in memory instead of to a file.

So how do you do it? The proof-of-concept little database I created contained 3 tables:

  • chromosomes (columns: id, name, length)
  • tracks (columns: id, name, glyph, colour)
  • features (columns: id, chromosome_id, track_id, name, location, url)
Create some features for a couple of different tracks for a particular chromosome.

In views/chromosomes/show.rhtml, add the following line:

<%= @chromosome.to_png %>


My models/chromosome.rb looks like this:

require 'stringio'
require 'base64'
require_gem 'bio-graphics'

class Chromosome < through =""> :features

def to_png(width = 800, start = 1, stop = self.length)
return %{}
end

def draw(width, start, stop)
panel = Bio::Graphics::Panel.new(self.length, width, false, start, stop)
track_container = Hash.new
self.tracks.each do |track|
if ! track_container.has_key?(track.name)
track_container[track.name] = panel.add_track(track.name, track.colour.split(',').collect{|i| i.to_i}, track.glyph)
end
end

self.features.each do |feature|
track_container[feature.track.name].add_feature(feature.name, feature.location)
end

output = StringIO.new
panel.draw(output)
return output.string
end
end


UPDATE: Apparently, Blogger does not allow me to paste the correct code above. In the to_png method, replace the following ascii codes:

  • %7B with {

  • %28 with (

  • %29 with )

  • %7D with }



And that's it. I leave the integration of my ensembl-api, bio-graphics and rails as an exercise for the reader. We could make a ruby version of the Ensembl browser... and then: world domination. Mwahaha.