Thursday, September 9, 2010

Ruby Procs

I've just started learning Ruby in conjunction with the Ruby on Rails framework. Going through my first Rails tutorial, I found myself trying to understand the respond_to code in my generated controllers. This lead me to an examination of Ruby's block and proc constructs. While experimenting I discovered that there's at least two ways to declare blocks, and three ways to instantiate Ruby Procs. Counting the 2 block variations, you may see 6 permutations of Ruby Proc instantiation.

strings = ["Foo", "Bar", "Blah"];

# Below is 6 functionally similar first-class Procs defined in different ways.
procs = []
procs.push(lambda {|x| print x})
procs.push(lambda do |x| print x end)
procs.push( {|x| print x})
procs.push( do |x| print x end)
procs.push(proc{|x| print x})
procs.push(proc do |x| print x end)

procs.each {|i| puts i}
# Prints:
#<Proc:0x0000010086a8c0@blocks_and_procs.rb:5 (lambda)>
#<Proc:0x0000010086a898@blocks_and_procs.rb:6 (lambda)>

for i in 0..5
print " of proc #{i}: " &procs[i]
print "\n"
# Prints of proc 0: FooBarBlah of proc 1: FooBarBlah of proc 2: FooBarBlah of proc 3: FooBarBlah of proc 4: FooBarBlah of proc 5: FooBarBlah

# And here's the inline methods of passing a block.
print " of do block:" do |x| print x end
print "\n"

print " of {} block:" {|x| print x}
print "\n"
# Prints of do block:FooBarBlah of {} block:FooBarBlah

You may notice that a dump of my procs yields two instances which note they're lambdas. Lambda and have subtle differences in their argument checking and the way returns are handled from the Proc. See this link for more detail.

Admittedly, I couldn't help but be a little disappointed that there's so many ways to accomplish the same simple thing with Ruby. Particularly when one of its prized attributes is a syntax that is simple and consistent.

Sunday, February 15, 2009

Software Documentation with Docbook, FOP, and Ant

For a long time I had been looking for a standard way to create conceptual documentation for software projects. It took some experimentation, but I think I've finally found an approach that I like. Here's how I got there.
  • Wiki - Wiki definitely serves the purpose of quick collaborative documentation creation, however over time I found myself getting in to trouble. A description of an API or XML Format would change, and I would update the wiki accordingly. Unfortunately the feature I was working on hadn't made it to production yet, so the users of the wiki documentation would then be reading documentation that was ahead of its time, resulting in mass confusion.
  • Source-Controlled HTML Documentation - This approach solves for the versioning issues noted with the Wiki approach by adding the documentation to version control right next to the source code. Unfortunately there was about 30 different ways I could create several paragraphs of description mixed in with code snippets. Add in a little styling to the mix, and the HTML source quickly becomes unreadable.
  • Semantic XML Language that generates HTML - This approach fixes the unreadable HTML source issue, and allows for the documentation to live with the source code in version control. The only issue remaining issue is what is possible confusion over where to document. For example, if a new developer on a project using this approach checkes out, and builds, he or she may not immediately realize that the generated HTML documentation is in fact generated. Not a huge issue, and there are ways around this, but still something that is within the realm of possiblity.
Finally I arrived at the magic combination of Docbook, FOP, and Ant, with the docbook source living in version control. Using an output representation that is essentially a read-only format removed any confusion over what is generated, and what is not. Let me describe the tools and document types involved.

Docbook is a nice semantic XML markup language convenient for technical documentation. It can be transformed into a variety of formats varying from PDF to HTML. There's a decent reference guide here. The source looks something like this.
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN">

<title>An Example Article</title>

<firstname>Your first name</firstname>
<surname>Your surname</surname>

<holder>Copyright string here</holder>

<para>If your article has an abstract then it should go here.</para>

<title>My First Section</title>
<para>This is the first section in my article.</para>
<title>My First Sub-Section</title>
<para>This is the first sub-section in my article.</para>

Apache FOP (Formatting Objects Processor) is a print formatter driven by XSL formatting objects (XSL-FO) and an output independent formatter.

Apache Ant is a Java-based build tool. I use Ant for nearly all of Java and Non-Java development projects.

The build script for the project has the job of generating the documentation as a PDF. To do this, two steps are required. First the Docbook FO XSL file is applied to your XML documentation file in Docbook format which generates a FO document. Second, Apache FOP's Ant task then generates the PDF from the FO document. It's that simple. Your Ant target will end up looking something like this:

<target name="doc" depends="doc.upToDate" unless="doc.notRequired">

<!-- Create the FO doc -->
<xslt basedir="doc" includes="MyProject.xml" style="${build.docbook.dir}/docbook-xsl-1.73.2/fo/docbook.xsl"
destdir="${build.documentation}" extension="-fo.xml">
<factory name="org.apache.xalan.processor.TransformerFactoryImpl">
<attribute name="" value="true"/>
<param name="body.font.size" expression="8pt"/>

<!-- Create the PDF -->
<property name="fop.home" location="bin/docbook/fop-0.94"/>
<taskdef name="fop" classname="">
<fileset dir="${fop.home}/lib">
<include name="*.jar"/>
<fileset dir="${fop.home}/build">
<include name="fop.jar"/>
<include name="fop-hyph.jar" />
<fop format="application/pdf"
outfile="${build.documentation}/MyProject.pdf" />

