Virtual Surreality

It's too real to be true

Browsing Posts in Coding

Came across this twice in the past two weeks.

How NOT to do it:

$('form :submit').click(function() {
    $(this).attr("disabled", true);
    $(this).val("wait...");
    $(this).addClass("disabled");
});

Doing it the above way, the click event will indeed fire, but on some browsers the submit event will not.

The event to bind to is submission of a form, not clicking of a submit button.

How to do it:

$('form').submit(function() {
    $(":submit").attr("disabled", "disabled");
    $(":submit").val("wait...");
    $(":submit").addClass("disabled");
});

Also, the :submit selector is a jQuery cross-browser selector for input and button elements that could submit the form, used in preference to input[type="submit"]

A little “remember me later” for conditionally deploying a Rails 3 app running on Ruby 1.9 on Heroku.

$ruby_version = `ruby --version`.split[1].to_f
$heroku = ENV['USER'].match(/^repo\d+/)

source :rubygems
source 'http://gems.github.com'

gem 'rails', '3.0.0.beta4'
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'bson_ext', '~> 1.0.1'
gem 'decent_exposure'
gem 'haml'
gem 'mongoid', '>= 2.0.0.beta.9'

unless $heroku
  if $ruby_version < 1.9
    gem 'ruby-debug'
  else
    gem 'ruby-debug19'
  end

  group :development, :test do
    gem 'rspec-rails', '>= 2.0.0.beta.17'
    gem 'rails3-generators' #for HAML
  end
end

The --without=test option isn’t (yet) being used on Heroku deploys, thus the :test group is in the unheroku block. Update: check if .bundle/config WITHOUT="" works.

