DB Content Rails Plugin 2

Posted by Oliver on April 17, 2008

The DB Content Rails plugin adds tasks to save and restore database content.

Usage

-- dump the development database to db/archive/development-content.sql.gz
rake db:content:dump

-- load the dumped database, and apply any necessary migrations
$ rake db:content:load

-- dump the production database to db/archive/production-content.sql.gz
$ RAILS_ENV=production rake db:content:dump

-- save the development database to db/archive/{timestamp}.sql.gz
$ rake db:content:save

-- save the (compressed) database to my-data.sql.gz
$ rake db:content:save FILE=my-data.sql.gz

-- save the (uncompressed) database to my-data.sql
$ rake db:content:save FILE=my-data.sql

-- load the database from my-data.sql
$ rake db:content:load FILE=my-data.sql

Tasks

rake db:content:archive

Saves a timestamped database to db/archive/{timestamp}.sql.gz.

rake db:content:dump

Dumps the database to FILE or db/{RAILS_ENV}-content.sql.gz. If FILE ends in .gz, the file is compressed.

rake db:content:load

Loads the database from FILE or db/{RAILS_ENV}-content.sql.gz, and migrates it to the current schema version. If FILE ends in .gz, the file is piped through gunzip.

Installation

git clone git://github.com/osteele/db_content.git vendor/plugins/db_content

If you’re running off Edge Rails (or, presumably, Rails > 2.0.2), you should be able to do this instead:

script/plugin install git://github.com/osteele/db_content

Limitations

The plugin works only with the MySQL databases. (It adds methods to the Mysql adaptor; see the source.) The gzip option probably only works on *nix (MacOS, Linux, etc.).

JCON: Ruby Gem for JSON type conformance

Posted by Oliver on April 17, 2008

JCON (the JavaScript Conformance gem) tests JSON values against ECMAScript 4.0-style type definitions
(PDF) such as string?, (int, boolean), or [string, (int, boolean), {x:double, y:double}?].

Usage

type = JCON::parse "[string, int]"
type.contains?(['a', 1])     # => true
type.contains?(['a', 'b'])   # => false
type.contains?(['a', 1, 2])  # => true

JCON also defines an RSpec matcher, conforms_to_js:

[1, 'xyzzy'].should conform_to_js('[int, string]')
[1, 2, 'xyzzy'].should_not conform_to_js('[int, string]')  # 2 isn't a string
{:x => 1}.should conform_to_js('{x: int}')

Use JCON together with the JavaScript Fu Rails plugin to test the argument values to functions in generated JavaScript:

# this will succeed if e.g. response contains a script tag that includes
#   fn("id", {x:1, y:2}, true)
response.should call_js('fn') do |args|
  args[0].should conform_to_js('string')
  args[1].should conform_to_js('{x:int, y:int}')
  args[2].should conform_to_js('boolean')
  # or:
  args.should conform_to_js('[string, {x:int, y:int}, boolean]')
end

Whence

Github for the sources.

Rubyforge for docs.

gem install jcon to install.

License and version

MIT License, of course.

JCON is at version 0.1 because it’s just a few days old and I had to guess about the ECMAScript 4.0 type syntax from the examples in the overview. I can’t imagine that I got everything right.

JavaScript Fu Rails Plugin 3

Posted by Oliver on April 14, 2008

JavaScript Fu extends Rails with a few facilities to better integrate JavaScript into Rails development:

1. The notes and statistics rake tasks compass JavaScript files in the public/javascript directory:

$ rake notes
public/javascripts/controls.js:
  * [782] [TODO] improve sanity check
$ rake stats
| Name                 | Lines |   LOC | Classes | Methods | M/C | LOC/M |
[...]
| JavaScript           |  7287 |  6322 |       0 |       0 |   0 |     0 |
[...]

2. The call_js RSpec matcher asserts that a string or response contains a script tag, that contains JavaScript that calls the named function or method:

response.should call_js('fn')
response.should call_js('fn(true)')
response.should call_js('gApp.setup')

If you pass a block to call_js, it’s called back with the argument list, parsed as though it were a JSON array:

# matches <script>fn(1, 'aString', {x:10,y:20})< /script>
response.should call_js('fn') do |args|
  args[0].should == 1
  args[1].should == 'aString'
  args[2].should == {:x => 10, :y => 20}
end

Use this with jcon to test for type conformance, using ECMAScript 4.0 type definitions. (Well, you can’t use it with jcon yet, because I haven’t released it — this is just a teaser. But you can peek.)

response.should call_js('fn') do |args|
  args[0].should conform_to_js('[Array, (int, boolean)]')
  args[1].should conform_to_js('{x: double, y: double}')
  # or just:
  args.should conform_to_js('[[Array, (int, boolean)], {x: double, y: double}]')
end

3. The page.onload page generator method generates code that executes the content
of the block upon the completion of page load:

page.onload do
  page.call alert', 'page loaded!'
end

These lines generate one of these (depending on whether the jRails plugin has been loaded):

Event.observe("window", "load", function() { alert("page loaded!"); });
$(document).ready(function() { alert("page loaded!"); });

Gitting It

JavaScript Fu is hosted on git. If you have git installed, you can clone it into your Rails directory thus:

git clone git://github.com/osteele/javascript_fu.git vendor/plugins/javascript_fu

If you’re running off Edge Rails (or, presumably, Rails > 2.0.2), you should be able to do this instead:

script/plugin install git://github.com/osteele/javascript_fu

Otherwise, you can simply download the tarball from here.

Update: changed the conform_to_js example so that it actually works with the (albeit unreleased) plugin..

FizzBuzz Station 4

Posted by Oliver on February 28, 2008

Uh oh! I overthought fizzbuzz:

Continue reading…

reWork: an online workbench for regular expressions 2

Posted by Oliver on February 23, 2006

reAnimator got me interested in writing something that would let you use regular expressions. That something is reWork. This web page has a couple of fields where you can type in a regular expression and a string to match it against, and see the results update as you type. It also displays the code to perform the match in some of the languages (JavaScript, PHP, Python, and Ruby) that I use with regular expressions.

reWork limited to the features of the JavaScript regex engine. In particular, it’s missing dotall (/.../s), because JavaScript is. I actually figured out a hack to implement dotall anyway, but this will have to wait for another day.

I suspect that it still has bugs involving scanning and splitting on regular expressions that match the empty string, and browsers that aren’t Safari and Firefox 1.5, but I’m publishing this now in the hope that it will be useful anyway.

OpenLaszlo Ruby library

Posted by Oliver on January 05, 2006

openlaszlo.rb is a Ruby library for compiling OpenLaszlo programs. I use it to build this, this, and the toolbar here. This article describes how to use it with Rake.

Update: This is now available as a gem. The rdocs are here.

Ruby and Laszlo 3

Posted by Oliver on March 08, 2005

I first heard of Ruby at the second Lightweight Languages Workshop 2, where Matz and I were both speakers. This was first public disclosure of the then-proprietary Laszlo platform language. I’m afraid I was more worried about preparing my talk then listening to Matz at the time!

Since then, a number of different people have expressed interest in both Laszlo and Ruby. I figured I had finally better take a look at it.

I understand what the fuss is about. Ruby is one of the rare languages with a readable embedded syntax for metaprogramming, it’s well designed, and it has a mature library for web programming. What this translates to in practice is that you can program in a language with “keywords” (really just functions) suitable to the task at hand.

Compare the two class definitions below:

class Person < Object
  attr_reader :name
  attr :location
end
class Person < ActiveRecord::Base
  has_one :name
  has_many :address
end

The first definition uses the core language syntax to define a Person class that contains a getter for name, and both getters and setters for location. The second uses Rails to define a Person Active Record that has one name record and many address records. (It uses the Foreign Key and Association Table patterns, respectively.) The cool thing is that attr and has_one look the same to the library user. Ruby allows the library developer to grow a language. This lets the library user write in a concise domain-specific language that embeds Ruby.

What does this mean in practice? During my last vacation it took about five lazy vacation days with Ruby on Rails to implement a fairly sophisticated 40-page web application with five models, two metamodels, CRUD, cookies, image upload, and login. (I’ll write more about the application itself, if I find a few free weekends to harden it for public use.) For comparison, it took me about the same amount of time during my previous vacation to write a much simpler ten-page PHP web application that had only one model. And I already knew a little bit of PHP, whereas I was learning Ruby and Rails from scratch.

Now, what does this have to do with Laszlo? Laszlo certainly doesn’t have any metaprogramming facilities. It has states, constraints, and data binding, which extend the reach of declarative programming beyond static layouts. (Yeah, yeah, I should write about this too; in the meantime there’s docs and examples here and here.) I suspect that some of the people who “get” how to use metaprogramming in Ruby also get how to do declarative programming with the Laszlo features. But I also think a large part of what Laszlo brings to the table is simply that it allows you to use conventional OO techniques in client-side browser programming. For example,

<canvas layout="axis: y">
  <view width="10" height="10" bgcolor="red">
    <view x="1" y="1" width="8" height="8"/>
  </view>
  <view width="20" height="20" bgcolor="red">
    <view x="1" y="1" width="18" height="18"/>
  </view>
  <view width="30" height="30" bgcolor="red">
    <view x="1" y="1" width="28" height="28"/>
  </view>
</canvas>

DRYs out to:

<canvas layout="axis: y">
  <class name="box" width="${this.size}" height="${this.size}" bgcolor="red">
    <attribute name="size" value="10"/>
    <view x="1" y="1" width="${parent.width-2}" height="${parent.height-2}"/>
  </view>
  <box/>
  <box size="20"/>
  <box size="30"/>
</canvas>

This (OOP) is old hat in the server-side world — just like MOP is old hat to Smalltalk and Common Lisp developers — but it’s relatively new in the world of zero-install client-side platforms. So I think the analogy between Ruby on the server, and Laszlo on the (much more resource-constrained) client, is that each of them advances advances the reach of non-academic programming:

Update: Now that I’ve done more Ruby and DHTML programming, I can see that the diagram above gives OpenLaszlo short shrift. Although OpenLaszlo is lower level that Ruby with respect to code generation and a MOP, the use of databinding and constraints makes it higher level in a different set of ways.