Sep 8 2007

One reason static typing doesn’t suck

Julian Doherty

Eric Redmond over at Death by Overcoding has posted a discussion on 5 Reasons Static Typing Sucks

It’s a great article, and I agree with pretty much all of it. For the most part excessive static typing is a PITA. The illusion of safety is just that. Static compile time checks only catch the most trivial of bugs, and even then, most of those would have manifested themselves the first time the code was even run. When it comes down to it, the trade offs of the traditional benefits of static typing (you don’t shoot yourself in the foot; you and the compiler always know what’s going on), are often outweighed by the disadvantages discussed in the article.

However, the one thing I’ve always liked when working with static type systems, and one that is often glossed over when discussing dynamic typing systems, is how easily tools can interpret and navigate code. When coding Java in Eclipse, it’s amazing how easy understanding a massive code base can become. You’ve got simple hyperlink navigation, sophisticated refactorings, and smart code analysis that can show you what is called from where and how. Even interfaces and figuring out which implementation is used (which is kinda dynamic typing for Java) can be groked easily with a good IDE.

Got a class with some methods? Want to find where it’s called from? Check. Want to find what methods can be called on the argument you’ve been passed? Check. Want to refactor a whole class hierarchy? Check.

I really love Ruby, but the first thing that struck me when I sat down to code is how much you’re on your own figuring out what is happening. Got a method with an argument passed in? What is it? What can you do with it? Dunno. Want to call another method? What arguments does it take? What about the block it accepts? What does it return? Dunno.

Dynamic languages are great for quickly writing simple elegant code, but not always so great for following and debugging existing code (especially code someone else has written).

Try digging into the internals of Rails, and you’ll become very familiar with the free text search of your text editor. What the hell is that variable? Where was it even instantiated? Dunno. Once you understand the general layout of the classes and modules its pretty straight forward, and thankfully Rails has a pretty well laid out architecture. Which is probably the whole point. If your Ruby code is clean and well designed, then obviously it’s going to be easier to navigate.

So really it comes down to good developers doing smart things. The size and complexity of a good Ruby code base is significantly less than something comparable written in Java for instance. As with most things in software development, this is about trade offs. Ruby is smaller and simpler, but the tools don’t allow you to refactor as easily as Java (the agile purists will say your unit tests allow you to refactor, but it’s still a lot more manual and involved than the automatic refactorings you can do in Java).

It means that in dynamic languages, its more important to have a good design so you don’t get lost in dynamic spaghetti down the track. But at the same time you’re more likely to have a good architecture in the first place because you’re not wasting mental energy focusing on satisfying the static typing system. One of the weakness of static typing discussed in the original article touches on that - the fact that more design must be done up front to predict the future when using static typing. With dynamic typing you’ve got less baggage stopping you from evolving your design as you work, so you can apply the YAGNI principle more easily.

…Although I do still miss being able to zip around Ruby code like I can in Java.
(Yeah, I know Netbeans is getting there, but it’s still a long way behind what you can do with tools analysing and refactoring static typed code).

A decade ago, people said you couldn’t do refactorings and static code analysis with Java. Maybe IDEs will evolve enough over the next few years will make this true for Ruby as well, and we’ll get the best of both worlds.


Jul 31 2007

How to send SMTP mail in Ruby using ActionMailer (outside Rails)

Julian Doherty

Like most bits of Rails, ActionMailer has an elegant and coder friendly interface. With a bit of set up, it’s remarkably quick and easy to get running from vanilla Ruby outside of Rails.

Recently I’ve needed to bulk email a bunch of files to an internal server for testing purposes. I’ve used ActionMailer inside Rails in the past, and wondered how hard it would actually be to get it up and running standalone. Sure, there are a stack of other mail gems and libraries in Ruby to do this, but they expose a lot of the internals of STMP and can be a pain to use. Definitely overkill when all you want to do is quickly fire off some mails from a script. (ActionMailer is actually built on top of a lot of those libraries, and acts like a coder friendly wrapper).

My requirements were pretty simple: Iterate over a bunch of files, and attach each one to a separate email and send to some address.