Update: Mongoid changed gem versioning for lexicographical sorting (a “dot” between “beta” and the number
Update: Latest mongoid (beta.16 and something after beta.9) requires Rails 3.0.0.rc which doesn’t support Ruby 1.9.1 which isn’t yet on Heroku
Update: Heroku user doesn’t have “repo” in it anymore and USER env var isn’t available – find new mechanism if bundler config WITHOUT option doesn’t work

Also:

  • Only the --colo(u)r and --format options work in the .rspec file
  • use_transactional_fixtures=false in spec_helper.rb (talk to Chelimsky about transactional fixtures in non-ActiveRecord environments)
  • In application.rb:
    • require 'mongoid/railtie'
    • require 'decent_exposure/railtie'
    • g.orm :mongoid
    • g.template-engine :haml
    • g.text_framework :rspec, :fixture => false, :views => false

Object/Relational Mappings (ORM’s) are in the wrong place in the architecture.

An application should have minimal impedance mismatch with the persistence of its own data. External or ancillary systems should bear the cost of mapping between paradigms. If you are writing an application with the concepts modelled in an object-oriented fashion, then the state of those objects should be stored in an object-oriented fashion. Mapping from the object-oriented structure to a relational structure should be done where and when it’s needed. If you want to access application data in a relational way for reports, do the mapping for the report.

There has been a low uptake of OODBMS’s. Why is outside the scope of this post. However, there are other, older (albeit feeling newer) data storage techniques available that more readily persist an object graph than a relational database. A flurry of open-source implementations have come along. You may have heard of MongoDB, neo4j, Redis, Hadoop, CouchDB, Memcached, and Raven DB (a native .NET document database). These are all under active development, and almost all have been proven on many large commercial projects (Raven was being developed by Oren while he was at speakerconf 2010!).

For an introductory look at evaluating the landscape, check out Sarah Mei’s RailsConf presentation slides.

One of the projects I’ve worked on at Hashrocket involved a large MongoDB database. The reasons for the choice for MongoDB were clear:

  • the way the users handled most of the data more naturally fitted an embedded document model;
  • the scale and speed required were far greater than relational databases could achieve; and
  • the need for ACID transactions was almost nil

Additionally, the data was mostly read, rather than written (although MongoDB writes blazingly fast too). I’m hoping to address the equivocations in those reasons in a subsequent post.

MongoDB uses a binary form of JSON. As JSON is a serialization format for object state, it’s a good candidate for persisting an object graph. JavaScript, remember, uses composition rather than inheritance, so there is also a tendency to “embed” document instances within other document instances. So, for MongoDB, most of the object graph is stored a tree structure. Cyclic graphs and associated objects (those that aren’t aggregated with composition) are handled with references to identifiers.

As a consequence of using Rails and MongoDB, the team looked to various ways of manipulating the JSON structures from Ruby: directly through the driver, MongoMapper, MongoDoc, and Mongoid. The rationales behind these libraries and their different and interesting approaches are the subject of additional blogs (hopefully jointly with Nunemaker, Hill, and Jordan respectively). The needs and makeup of the project we were on fell into the lap of mongoid to solve.

DBAs want to interact directly with the database. Because of this “new-fangled” approach to data storage that has been around since before SQL, some are unwilling or unable to learn the query language to interact directly with the database. So, to make their world a less scary place and let them retire without the stress of intellectual endeavour, I built a simple, declarative language where the mapping from the tree structure of MongoDB to the tuple space in an RDBMS can be scripted.

Durran Jordan (author of Mongoid) and I paired on “squealer” (and on emptying bottles) in our evenings while he was stationed in the Chicago office of Hashrocket. The name came from “SQL” (which some of us still pronounce “squeal” rather than “sequel”) and the facetious notion that it turned the data into a pig.

We decided to focus on mySQL as the target and MongoDB as the source as these are the technologies we were using. Upcoming targets will include PostgreSQL, SQL Server, Oracle. Upcoming sources will include Redis and CouchDB.

UPDATE: squealer 2.2 now supports PostgreSQL!

Matt Yoho provided multiple insights into implementing the Ruby DSL, and Bernerd Schaefer helped me reduce the DSL syntax and provide sensible defaults (as well as the righteous progress bar). Bernerd then struck on the idea of reflecting on the Mongoid declarations in the Rails domain model classes to generate an initial squealer script and SQL DDL to build the target SQL database. He then set about writing it overnight and we tweaked it over lunch. We called this tool “skewer”, because that’s what you do to something to make it squeal ;-) . It’s part of the squealer RubyGem.

Next time: how to use skewer and squealer.

Announcing PreparedEval, prepared statements for generating JavaScript (and the like) from Java. It prepares Java strings for JavaScript evaluation, similar to SQL prepared statements. Saves you from quote escape nightmares! Great for Selenium tests and Rhino JavaScript.

As a follow-up to my post on escaped, quoted strings, Taking the idea of using a different encoding scheme further (and not being super happy about the need to pump the string through unescape()) I thought about interpolation and wondered about prepared statements in SQL. Some quick research turned nothing up, but while chatting with Ola Bini he also mentioned prepared statements, so this convinced me to knock something together that might be useful.

More information is at http://wiki.github.com/delitescere/PreparedEval.

There’s no runtime dependencies so it’s nice and tiny if you just want the JAR.

Let me know if you use if to help with CSS / XPath selectors for Selenium or if you have any suggestions on improving the API.

When you have more backslashes than words in the strings you are constructing, perhaps it’s time to look at another way of handling special characters like quotes.

The problem

You’re generating JavaScript code from another language with C-like quoting and escaping syntax (e.g. Java).

As part of that code generation, you’re substituting strings that have both double quotes (“) and single quotes (‘). My team’s actual problem stems from using XPath locators which include quoted text and sending that to Selenium so we can obtain the particular element that contains the text*.

Let’s say we want to pop up an alert within which are some double quotes:

String original = "Hello \"stranger\", how are you?";
String quoted = original.replaceAll("\"", "\\\"");
String script = "alert(\"" + quoted + "\")";
eval(script);

We then expect the browser to have this JavaScript code to process:

alert("Hello \"stranger\", how are you?")

