June 28th, 2008 benhughes
To me, the benefit of using JavaScript frameworks in an application cannot be overstated. Though I’m also a fan of server-side frameworks, there is scarcely a reason not to use a client-side framework these days. Of course the most common complaint against JavaScript frameworks is “bloat” and the long download time. Funny that the most vocal of those complaining about the frameworks’ download time are those who haven’t even ever used a framework to experience it’s benefits. The tradeoff of course is a noticeable load hit for some users on slower connections vs. architectural elegance, much higher productivity, more maintainability, and less code in general. To me in most cases the trade-off is a no-brainer in any sufficiently modern web application, but not to all.
Released recently is the Google Ajax Libraries API which is basically a way of allowing browsers do download only one version of a given framework for all applications using that framework. Currently most web applications host their own version of a given JavaScript library, which is inefficient across the spectrum of the internet since many sites are using the exact same library. With Google Ajax Libraries you essentially reference Google’s hosted version of the library and the download hit is only incurred the first time a user visits any site using that framework. So it’s quite likely that a user going to your site won’t have to download a thing - it’s as if the framework is at that point simply part of the user’s browser.
Of course this only works if it becomes widely used and I sure hope it will. I’d encourange all developers to start using this in their production environments (development environments should still use local copies for local development:
Google AJAX Libraries API
Rails Plugin for Google AJAX Libraries API
Posted in Uncategorized | No Comments »
June 25th, 2008 benhughes
I fairly often use the acts_as_tree plugin in my applications. While acts_as_nested_set (and superior variants..) is more powerful, often times a simple two-level deep hierarchy is all I need and acts_as_tree is simple. I’ve found the new named_scope functionality in Rails 2.1 to be very helpful when dealing with tree data structures.
Firstly, it’s somewhat rare that I have one single root node in the tree structure (which is apparently how it’s meant to be used). Instead I’ll have multiple “parent” nodes designated with a NULL parent_id and children beneath. In the past I’ve always done something like: find(:all, :conditions => {:parent_id => nil}) to grab the top entries. Instead with nested set you can do this:
named_scope :top, :conditions => {:parent_id => nil}
#Then:
Category.top
Another common task when dealing with hierarchical categories is to query on the base object (products for example) for members that are “part of” that category. Specifically, part of in a 2-level heirarchy simply means “where id = ? or parent_id = ?” on the joined categories table. Because this involves a join it was somewhat clunky to do before. Now with nested set, on the product model I can declare this:
named_scope :in_category, lambda {|c| {:include => [:category], :conditions => ["categories.id = ? OR categories.parent_id = ?", c, c]} }
# Then:
Product.in_category(3)
I would also highly encourage you all to check out RailsCasts Episode 112 “Anonymous Scopes” by Ryan Bates where he outlines a pattern for handling conditions elegantly with searches using named_scopes in Rails 2.1, something I’ve always found to be lacking from Rails core and always resorted to using plugins like criteria_query.
Posted in Rails General, Rails Techniques, Rails Tools | No Comments »
June 4th, 2008 benhughes
Though I’ve been extremely happy with leopard (in fact, why I finally bought a Mac), little quirks with spaces were frustrating. Specifically, spaces seems to have been designed for users who want to place a separate application in each space. I use spaces in a task-oriented manner where each space typically has a Firefox window, tabbed terminal, and TextMate. Command-Tabbing and others workflow situations were just quirky. Also, a huge annoyance was going into the terminal, typing “mate .” and having it open up a new TextMate window in whatever space already had a TextMate window.
I’m very pleased to report that 10.5.3 solves all of these problems, with one new option in the spaces dialog called “When switching to an application, switch to a space with open windows for the application.” In fact, you want to uncheck this option if you are working in a task-oriented manner like me. There were also some bug fixes in 10.5.3 which transcend this new option.
With these frustrations gone I feel very solid working with 3-5 project workspaces at once and can move efficiently within and among them.
Upgrade to 10.5.3 now if you haven’t already done so!
Posted in Personal | 2 Comments »
April 12th, 2008 benhughes
I had an opportunity to play around with Phusion Passenger (mod_rails) which was just released yesterday. Before yesterday all that was available was an introductory video showing Passenger being configured, and I was quite impressed by it’s ease. Clearly one of the problems with Rails as a major platform right now is it’s hosting situation. Currently the best solution is to proxy HTTP requests from Apache or Nginx to a cluster of mongrels, which is tricky to set up and somewhat tedious - certainly not as as easy as a mod_php in Apache where things “just work”. Phusion set out to overcome this problem and release a module for Apache that hosts Rails applications easily. Here is what took me from a clean Ubuntu 7.10 slice from SliceHost to a working server with Passenger:Starting OutTo start out, I used the following *excellent* SliceHost articles to get some of the basic packages installed such as Ruby and MySQL:Ubuntu Setup - Part 1Ubuntu Setup - Part 2MySQL and RailsApache and PHPApache Virtual HostsVirtual Hosts & PermissionsNote my permissions gotcha below - you may not want to strictly follow their permissions advice (where the global does not have read permission).I also installed sqlite3 as this is now the default database package used in Rails 2.0:
$ sudo aptitude install sqlite3$ sudo gem install sqlite3-ruby
Installing the Passenger Apache ModuleUsing the simple instructions on the Passenger website, I ran:
$ sudo gem install passenger$ passenger-install-apache2-module
The passenger-install-apache2-module binary walks you through the installation of the Passenger. On the first run, it told me I didn’t have some software that was required:
* GNU C++ compiler... found* Ruby development headers... found* OpenSSL support for Ruby... found* RubyGems... found* Rake... found at /usr/bin/rake* Apache 2... found at /usr/sbin/apache2* Apache 2 development headers... not found* Apache Portable Runtime (APR) development headers... not found* fastthread... foundSome required software is not installed.But don't worry, this installer will tell you how to install them....* To install Apache 2 development headers:Please run apt-get install apache2-prefork-dev as root.* To install Apache Portable Runtime (APR) development headers:Please run apt-get install libapr1-dev as root.
Clearly the installer detected I was running Debian-based Linux and told me exactly what to do. No compile errors or nasty dependency issues, just simple and clear instructions. After installing the requisite software the installer compiled the Apache module and spit out this:
The Apache 2 module was successfully installed.Please edit your Apache configuration file, and add these lines:LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.soRailsSpawnServer /usr/lib/ruby/gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-serverRailsRuby /usr/bin/ruby1.8After you restart Apache, you are ready to deploy any numberof Ruby on Rails applications on Apache, without any furtherRuby on Rails-specific configuration!
Note that it didn’t find or attempt to find where apache modules are installed as the actual compiled modules is kept within the Ruby gems directory, it just told me what lines to include in my Apache configuration file. The last part of the installation says:
Deploying a Ruby on Rails application: an example.Suppose you have a Ruby on Rails application in /somewhere.Add a virtual host to your Apache configuration file,and set its DocumentRoot to /somewhere/public, like this:<VirtualHost> ServerName www.yourhost.com DocumentRoot /somewhere/public</VirtualHost>And that's it!
Now this is pretty cool… Passenger doesn’t even require virtual hosts to configure themselves as Rails applications. It will automatically detect a Rails application (I’m unsure of the actual criteria here) based on the DocumentRoot that you provide.So I added the necessary lines specified above to /etc/apache2/apache2.conf to load the module. Note that some deployments of Apache have their own way of managing modules; in Ubuntu there is a mods-available directory with individual configuration files for each module. You could split up the above commands to follow the convention for your system of choice, but for my purposes I just dumped the three lines into apache2.conf.Then I created a new Rails application and pointed DocumentRoot to the Rails public directory. Restart apache, and the site should then immediately work with no further configuration.Permissions Gotcha - Important!If you get:
RAILS_ROOT is not a directory.
The first time I got to this point I was running into an extremely obscure problem - Rails was reporting that RAILS_ROOT wasn’t a directory. After some debugging which involved hacking up the gem source code of both Rails and Passenger, I realized it was a permissions issue (what do you know). Passenger reports that it will run your Rails application as whatever user owns environment.rb. However, it will set the effective group to that user’s primary UNIX group, NOT the group that environment.rb is owned by. In my case, I set the group of all of the web files to www-data and no read or execute permissions whatsoever for other. I figured this would be sufficient since Apache runs as www-data. But in my case when Passenger got spawned, it got spawned running as bhughes:bhughes NOT bhughes:www-data, so it effectively couldn’t find the RAILS_ROOT directory and didn’t think it existed. You can design your permissions scheme however you want, but make sure you keep this in mind. I have an enhancement in Passenger’s ticketing system for fixing this and allowing you to manually set the effective group (you already can explicitly set the effective user through the RailsUser option).More Passenger ConfigurationThe Passenger User’s Guide is pretty good and includes some more specific configuration options you can choose, but the default appears to work fine. The Rails environment is by default set to “production” though this can be changed (sadly, only server-wide, not on a virtual-host basis - but there is an enhancement in the issue tracker for this feature).Restarting Your AppRestarting a Rails app hosted by Passenger is easy - simply touch a file called tmp/restart.txt within the Rails application root:
$ touch tmp/restart.txt
CapistranoBrian Ketelsen pointed out this Capistrano configuration which uses the touch tmp/restart.txt approach to restart and removes the .htaccess file which can cause issues:
namespace :deploy do task :start, :roles => :app do end task :stop, :roles => :app do end task :restart, :roles => :app do run "touch #{release_path}/tmp/restart.txt" end task :after_update_code, :roles => :app do run "rm -rf #{release_path}/public/.htaccess" endend
Diagnosing ProblemsOne of the absolutely wonderful things about Passenger is that problem diagnostics (regarding starting your Rails app) is fairly easy because Passenger includes its own nice error pages:Database Error ExampleFramework Initialization ExampleMemory ManagementOne of the issues with mongrel or thin is that they are constantly running and sucking up memory, even for sites that get very little traffic. This leads to a situation where hosting very low-traffic sites is very inefficient from a system resources perspective. This isn’t the case with PHP where memory usage spikes during traffic but is otherwise unused, allowing multiple sites to leverage the on and offs and maintain a pretty efficient hosting platform as far as memory is concerned. One of the great feature of Passenger is that you can configure it to automatically shut down your Rails application if it is idle for a certain period of time. Doing this obviously exerts a cost then on the next hit, but this may be an acceptable tradeoff for a server hosting many low-traffic sites. The configuration option is RailsPoolIdleTime and there is more information on this in the user guide.ConclusionObviously my introduction here doesn’t go in-depth into performance and ability of Passenger to scale. Time will tell as people begin using this whether it is a viable solution for Rails hosting, but for me installing this and getting it to work was dirt simple, at least compared to the mod_proxy_balancer setup with mongrel clusters I have used in the past. I’m not quite ready to actually host my sites using this but I’ll definitely be keeping my eye on this - it could be a major step forward in the proliferation of Rails hosting.
Posted in Rails General, Rails Tools | 17 Comments »
April 1st, 2008 benhughes
I am convinced this is the next big thing: Cobol on Cogs. Definitely the future of web development. As of today I renounce Ruby on Rails and all it stands for!
Posted in Uncategorized | No Comments »
March 19th, 2008 benhughes
Today I deployed a major update to my Jazz object model which implements a full REST web interface that is currently accessible through a web browser. Visit http://www.jazztoolbox.com/ for the RDocs - there are plenty of examples at the bottom of the index file, or you can try this immediately:
http://www.jazztoolbox.com/chords.xml
Some fairly complex relationships can be explored in this manner just using your web browser (displaying XML). Note that I still do not have a whole lot of data in here; all the data is just my personal knowledge of Jazz theory. Eventually I will consult a theory reference and develop the database of jazz more thoroughly.
Posted in Uncategorized | No Comments »
March 11th, 2008 benhughes
Something I constantly find myself doing is checking to see if a value is blank, and returning something else if it is, otherwise the object itself:
birthday.blank? ? '0000-00-00' : birthday
I started thinking about how I could possibly eliminate the need for all these ternary operators, and came up with this:
class Object
def or_if_blank(value)
self.respond_to?(:blank) && self.blank? ? value : self
end
end
Now we can do something like this:
birthday.or_if_blank('0000-00-00')
You could do something similar for nil, though a more general Ruby idiom is to just use the || operator, which does not work for blank.
On another note, if any of you are used to appending a “if object.respond_to?(:method)” predicate, check out this technique using try.
Posted in Uncategorized | 1 Comment »
February 25th, 2008 benhughes
As a (wannabe) Jazz pianist, I’ve always had a strong interest in Jazz theory not only from a practical you-need-this-to-play standpoint but also a theoretical standpoint. At it’s core, music theory is all about a 0 - 11 number system where each number represents a pitch, with the added complication of letters (which makes Eb theoretically different from D#). Everything in music is based on this basic number system: scales and chords are simply sequences of these numbers. Changing key in a scale or chord mathematically is adding some integer to all of the index values and doing modulo 12. Changing modes within a scale simple involves a position shift of the sequence.
Last week I began exploring the idea of developing some sort of computerized object model to capture these musical theory concepts. As a pianist, knowing theory is extremely important and voicing chords can become quite complex, yet there is sanity in the complexity - a harmony of mathematical precision. Today I introduce “Jazz Toolbox”, the future front-end for which will be located at JazzToolbox.com. Right now I have only developed the back-end object model and calculation engine, which is definitely the foundation of the project. I’ve also written up extensive documentation. Here’s an introduction to the project straight out of my README file:
Jazz Toolbox
Jazz Toolbox is an online Jazz utility driven by a full object-relational and REST model of
concepts in Jazz theory, establishing relationships between chords and scales, and much more.
The web interface is a fully Ajaxified Web 2.0 interface towards exploring these relationships and
answering questions about the jazz science. The REST interface exposes the underlying data model
and relationships to other developers wishing to use Jazz Toolbox as a source for their own web
applications.
Architecture Overview
The core of Jazz Toolbox is a full Ruby object model representing concepts of Jazz theory,
distilled to their most basic concepts and architected in a very abstract manner. The system
is data-centric and all “rules” (for example, the tones in a C7 chord) in theory are
self-contained in the database.
All chord/scale/mode/etc. definitions are stored as a mathematical system (sequences of numbers)
which are then used to perform calculations. For example, putting some chord in a different key
is a matter of adding a semitone delta and doing modulo 12.
While there are currently many chord calculators in existance, to my knowledge this project is the
first one that attempts to fully represent the entirety of Jazz theory as a mathmetical/computational
system exposed through an elegant object model.
Full Documentation
I’ve published the full RDocs which are available here and are very complete.
Examples
Any musician/programmer will appreciate these examples; far more are available in the rdocs:
Chord['Ebmaj7'].notes
# => ['Eb', 'G', 'Bb', 'D']
# Or specify key context with chained methods like this...
Chord['maj7'].in_key_of('Eb').notes
Chord['Bmaj7#11'].notes
# => ['B', 'D#', 'F#', 'A#', 'E#']
# Note E# - Correct theoretic value for this chord, not F
Chord['Falt'].notes
Chord['F7b9#9'].notes
# => ['F', 'A', 'Eb', 'Gb', 'G#', 'C#']
Scale['Major'].in_key_of('Eb').modes['Dorian'].notes
# => ['F', 'G', 'Ab', 'Bb', 'C', 'D', 'Eb']
Scale['Melodic Minor']['Lydian Dominant'].notes
# => ['F', 'G', 'A', 'B', 'C', 'D', 'Eb']
Scale['Major']['Dorian'].chords.symbols
# => ['min7', 'min6']
Chord['Amin7'].modes.names
# => ['A Dorian']
Scale['Major'][4].chords.symbols
# => ['maj7#11']
This is definately still a work in progress though it has the potential to become very powerful. I have high ambitions for the front-end web interface for this as well as it could become a valuable tool for Jazz musicians and others trying to nagivate the complex roads of jazz…
Posted in Uncategorized | 2 Comments »
February 21st, 2008 benhughes
Occassionally I’ll decide to create some structured data in a migration by issuing create statements against my model classes. In a project I’m currently working on, I had to do this several levels deep. Rather than using temporary variables to create the sub items and so-on, all in a lexically flat structure, I came up with this simple one-liner:
def self.with(o); yield o; end
Doing this now allows me to issue those creates with nested data as a series of nested blocks, which is looks much better. For example:
with ChordQuality.create(:name => 'Major', :code => 'MAJ') do |q|
with q.chords.create(:name => 'Major Triad') do |c|
c.chord_symbols.create(:name => 'maj')
c.chord_symbols.create(:name => 'M', :case_sensitive => true)
end
with q.chords.create(:name => 'Major 7') do |c|
c.chord_symbols.create(:name => 'maj7')
c.chord_symbols.create(:name => 'M7', :case_sensitive => true)
with c.children.create(:name => 'Major 7 #11') do |cc|
cc.chord_symbols.create(:name => 'maj7#11')
cc.chord_symbols.create(:name => 'M7#11')
cc.chord_symbols.create(:name => 'lyd')
cc.chord_symbols.create(:name => 'lydian')
end
end
with q.chords.create(:name => 'Major 6') do |c|
c.chord_symbols.create(:name => 'maj6')
c.chord_symbols.create(:name => 'M6', :case_sensitive => true)
end
end
Oh, the beauty of Ruby code blocks!
Posted in Uncategorized | No Comments »
February 7th, 2008 benhughes
Since working with Ruby and other dynamic languages, I’ve thought a lot about the differences between statically-typed and dynamically-typed languages and what makes them different. Statically-typed languages guarantee some level of confidence of workability — but this comes at a huge cost of flexibility, and more importantly overlaps with software testing, not making efficient use of the concept of testing.
Software testing can be used to make up for some of the lost confidence resulting from dynamic typing, yet since they must be done regardless, the outcome is suboptimal with static languages - there is an overlap between the confidence generated from static typing and the confidence generated from the test suite. With dynamic languages there is much less overlap: the test suite makes up for the confidence lost from dynamic typing, yet is also there to ensure the software works as expected.
Posted in Ruby Evangelism, Ruby Language | No Comments »