Here’s what the code looks like for the ActionMailer class:

require 'action_mailer'

ActionMailer::Base.smtp_settings =
{:address => 'smtp.example.com',
 :domain  => 'example.com'}

class FileMailer < ActionMailer::Base
  def file(to, sender, file_name, content_type, strip_ext = true)
    # strip any directory fluff 
    subj = file_name.gsub(/.*\//,'')
    #remove the file extension if required
    subj = subj.gsub(/\.\w*/,'') if strip_ext

    #standard ActionMailer message setup
    recipients  to
    from        sender
    subject     subj
    #setting the body explicitly means we don't have to provide a separate template file
    body        ''

    #set up the attachment
    attachment  :content_type => content_type,
                :body         => File.read(file_name),
                :filename     => file_name.gsub(/.*\//,'')
  end
end

The only thing different from Rails, is that you need to explicitly configure the SMTP details via ActionMailer::Base#smtp_settings.

It’s worth noting that you don’t actually need to create a .rhtml view file if you specify the body attribute of your message. I ran into a few blogs claiming there was no way to turn off the .rhtml requirement - a quick inspection of the ActionMailer source code proves otherwise. I’m sure it violates good MVC design, but if you’re just throwing together a quick script, who cares. I’ve left the body in the example as an empty string (the server at the other end was only interested in the attachement), but you can specify whatever string you want there.

To use the mailer class, you just call it in the normal Rails ActionMailer manner. With ActionMailer you don’t call the mail action method you implemented, but a generated method prefixed with deliver_. So in our example, even though we implemented a method file, we actually call deliver_file (passing it the same parameters).

FileMailer.deliver_file('recipient@example.com','julian@example.com','my_file.csv','text/csv')

Jun 7 2007

Ruby vs JRuby Fractal Benchmark

Julian Doherty

After reading about benchmarking various languages generating fractal patterns, I tried throwing the Ruby code at both the standard MRI Ruby and JRuby interpreters to compare relative performance. This is all totally unscientific, but is interesting all the same.

MRI Ruby (Matz Ruby Interpreter)


ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-darwin8.8.1]

Rendering

Ruby Elapsed 6.732136

JRuby


ruby 1.8.5 (2007-06-04 rev 3812) [i386-jruby1.0.0RC3]

Rendering

Ruby Elapsed 68.757000

C Ruby is the clear winner, but that’s not so surprising. What is surprising is how far JRuby was behind - by at least 10 times. I’ve heard good things about JRuby’s ability to compile Ruby down to bytecode, but I didn’t have too much luck with that. Admittedly I didn’t play around with it for long.

I was curious where the bottlenecks are in both versions. After running the code through both VMs with the -r profile flag, really slow floating point operations turned out to be the culprit. The profile for each was pretty much identical. Lots of float operations (+ / < * etc), with everything multiplied by 10 for the JRuby VM.

So what does this tell us? Pretty much nothing. Most apps won’t be doing this kind of CPU heavy crunching (and if you’re using an interpreted language you’re asking for trouble). Especially the kind of apps you’d use either MRI Ruby or JRuby for, which spend most of their time waiting for the database. I might have another play and see if I can get JRuby to run using bytecode - the hype is that it will be as fast if not faster than MRI.

Disclaimer - I’m actually a huge fan of both MRI Ruby and JRuby and just did this out of curiosity. Put AWAY the flame torches now…

Update - JRuby can actually be as fast or faster than MRI

Charles Oliver Nutter (of the JRuby team), has added some suggestions for tuning the JRuby VM. The following is also in the comments, but I’ve included it in the main post as it is useful information that might get missed. What is really interesting is that JRuby is faster in this case when the VM is tuned and the code gets a chance to run enough for the JIT compiler to kick in.

FYI, I grabbed the code in question to try it out myself. These are my numbers using JRuby trunk (not really different from RC3), Java 6 server VM on OS X, and the following command line:

jruby -J-server -J-Djruby.jit.threshold=0 -O fractal.rb

JRuby:

Ruby Elapsed 6.454000

Ruby 1.8.6:

Ruby Elapsed 6.971203

The command line above adds three options:

-J-server turns on the server VM

-J-Djruby.jit.threshold=0 sets the JIT threshold to zero, so it will try to compile methods immediately (critically important for this benchmark since the methods are only called once), and -O turns off ObjectSpace, which is pure overhead for us.

Additionally, if I let the benchmark run ten times, allowing the JVM to optimize it further, I get the following result for JRuby on the tenth iteration:

Ruby Elapsed 5.629000

There’s a good page in the JRuby Wiki for performance tuning JRuby. The reason this wasn’t compiling is twofold: the methods weren’t called enough times to trigger the JIT, and the script itself had a “class” definition in it, which the compiler doesn’t yet handle.

Cheers Charles, extremely useful.


May 2 2007

Ruby multiple assignment to create unit test data

Julian Doherty

One of the tedious parts of writing unit tests is populating varying test data. Often you can wrap it all up into an array and iterate over it, other times you’re more interested in the individual objects and their interactions.

It’s not hard, but it takes up a few lines initializing each one separately. Less typing is better! Luckily, you can use Ruby’s multiple assignment operator to map all the objects you need in one hit to make your life easier:

def test_exam_result
  a,b,c,d,e,f = ('A'..'F').map{|v| MyObject.new(v)}

  assert stuff(a,b,c)
  assert other_stuff(c,b,f)
  assert d_hates_a(d,a)
end

Apr 13 2007

List Manipulation in Java and Ruby

Julian Doherty

After doing a bit of Ruby coding, I get that "this should be easier" feeling when working in Java for any length of time. An example of that is doing some simple operation on a list. In this case, I’m wanting to do something trivial.

The task is simple: given an unsorted list of objects, find the lowest value of some property.

In Java this would look something like:

Date startFoo = null;
for(Foo f : getFoos()) {
  if (startFoo == null) {
    startFoo = f.getStartDate();
  } else {
    startFoo = (startFoo.before(f.getStartDate()) ? startFoo : f.getStartDate());
  }
}

And in Ruby, this would look something like:

get_foos.map{|f| f.start_date}.inject{|low,start| low < start ? low : start}

Not a huge difference in code length or complexity, but once you start needing to do this a few times the extra verbosity starts to add up. All that typing makes it harder to build momentum and get into flow while coding. In any example more complicated than this you’d often have to explicitly handle generic declarations or type casting (which means even more typing). In Ruby you can pretty much think of how it’s going to work, and just run with it (once you grok how map and inject work).

There is a lot of talk about adding closures to Java 7. That’s something I’d love as it would make a lot of the techniques used in Ruby possible in Java. I just hope that it’s done better than when generics were introduced in Java 5. (We’ve just upgraded one of our products from 1.4 to 5, and I’ve been exposed to generics in action for the first time. Not so impressed so far… but that’s another post.)

UPDATE

As pointed out by robert in the comments, there is an even simpler approach:

get_foos.map{|f| f.start_date}.min

Cheers :)


