Categories
Innovation

Ricky, Ruby and Rails (hypothetically speaking)

In the bits of spare time I get here and there, I’ve been continuing my hypothetical hunt for a language and web framework in which to implement my hypothetical "web 2.0" idea. It occurs to me that if all these little bits of spare time were clumped together so that I could, hypothetically, do some actual coding as opposed to “investigating”, hypothetically I’d be well on my way to having a hypothetical working system by now. But, alas, little bits of time here and there is all I’ve got at the moment.

chunky bacon

Anyway, after having checked out Python and Django and deciding that I’d be happy enough with that set of tools, I thought I’d better check out Ruby and Ruby on Rails to see what all the fuss is about. Well, I have to say, so far I really like the Ruby language. I’ve been helped along by what has to be the weirdest, but coolest, guide to programming that has ever been written for any language (what other programming guide comes with cartoon foxes and its own soundtrack?). I’m still learning the ins and outs of Rails, but there are some very helpful tutorials online for this, too. The fact that Ruby, like Python, comes pre-installed in Leopard was a pleasant surprise. Ruby comes with a command shell environment called irb (Interactive Ruby), which enables you type Ruby code at the command prompt (again, just like Python’s python command line tool). This makes it very easy to experiment with the language.

One of the things I like about Python is list comprehensions. They’re a very neat and convenient way of mapping a list to a new list by applying a function to each element of the original. It kind of works like the map function in many other languages, except you can include conditional statements. The heavy use of list comprehensions in Programming Collective Intelligence tells me that there’s a good chance they’ll come in handy for me later on. Here’s a trivial example:


>>> list1=[1,2,3]
>>> list2=[x**2 for x in list1 if x%2==1]
>>> list2
[1, 9]

In Ruby there’s no syntactic sugar for list comprehensions, but it turns out you can pretty easily implement the required behaviour:


>> list1=[1,2,3]
=> [1, 2, 3]
>> list2=list1.map {|x| x**2 if x%2==1}.compact
=> [1, 9]

Furthermore, since classes are never “sealed” or “final” in Ruby, it means that you can do something like this:


>> class Array
>>   def comprehend( &block )
>>     block ? map( &block ).compact : self
>>   end
>> end

We’ve just added another method to the (existing) Array class which works very much like a list comprehension:


>> list1.comprehend {|x| x**2 if x%2==1}
=> [1, 9]

That’s a little of what I’ve learned about Ruby in the past week or so. Anyway, I can say that I’ve narrowed down my search to two candidates. Python has the lead in terms of being a mature technology. But Ruby really is fun to program in, and I like its syntax better than Python’s. Furthermore, I spent a while faffing around with Django and mod_python for my Mac. But getting Rails up and running was a breeze using the Mongrel web server – a production quality web server for Ruby applications, used by many web sites including Twitter. Ultimately, my (hypothetical) first hire gets the final say. :-)

Categories
Random observations

The Get out Clause and Weezer

I’ve got some time to work on the context manager today, and I’m listening to some stuff as I code. Here’s a sample:

Also check out The Get Out Clause and this video. It was made by requesting CCTV footage through the Freedom of Information act (apparently).

Update: Here’s the “Paper” video clip inline:

Categories
Random observations

Rediscovering closures and nested functions

When you’ve spent years coding pretty much everything in Java, it’s hard to break out of the Java way of doing things. It means that you tend to forget that other languages might have things called closures, for example. Here’s how a closure looks in Python:


lambda x:dosomethingto(x,anothervariable)

The neat thing is that this closure can be passed around like a first class object. Also, anothervariable, bound in the outer scope, is accessible to the lambda expression when it is invoked later. You can do stuff like:


if isinstance(somevalue, int) or isinstance(somevalue, float):
  isfunny=lambda x:log(x)>somevalue
else:
  isfunny=lambda x:isalpha(x) and islower(x)

funnyitems=[item for item in mylist if isfunny(item)]
seriousitems=[item for item in mylist if not isfunny(item)]

Sure there are other ways to do the same thing. But this is arguably more elegant.

There’s also nested functions, which are kind of like closures. Rather than contriving an example, I’ll give one from the book I’m reading, Programming Collective Intelligence. In chapter 8, a crossvalidation function is defined. Forgetting the specifics and purpose of this function, just know that the crossvalidate function returns low numbers for good solutions and high numbers for bad solutions. Earlier in the book, we’d already been introduced to optimisation problems and cost functions. The cost functions take a single argument, which is a potential solution to be costed. The crossvalidate function takes a bunch of parameters, so for this and other reasons it can’t be used directly. But you can do something like this:


def createcostfunction(algf, data):
  def costf(scale):
    sdata=rescale(data,scale)
    return crossvalidate(algf,sdata,trials=10)
  return costf

So now your costf function knows about algf and data, despite not having them as parameters. That is, the bound variables to algf and data are available to costf when it is called at some later time:


costf=createcostfunction(knearest,mydata)
annealingoptimise(wdomain,costf,step=2)

So when annealingoptimise eventually invokes costf, costf has access to knearest and data. That is the bindings of algf to knearest and data to mydata live on after the execution of createcostfunction completes. Cool.

Categories
Random observations

Mod_wsgi

Forget my previous entry about mod_python. Just use mod_wsgi. It compiles without issues on the Mac (unlike mod_python, which is why I made a binary available for it), and seems to be the future for Apache/Python integration. See Graham’s comment on my last entry.

Categories
Random observations

Mod_python for the Mac

In case anyone’s interested, I’m making available a pre-built universal binary of mod_python 3.3.1 for Apache 2.2.8. I’m running Mac OS X Leopard 10.5.2 and Python 2.5.1. The DMG contains an installer package, and it will try to install mod_python to /usr/libexec/apache2, which is where the other apache modules are usually located. Use at your own risk.

You can download it here.