<touch file="${doc.timestamp.file}"/>


Sunday, December 28, 2008

Case-Shiller Futures added to Home Price Charting Application

The S&P/Case-Shiller Home Price Indices Futures quotes are now included in the charts and data tables in the Lightsblue Home Price Charting Application. This data indicates where buyers of futures contracts on the Chicago Mercantile Exchange foresee the housing market going in Boston, Chicago, Denver, Las Vegas, Los Angeles, Miami, New York, San Diego, San Francisco, and Washington D.C. This information is updated daily.

Thursday, December 4, 2008

Case-Shiller Home Price Charting and Visualization Application

My family has been in the market for a house for several years now. A home in Boston is a huge investment, so naturally I've been curious about where home prices are headed. The S&P/Case-Shiller Home Price Indices measure home prices calculated from data on repeat sales of single family homes. Until recently, at the end of each month I would download the numbers in the form of an Excel spreadsheet, and manually chart and analyze the data. Finally, a couple of weekends ago I developed a simple Flex Application that uses the Advanced Data Visualization Framework to generate line graphs of home prices relative to 2000, month over month changes, and year over year changes.

So go check out the Lightsblue Home Price Application.

Alternatively, you can subscribe to the Lightsblue Home Price Feed, which will be updated when new features or data is added. The latest Case-Shiller home price data is currently published the last Tuesday of every month by S&P.

Tuesday, November 18, 2008

Lazily Loading List Items in Flex

When using Flex controls with a large dataset, it's often too expensive to load the items in the list all at once. In some scenarios you may find yourself using a third-party API which dictates that you use pagination by only allowing you to load a maximum number of elements at a time. In these scenarios, one of the more elegant solutions is to implement an IList that lazily loads items as they're requested.

I've implemented an example application which demonstrates two variants of this technique. The source is available via the normal right-click on the application mechanism, or via this link.

The first variant (in the first tab of the example application) immediately throws ItemPendingErrors when the list item hasn't previously been loaded. The flex framework supports asynchronous loading of items requested via the IList interface via ItemPendingError. Most Flex controls participate in the ItemPendingError contract, including List, HorizontalList, TileList, DataGrid, Menu, and Tree. When an IList (or ICollection) throws this error, the control gracefully handles it by registering a new IResponder with the error. The control's callback is called asynchronously when the results eventually are available, allowing the control to render the items as they become available.

The second variant (in the second tab of the example application) begins by synchronously returning partially loaded items to the List control, immediately requesting a page of details as the abbreviated version of each item is requested. The LazyList then replaces the appreviated version with the full version in the background, dispatching the appropriate CollectionEvent. The asynchronously dispatched CollectionEvents allow the control to render the details of the items as they become available.

Thursday, October 2, 2008

Flash HTTP Client Limitations

Flash currently has no legitimate HTTP client when running within a browser. If your Flash browser application needs to integrate with a REST service, you may find your self having to write a bunch of extra code to work around Flash's limitations. Your two options when using the Flash APIs are and mx.rpc.http.HTTPService. HTTPService actually uses URLLoader internally, so any URLLoader limitations are passed along to HTTPService. URLLoader's largest limitation is its inability to send any request with an HTTP method other than GET or POST. Note that these aren't the only limitations - there are many others, as well as some interesting quirks.

When confronted with these limitations, I considered the following workarounds:
  • FDS Server Proxy - This would require every HTTP request to hit the FDS server, followed by the target REST service.
  • Homegrown Server Proxy - This essentially would be a free alternative to FDS. The actual HTTP request sent by the client would have to have to be wrapped in an HTTP POST, and the POST would include information about the actual HTTP method desired. The legitimate HTTP Client on the server-side would then send the actual HTTP request with the appropriate method to the REST service.
  • Flash Socket API - This seemed like it had potential, however I had the added restriction of HTTPS communication with the REST service. Some third-party libraries such as as3crypto exist which have limited TLS 1.0 support, but the code was very new at the time, and I probably would have ended up writing a lot of HTTP client code.
  • Browser's native HTTP Client via XML HTTP Request + flash.external.ExternalInterface - Basically flash calls out to a javascript method which sends the actual HTTP request. The javascript function then calls back to flash when it receives the response. This is the option that seemed the least like a hack, and required the least amount of work. It's working rather nicely so far.

Sunday, December 30, 2007

Content-Disposition with Adobe Air / Flex HTMLLoader

It appears that the HTMLLoader in Adobe AIR 1.0 Beta 3 has no way of handling the HTTP Content-Disposition header when set to type 'attachment'.

An example is
Content-Disposition: attachment; filename="fname.ext"

When the Air HTMLLoader encounters an HTTP response with a Content-Disposition similar to the example above, I haven't found a way to retrieve the HTTP response body. This is bad news if you want to create an Air browser that is capable of common Web Browser file-download behavior.

The correct behavior for an HTTP client which receives an HTTP response parameter of this type can be found in RFC 2616, section 19.5.1. It is stated that "If this header is used in a response with the application/octet-stream content-type, the implied suggestion is that the user agent should not display the response, but directly enter a ‘save response as...’ dialog". I suspect that Adobe hasn't had a chance to implement a way for HTMLLoader to notify client code of this situation, or the process for getting the HTTP response body.

I've posted to the Adobe Air forum and filed a Flex bug:
Adobe Air Forum Post
Jira Issue