Feb 15 2007

JRuby can save Swing

Julian Doherty

Swing is hard. Needlessly so. With the advent of scripting support on the JVM, why not wrap a light and elegant Ruby layer around Swing? Why keep coding Swing at it’s lowest API level using a heavy-weight language like Java?

I’ve always maintained Swing is a nice framework. It’s just that it’s too low level and Java is a lousy language for programming it in. It’s already possible to code Swing in Ruby by using JRuby. You get some of the Ruby niceness (such as easier method calls, some dynamic typing, and blocks), but you still end up fighting against listeners, layout managers, look-and-feels, event-threads etc before long. Suns trademark API over-engineering casts a long shadow, even into Ruby land.

The Swing API itself is very flexible and powerful, but at a low level. It’s powerful in the same way that a coil of wire and a bunch of tools is a flexible and powerful way to configure the electricals in your house. It’s just that sometimes you only want to plug a few things in and flick a switch to watch a DVD.

So what specifically are the problems?

Swing’s issues

Joshua Marinacci’s blog post Swing has failed. What can we do? from 2003 covers this issue nicely. Joshua points out these flaws which I’d agree with 100%. Nothing much has changed in the years since, except maybe that Swing looks somewhat better now and resembles native apps much more closely.

  • "Swing apps are slow to build."
  • "Swing layout managers suck."
  • "Swing apps are hard to maintain."
  • "Swing is too powerful."
  • "No native features."
  • "Swing apps have a bad history."

