Before going to last years Akademy I had planned to use the week to try and start helping out with Ruby support for KDevelop4. In the end I got sidetracked by two things; playing with the Nokia N810 and finding out about a web application development library called 'Wt'. Koen Deforche gave a talk about Wt and I was impressed the way he described how web development usually sucked, and why a widget based desktop style api was better than the usual web page with embedded code approach.
After the talk, Pau Garcia i Quiles introduced me to Koen and Wim Dumon who are the two main Wt developers. Pau has used QtRuby and Korundum a lot and so I know he likes Ruby, and yet he thinks the best web toolkit is Wt, which usually involves coding in C++. Hmm, WTF - there must be something interesting with this stuff I thought?
They helped my get Wt built using cmake and linking against the boost libs, and I had a go and running the Wt headers through the kalyptus bindings generator. When I found out that Wt uses boost instead of the Qt core classes I was a bit concerned as basically boost is a complete nightmare for producing language bindings against. It has load of compile time generated C++, and pushes the limits of 'C++'ness, which is a big turn off for me compared with the Qt style of api that I found translates very nicely to non-C++ languages.
I think I got the code generation for a 'Smoke' libary for Wt fixed by the end of Akademy. It turned out that although Wt uses boost, mainly for signals and slots, it fortunately doesn't have a very boost-like api itself. Instead, it is modelled on the Qt4 api with very similar classnames, just with 'W's instead of 'Q's in them. When someone asked Koen at his talk why Wt didn't use the QtCore classes instead of boost, he said it was for licensing reasons, rather than technical ones. Wt is dual licensed GPL/commercial and the commercial version sells for about 500 euros I believe. So the extra cost of a Qt C++ license for the customers would just be too much. Maybe the recent Qt license change to add LGPL will mean that we will see more 'niche products' like Wt built on top of Qt.
A week or so after I got back to Gran Canaria my big toe started hurting. It felt like I had bashed it on something, but I couldn't remember where I'd done that. It got more and more painful and after another week I couldn't even walk and had to go and see a doctor. About the second question the doctor asked was 'Do you drink a lot of beer?', like she was telepathic or something. Maybe it was my english accent, I don't know. The problem she diagnosed was that I had gout in my big toe possibly caused by beer drinking. So how an earth do I get some illness, which I thought had gone out of fashion in the 18th century? I thought that to have 'la gota' properly I should really be wearing a three cornered hat and a curly wig. So I ended up stuck in my flat with a seriously painful toe, a bunch of pills to take and no alcohol for a month. I didn't feel like listening to music or reading a book with my toe hurting like hell. Nothing to do but eat 'gout friendly' stuff, which seems to be just bread, cheese and water. What to do? The solution was go into a hacking frenzy of course, and get the Wt::Ruby hello world working after a week of doing absolutely nothing but either hacking or sleeping. Whenever, I woke up in the night in so much pain I couldn't sleep, I'd just get up and start coding.
After this initial burst of activity I've been working on Wt::Ruby on and off, gradually solving the problems of dealing with boost slots, translating the examples to Ruby and so on. But the trouble with language bindings is that they aren't much use until they are pretty much done, and so there isn't a lot of point in telling anyone much about them. Finally, I think the project is pretty much ready for a first release. The code is hosted on 'gouthub' :-). Here is what hello world in Wt::Ruby looks like:
#!/usr/bin/ruby require 'wt' # # A simple hello world application class which demonstrates how to react # to events, read input, and give feed-back. # class HelloApplication < Wt::WApplication # # The env argument contains information about the new session, and # the initial request. It must be passed to the WApplication # constructor so it is typically also an argument for your custom # application constructor. # def initialize(env) super(env) setTitle("Hello world") # application title root.addWidget(Wt::WText.new("Your name, please ? ")) # show some text @nameEdit = Wt::WLineEdit.new(root) do |e| # allow text input e.setFocus # give focus end button = Wt::WPushButton.new("Greet me.", root) do |b| # create a button b.setMargin(Wt::WLength.new(5), Wt::Left) # add 5 pixels margin end root.addWidget(Wt::WBreak.new) # insert a line break @greeting = Wt::WText.new(root) # empty text # Connect signals with slots button.clicked.connect(SLOT(self, :greet)) @nameEdit.enterPressed.connect(SLOT(self, :greet)) end def greet # Update the text, using text input into the @nameEdit field. @greeting.text = "Hello there, " + @nameEdit.text end end =begin Your main method may set up some shared resources, but should then start the server application (FastCGI or httpd) that starts listening for requests, and handles all of the application life cycles. The block passed to WRun specifies the code that will instantiate new application objects. That block is executed when a new user surfs to the Wt application, and after the library has negotiated browser support. The block should return a newly instantiated application object. =end Wt::WRun(ARGV) do |env| # You could read information from the environment to decide whether # the user has permission to start a new application HelloApplication.new(env) end
You can run this application from the command line when developing it, and then you can install exactly the same source in an Apache2/Fastcgi based site for the released version.
$ ./hello.rb -- --docroot `pwd` --http-address localhost --http-port 4000
Now the basics are there, I think there are a whole lot of things we can do fairly easily to combine Wt::Ruby with Rails stuff and create a pretty nice RAD web development environment. For instance, I've just tried out creating a Wt::WStandardItemModel model from ActiveRecord and showing it in a Wt::Ext::TableView and that works beautifully.
If you are going to FOSDEM this year, I'm hoping to give a short 25 minute talk in the Ruby track on Sunday, but it hasn't been confirmed yet. In the meantime, if you want to checkout the code and try it out that would be great. I would really like to hear from someone other than myself who has got it all working OK before the first actual release.