Archive for October, 2007

TextMate: On the fly JavaScript evaluation with Rhino

Sunday, October 28th, 2007

For those interested in developing JavaScript outside the browser, Rhino is one of the natural choices. It seems to combine the best of both the dynamicaly and statically typed worlds. Rhino offers a Shell for dynamic script evaluation, along with the option to compile the scripts into Java classes and reap any advantages compiled software has on display. It’s a mature platform, built with performance in mind, leveraging a robust VM.

In order to evaluate scripts using Rhino in TextMate in a similar fashion to that of the Run command ("cmd R") from the Ruby Bundle:

Provided that Java is installed on the system and the $JAVA_HOME
environment variable has been set, download Rhino, unpack it somewhere and set an environment variable ($RHINO_HOME) to point to the unpacked Rhino distribution directory. I keep these environment variables in ~/.profile. Open the Bundle Editor in TextMate, navigate to JavaScript and add a new Command. From the Save drop-down, pick Current File, set Input to Entire Document, Output to Show as Tool Tip and Activation to Key Equivalent. I chose "cmd E" as the hot-key for invoking the Command.

Here’s the script for the Command(s) input:

echo Evaluating : "$TM_FILEPATH"
echo
echo
$JAVA_HOME/bin/java -classpath $RHINO_HOME/js.jar \
org.mozilla.javascript.tools.shell.Main -f $1 "$TM_FILEPATH"

Sample output:

textmate-rhino-js

A more prototype based JavaScript

Wednesday, October 24th, 2007

JavaScript, like io, is a Prototype-based language. Prototype-based programming is a variation of OO, one of the main differences being the absence of classes. Objects are not instantiated, but are instead cloned, with additional behavior defined on the clones of the Prototypes.

Io provides a clone method, with the option to specify the cloned object’s state and behavior within a do construct:

Person := Object clone do(
  givenName := "Kirk"
  surname := "Hammett"
)

JavaScript allows functions to be used in conjunction with the new keyword, thus acting as Constructors.

person = function(givenName, surname) {
  this.givenName = givenName
  this.surname = surname
}

kirk = new person('Kirk', 'Hammett')

The use of new presents a, perhaps, odd choice for a language without classes that need to be instantiated from their static definitions. It would be interesting to have the option to code a cloned Object’s state, behavior and composition within the scope of its cloning.

For example, let’s extend JavaScript’s base Object by giving it a clone function:

Object.prototype.clone = function() {
  var target = {}
  for (var i in this) {
    if (target == this[i]) {continue}
    if (typeof this[i] == ‘object’) {target[i] = this[i].clone()}
    else if (this[i] != undefined) {target[i] = this[i]}
  }
  if (arguments[0]) {arguments[0](target)}
  return target
}

The clone function effectively copies all of the Prototype’s attributes, functions, etc to the cloned object. In addition, it passes a reference of the target as an argument to a delegate function which can be provided as an argument to clone. This can be used to configure the cloned object within the scope of the clone function:

Guitarist = Object.clone(function(g) {
  g.shred = function() {alert('shred!')}
})

kirkHammett = Guitarist.clone(function(kirk) {
  kirk.guitar = 'ESP'
  kirk.plays = function() {alert(kirk.guitar)}
})

kirkHammett.shred()
kirkHammett.plays()

What about composition? Objects in io can attach unlimited protos to their slots. Similarly, JavaScript objects are open to modification and extension at runtime, although I am not aware of a standard way to achieve mixin functionality in core JavaScript - jQuery and the Prototype Framework both offer extend functions.

For the above example, we could have something like:

Object.prototype.mixin = function(other) {
  for (var i in other) {
    if (this == other[i]) {continue}
    if (typeof other[i] == ‘object’) {this[i] = other[i].clone()}
    else if (other[i] != undefined) {this[i] = other[i]}
  }
}

With the mixin function, objects can be extended through composition:

Repeater = Object.clone(function(r) {
  r.times = function(i, delegate) {
    for (var j=0; j < i; j++) {delegate(j)}
  }
})

Guitarist = Object.clone(function(g) {
  g.shred = function() {alert('shred!')}
})

kirk = Guitarist.clone(function(k) {
  k.mixin(Repeater)

  k.shredThreeTimes = function() {
    k.times(3, function() {k.shred()})
  }
})

kirk.shredThreeTimes()

I find experimenting with this approach in JavaScript possibly offers a more structured, concise development canvas.

Queueue version 0.0.4

Saturday, October 20th, 2007

A new version of Queueue is available for download.

This is mostly a maintenance release. The HTTP header date is now validated based on the format required by AWS SQS. An example valid header date would be: Sat, 20 Oct 2007 14:45:15 BST

Embedding Queueue

Monday, October 1st, 2007

As of version 0.0.3, Queueue can be embedded in Ruby code through its QueueService interface. In this mode, Queueue could be used as a simple alternative for instrumenting message driven Ruby code.

require "rubygems"
require "queueue"

QUEUE_NAME = "queue"
SERVICE = Queueue::QueueService.new

SERVICE.create_queue QUEUE_NAME
SERVICE.set_visibility_timeout QUEUE_NAME, 5

listener = Thread.new do
  loop do
    messages = SERVICE.receive_message QUEUE_NAME
    messages.each do |msg|
      p msg.body
      SERVICE.delete_message QUEUE_NAME, msg.message_id
    end
  end
end

talker = Thread.new do
  %w(We've been dancing with Mr Brownstone).each do |msg|
    SERVICE.send_message QUEUE_NAME, msg
    sleep 2
  end
  p "Done. Exiting running threads"
  Thread.list.each { |t| t.exit! }
end

talker.join
listener.join

Another interesting scenario can involve QueueService combined with DRb as a means to instrumenting distributed Ruby processes.

An instance of QueueService wrapped inside a DRb server:

require "drb"
require "rubygems"
require "queueue"

DRb.start_service "druby://0.0.0.0:7777", Queueue::QueueService.new
DRb.thread.join

And DRb clients posting and consuming messages:

require "drb"
require "rubygems"
require "queueue"

service = DRbObject.new nil, 'druby://0.0.0.0:7777'
service.create_queue 'q'
service.send_message 'q', "We've been dancing with Mr Brownstone"
messages = service.receive_message 'q'
messages.first.body # => "We've been dancing with Mr Brownstone"

Queueue turns 0.0.3

Monday, October 1st, 2007

A new version of Queueue (0.0.3) is available for download.

New in this version

The Queueue::QueueService API can be embedded in Ruby programs and used independently from its Mongrel backed, RESTFul HTTP interface.

RDoc for Queueue::QueueService and related assets.