What needs to be done?

Joshua’s ideas on what needs to be done to fix Swing are interesting.

(there are more points he makes, but I’m just including the relevant ones)

  • "A structured way of building Swing apps. Something like Struts where each concern (aspect?) has it’s own special place to be stored and manipulated. How do you organize your layout, workflow, validation, intz’ed text, and hooks to the BL? Should you subclass to make frames or use factory code? We need a set of best practices and then a framework to implement them."
  • "A standard cross-tool representation of a GUI that is not Java code. Something that can be moved in and out of different IDEs and build tools. Probably an XML representation or maybe serialized Swing objects."
  • "An intermediate API. Maybe we need a simpler API on top of Swing? A new set of wrapper components which hide a lot of the complexity. Hell, half of the work could be done by just conditionally hiding 3/4 of the API from the Javadocs."

I particularly like the idea of a structured way of building Swing apps. At the moment it’s a free-for-all. Some developers have come up with nice individual patterns for maintaining order, others implement spaghetti, most start out well, but degrade into entropy. This even applies individual screens in some apps! - I’ve seen 6000 line long, single-class monstrosities for a single window! One of Rails main strengths is it’s “Convention over Configuration” approach for separating out and structuring an application. There is no reason why this can’t apply to a Rich Client.

My Ideal Swing/Ruby framework features

So… what would this look like?

  • Structured application layout. Works for Rails. Nuff said.
  • Proper decoupling of model from view. Probably using Martin Fowler’s Presentation Model pattern, or similar.
  • Automatic binding of model to view without glue code. (this makes the last point much easier to implement.) Ruby is perfect for this. You should be able to write something like name_field.bind_to song, :title and be done with it. Ruby should do it’s thing and set up listeners automatically - Even if the model class wasn’t designed with listeners when it was coded.
  • View logic code separated from layout markup. View components and interaction (enable this button with this tooltip etc) should be coded in Ruby. Layout should be stored in a YAML file or similar (please no more XML…). Layout via coding is far too hard for most people to use effectively. Minimize the pain and let the framework take care of the grunt work. We definitely DO NOT want anymore GridBag boilerplate code…
  • Application lifecycle support. Related to having a structured application layout. Provide session support, long lived models etc, and handle startup/shutdown.
  • Minimize the amount of code. You already get this for free by using Ruby, but removing the fluff from Swing is a must. Too much code to achieve too little. It should be possible to scaffold something basic like Rails does, then tweak it if it needs to do more. DRY is part of this, but that just seems like basic common sense for any kind of development in any language.
  • Minimize complexity. Related to minimizing code. Making it easy to use a proper pattern like Presentation Model and removing a lot of the spaghetti listener code by using bindings will help a lot.
  • Testable. It’s really hard to write automated tests for GUIs. Libraries like JFC Unit make it easier, but it’s still pretty heavy going. I don’t know the answer to this one. GUIs always need at least some manual intervention to check the visual layout (a computer can’t tell if it doesn’t “flow” right). Maybe the framework could help by making it easy to substitue mock objects for testing the presentation model code.
  • Make the Right way of doing things the path of least resistance.. This one is important, and I think it is one of Swing’s big weaknesses. This is related to having a good structure, but it goes from there all the way down to how easy the APIs are to use. Rails makes it easy to create good designs and stick to them. Swing makes it hard - as evidenced by the plague of badly thought out Autonomous Views espoused by Sun’s Swing tutorials

Even a few of these points would make Swing much more productive and fun. I’ve made a few posts recently that are leading up to this. Over the next few posts I’ll start to experiment with a few more of the pieces to see how it all hangs together. Who knows, maybe I’ll actually get something usable at the end :)


Feb 7 2007