and when then expect the alert to display the string:

Hello “stranger”, how are you?

But why doesn’t it work?
continue reading…

Should it be assertEquals(expected, actual) or assertEquals(actual, expected)?

This discussion came about because at the Chicago Code Camp, Jim Suchy from 8th light was demonstrating TDD in JavaScript by building a simple unit testing library. One of the methods he created was the typical assertEquals. In the code on github he had a signature of assertEquals(expected, actual) while during the demo he swapped the order, and I pointed out that the original was what I would have anticipated. He commented that there was an interesting discussion about it at his office a few days before. I’m interested to hear more about it, and I tweeted that I was inclined to get a debate going about it just to see what the different rationales were. This post is a collation of thoughts and opinions to date.
continue reading…

CodeMash

2 comments

I’ve been given the privilege of speaking at CodeMash 2009 in Sandusky, Ohio this coming January.

The presentation and discussion will cover the learning from implementations of Guerilla SOA and will include code and demonstration based on the WCF. It may change some minds about the default approach to the WCF programming model and open some eyes on how to build a truly message-oriented service oriented ecosystem.

Looking forward to a conference that comes highly recommended.

The submitted abstract

Title: Guerilla SOA for WCF
Track: Arch & Design
Level: Intermediate

Description:
This talk goes over the fundamentals of Guerilla SOA (a concept conceived in ThoughtWorks and championed by Dr Jim Webber) and how they are applied to WCF in both a SOAP and REST context.

Using principles from agile software development into an emergent architecture, particularly for services, the talk looks at an alternative approach to the usual usage of the WCF programming model which provides a true message-oriented approach (rather than the RPC hole almost every WS-* stack drives us into).

Drawing on real large-scale projects, we’ll touch on consumer-driven contracts, sensible XSD, alternate validation techniques, LINQ to XML, XPath, and a convention-based and MVC approach to web service implementation.

My colleague Jay Fields recently blogged about the value of test names.

We had a little discussion about it yesterday on IM. Here’s a summary.

Josh Graham

I feel the test name is important for two reasons:
1) it is intentional programming – a neural pathway is established in your brain as you write the name of the test method so your mind tries to think about what the hell you are trying to achieve by doing all that typing
2) for those test consumers you speak of to get a sense of the behaviour of the system as specified by the stories and high level acceptance criteria

Jay Fields

2) [is] fair enough. Before introducing expectations on any client project I’ve brought it up as “what do you think about” and let the team decide. The last thing I want is an idea to be branded as bad because the wrong ppl used it
1) I think is based on the person. I always found it 10 times harder to write a sentence, I just want to get to the code but, I’m crazy for making the code intention revealing

Josh Graham

Picking a reasonable moniker for the test name is useful too, when something breaks (particularly if it occurs often)… “That #$%#$%! shouldRejectLostOrStolenCard test is failing again – must be the clearing house API has changed or they’ve crashed once more”.

Jay Fields

yeah, that’s an interesting point
wish you would have replied with that one, I’d have put it in my entry

We then talked about how to attach a moniker to the test on different languages – method names in Java being the easiest, while anonymous inner classes being a way to do so without having a moniker (other than perhaps a comment) at all.

I still contended that a method was a reasonable level of granularity to contain a test and use the method name as the moniker. A method (it’s declaration and its body) is location independent – it can be moved around in its module and you can still find it and its moniker appears in the abstract syntax tree so it’s very easy to find when using an editor that maintains an AST.

Jay’s responses to my scenarios in which this proves useful assume a short TDD cycle and also good developers.

So, while the test name may be superfluous in some cases, I don’t mind the extra mental effort of summarising the intent of the test into its name – and if that is overly difficult or not needed (both of which are plausible) then a banal label like enclosing the test in a method called “test1″ is a small price for me to package it up in a manageable, easy-to-find chunk.

YMMV.

My CTO, Rebecca Parsons, announced the publication of the ThoughtWorks Anthology a few days ago:

I am thrilled to announce that the ThoughtWorks Anthology is now ON SALE!

http://www.pragprog.com/titles/twa

There are essays by Roy and Michael Robinson, Martin, Neal Ford, Tiffany Lentz, Stelios Pantazopoulos, Ian Robinson, Erik Doernenburg, Kristan Vingrys and James Bull, as well as ex-TWers Dave Farley, Jeff Bay and Julian Simpson. (And of course your’s truly made her own contribution). Mike Aguilar wrote the introduction.

Some comments that appear in the book:

Jim Fischer writes, “The anthology provides a peek into the diversity of views and perspectives held by a company that dares to take on the long-accepted tenet of the IT industry that custom software is too hard and too costly.”

Big Dave Thomas writes, “Software is in many ways a team sport, and the leaders shape the software culture. Often successful organizations don’t take the time to document them, and hence others don’t benefit from them. This interesting collection of personal essays gives a glimpse into the culture of ThoughtWorks through some of its leaders.”

I’m really excited that this project has come to fruition and I hope you all enjoy what you see.

Rebecca

I was lucky enough to review the content earlier this year. It’s a keeper.

UPDATE: Some press… http://www.sys-con.com/read/541124.htm

After a meeting of the office of the CTO, most of us stayed around in our San Francisco office for a few days to do some podcasts and to participate in a Code Jam for Inveneo, a not-for-profit who provide computers and connectivity to developing countries (especially their schools, hospitals, and poorer villages).

They install a server in, say, a hospital with a few lower-powered, custom desktops (almost iMac in configuration). These, as well as the servers, can run off solar panels for power.

We were presented with a worthwhile problem with a number of interesting constraints:

  • Low-power server running Ubuntu, with two small SATA hard disks in a Linux software RAID-1 array
  • VMWare images of the servers for testing
  • Python, bash, mdadm, and beep as our “programming languages”

When a RAID array fails, we need to alert any (if any) humans who are near the server. This can be interesting as the only things nearby might be the tree it is mounted in with a long-range WiFi, or the goat who uses it as a heat source at night. This means that any alert should be sufficiently frequent and annoying for the locals to contact someone who can let the support technician know. The conflict is that it also might be the nurses in their office at the hospital who have work to do and don’t want to be disturbed.

The solution was to use the PC speaker to beep. We can control the pitch and duration of the beep. Some combinations sounded too much like an ECG machine so that was no good. In the end, we chose a simple rising scale that would sound odd in any environment (except, perhaps, in a Mike Oldfield recording). This is repeated by default every 30 minutes.

We also had to send an email to the support technician. This doesn’t work when the server doesn’t actually have any connectivity (as some are used only as a local communications hub), or when connectivity is unreliable. Even then, many of the technicians are hours or even days away from the servers.

As many of the technicians aren’t particularly technical, we also had help by identifying which of the two disks had failed and allow them to simply change the one labelled “Disk 1″ or “Disk 2″. Serial numbers are good for this but VM hard disks don’t have serial numbers (I think that’s a feature request to both VMWare and Parallels).

We had Jeff Wishnie from Inveneo as the customer, Anda Abramovici as IM, Jonny Leroy as BA, Paul Hammant and Chad Wathington as QA, and the star developer crew of Drew Olson, Sammy Zahabi, Ola Bini, Erik Doernenburg and your’s truly. We quickly learned the following:

  • The skills we needed (and had, just a little rusty) were more along the lines of Unix devices, shell, ASCII control characters, and simulation
  • Python sucks (a bad tradesman blames his tools? perhaps – but it still sucks)

Anyway, we got most of what we wanted done in the time, and given the context, more than we anticipated. But we all would have liked to get a lot more done and would have if we were using our tools of choice (which are chosen for very good reasons).

Nonetheless, we’re doing it for the kids and it was great!

What a buzz. Super Agile. Super Fun. Go Inveneo, you rock!!