Transparent Property Change Listeners in Ruby

Julian Doherty

One of my side projects is a framework for building Swing apps using JRuby. I’ve always maintained that Swing is a nice framework - it’s just that Java is a lousy language for writing it in.

One of the areas that Swing is weak in, is binding components to the underlying model. For those unfamiliar with Swing, its designed with a nice way of loosely coupling the model to the GUI components. This is done using listeners - typically Property Change Listeners - which fire whenever the value of some property changes and can be coded to explicitly replicate the state from the model to the view or (vice versa).

…Which is really nice in theory, but in practice it’s not a clean or easy task. It’s usually done badly as there is so much glue code to write if you want a nice pure OO design (developers hate writing boiler plate code). There are Java frameworks like JGoodies Binding and the PropertyChangeSupport class built into the JDK that help out, but in typical Java style, these can get quite complicated, and still require you to carefully manage new Objects to make sure they are manually bound correctly. It usually just ends up being a burden in real life which no one follows properly. (For an example of how NOT to write Swing properly - see Sun’s own Swing tutorials…)

I figured it should be possible to do this in a more Rubyish way. Something that is smooth and easy to use, and provides the best practice as the path of least resistance. I googled a bit and found RubyBeans revisited by Olivier Ansaldi, which seems cool… but involves having to subclass your bean classes from a common base class - some thing I was wanting to avoid. Ideally, the bean classes should be pure and simple Ruby classes build with attr_accessor. (what you’d call a POJO if were in Java land - although this concept is so obvious in Ruby I haven’t even come across a name for it)

Here’s what I came up with:

class ListenerSupport

  public
  def self.listen_to(klass, *properties)
    setup(klass)
    properties.each do |p|
      klass.class_eval do

        alias_method "#{p}_orig=", "#{p}="

        define_method "#{p}=" do |value|
          old_value = send "#{p}"
          send "#{p}_orig=",value
          fire_property_changed p, old_value, value
        end
      end
    end
  end

  private
  def self.setup(klass)
    klass.class_eval do

      def fire_property_changed(prop,pre,post)
        return if pre == post
        @listeners[prop].each do |l|
          l.property_changed(self, prop, pre, post)
        end unless @listeners.nil?
      end

      def add_property_listener(prop,listener)
        @listeners ||= {}
        prop_listeners = @listeners.include?(prop) ? @listeners[prop] : []
        @listeners[prop] = prop_listeners
        prop_listeners << listener unless prop_listeners.include? listener
      end

    end
  end

end

The general idea is that the original class is modified so that all properties that are listened to have their accessor write methods intercepted, and any property change listeners are notified when that property changes.

Let’s walk through how it works:

  • A standard Ruby class with property accessors is created. e.g.
    class RubyBean
      attr_accessor :foo, :bar
    end
  • A call to ListenerSupport.listen_to is made to modify the class to allow properties to be listened to.
    ListenerSupport.listen_to RubyBean, :foo, :bar
  • listen_to adds methods add_property_listener and fire_property_changed to allow listeners to be added to RubyBean for specific properties.
  • listen_to then aliases the original methods foo= and bar= to foo_orig= and bar_orig=. New methods for foo= and bar= are defined that delegate the work to the original method, then call fire_property_changed to notify the listeners.
  • Listeners are called, and any custom action (such as GUI component binding) can be carried out.

An example of this in action

class BeanListener
  def property_changed(obj, property, old_value, new_value)
    puts "#{obj.to_s} updated property:#{property}. old:#{old_value}. new:#{new_value}"
  end
end

class RubyBean
  attr_accessor :foo, :bar
end

ListenerSupport.listen_to RubyBean, :foo, :bar

bean = RubyBean.new
bean.add_property_listener(:foo,BeanListener.new)
bean.add_property_listener(:bar,BeanListener.new)
bean.foo = 'foo1'
bean.foo = 'foo2'
bean.bar = 'bar1'
bean.bar = 'bar2'
bean.bar = 'bar2'

Which outputs:

# updated property:foo. old:. new:foo1
# updated property:foo. old:foo1. new:foo2
# updated property:bar. old:. new:bar1
# updated property:bar. old:bar1. new:bar2

Which shows that the listener is being called each time the property changes :)

Although this doesn’t show any kind of GUI binding, it does show how easy it is to make ordinary Ruby classes (or even Javabeans in JRuby) behave as if they had property change support built in from the start. It’s an important piece of the design a smooth and easy GUI binding framework.

Update - Fixed code after feedback from Pit Capitain in comments - should have used class_eval rather than instance_eval to define new methods in setup()


Feb 5 2007

Ruby / Oracle / Mac OS X pain

Julian Doherty

Environment setup is one of the worst aspects of software development. You can get all hyped up about the latest and greatest technology and techniques, but at some point you’ve got to get your environment set up so you can use them. I’ve spent a good part of this afternoon trying to get Ruby to work with an Oracle database on my Mac OS X box.

Simple huh? Nope. Mostly just old fashioned pain.

A bit of googling initially pointed me to the ruby-oci8 project, which provides a Ruby library for Oracle. I happily download and started working through the install instructions which involves compiling the library. Fine - except for the compilation problems. Seems my Oracle Instant Client install isn’t quite complete.

Next step is a trip to Oracle’s website, which is an altogether separate exercise in frustration - after eventually reviving my developer login (with the help of mailinator and Borat), I stumbled around clicking through a “terms of use - sell your soul agreement” for every… single… page… I eventually find the download I’m after. Cool.

I try to compile ruby-oci8 again, but this time I come up against:

Oracle doesn't support intel mac.
 http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/223854

There are three solutions:
1. Compile ruby as ppc binary.
2. Wait until Oracle releases mac intel binary.
3. Use a third-party ODBC driver and ruby-odbc instead.
    http://www.actualtechnologies.com/

By this time about 2 hours have gone by, and hair is being pulled out in clumps. Admittedly I would have known this if I’d just read the platform specific issues on the ruby-oci8 site.

By now it’s 6pm, and the evening round of CS is starting up. I’ll save this one for tomorrow. Maybe I’ll play around with ODBC, or possibly try using a JDBC driver and using JRuby instead.

The ironic part is that I’m just wanting to "quickly" mock up some code to test out something that will later be implemented properly in Java (oldschool, heavy Java). At this rate it probably would have been quicker to do something quick and nasty in Java and be done with it (which isn’t *that* bad with Eclipse). Lately though, I’m shuddering at the thought of file after file of needless case handling, redundant interfaces, xml config files, and over engineered Sun APIs - even for simple stuff. Environmental pain is probably the lesser of two evils in the long run.


Jan 30 2007

F3/swiby style declaration blocks

Julian Doherty

swiby is a proof of concept framework inspired by F3. Both use a hierarchical block format for defining Java/Swing visual elements. eg:

Frame {
  title "Hello World F3"
  width 200
  content {
    Label {
      text bind(model, :saying)
    }
  }
  visible true
}

I was looking through the documentation, and got curious as to how the class level block declaration is actually implemented in swiby. After a bit of digging around, it is relatively straight forward.

There is some code in swiby that looks kinda like this:

def component_factory(class_name)
  eval %{
    def #{class_name}(&block)
      x = #{class_name}.new
      x.instance_eval(&block)
      x
    end
  }
end

I’ve removed the error handling and some extra functionality, but the basic idea is the same. component_factory is called for each class that is required to be instantiated as a declared block. Here’s an example:

class Foo
end

class Bar
end

component_factory :Foo
component_factory :Bar

my_foo = Foo {
  @my_bar = Bar {
    @baz = 'baz'
  }
}

puts my_foo.inspect

Which outputs:
#<Foo:0x60544 @my_bar=#<Bar:0x604e0 @baz="baz">>

A Foo instance has been created containing a Bar instance, with a variable of baz. This sort of syntax could be useful for DSL implemented in Ruby.

One limitation I ran into, is that calling attr_accessor methods don’t get recognized (they just get defined as local variables that go out of scope at the end of the block) - but that may just be a limitation of useing instance_eval to set the newly created object as the object in scope as self.