portable perspectives

a blog about programming, life, universe and everything

Leaving in 3,2,1 (again)

So, your host in this place is going to leave you for a while, again.

Two years ago, it was to move to Hungary, best time of my life.

This time, it's to move to Galway, Ireland where I'll be working with this people on some cool stuff.

I'm a bit afraid about finding a home, and I wish I'll not be completely useless in the project, but well, better to try and fail then never try.

See you, Dear Reader, I can't understand why you're still around this place, but thank you for doing so.

See all comments

Both my languages suck

Over at desperately unenterprise there is a nice article about the things the author dislikes about haskell, and an invitation to share your own quirks about your favourite language. Well, I almost equally like ruby and python. so here is a double rant.

Why ruby sucks

First, i can reopen classes but so can the others. It's all nice, and the usual idea that this will make development impossible is dumb, but it's true that it can get annoying. Matz once used to say this could be fixed by namespaces in ruby2 but I haven't heard anything about it in years and I'm not sure it will happen. Meanwhile, I still got the occasional oh, damn why isn't this working? moments, and it sucks. People may remember that nice chainsaw infanticide logger maneuver.

Modules as namespaces also suck. They rely on a wrong assumption, that everyone else will use modules as namespaces, which of course is not always true, so if you happen to use something poorly designed you may end hupo with their User class conflicting with your. Python got it right, namespaces are implicitly defined by files/directories and you have to explicitly import stuff in the current one.

But not just that, you can also import a single name from a python module. Try that with ruby's require if you can. You're either forced to split every single method in it's own file, like facets does or you impose on the end user namespace pollution.

And it's not even that namespaces are cheap to define. The usual way is

  • create a foo.rbmain file
  • create a foo/ directory
  • create many foo/xyz.rb files
  • in every single file define the module And it gets much worse with nested namespaces. And yeah I know I can do class Module::ClassName except that then I can't load that single file separately.

(I also dislike the thing about constants being lexically scoped to be fair, but probably it's just my disliking of class variables and the fact that I'd like to use constants for that)

What is nice about ruby modules is their usage as mixins, and even though I'd like them a bit different they are cool. But so under used.

The core classes in ruby are so fat that they are almost impossible to subclass. Have you ever tried subclassing String so that you can, for instance have a TextileString where you can do substitution without considering the markup? You'll never get it right enough, just String#[] has 7 different behaviors depending on th arguments, and String#[]= has 8 of them.

The Comparable mixin rocks, everybody loves Enumerable but go figure how to make an Hash-like or File-like object without subclassing

Why python sucks

The problems with python are, well, what makes it pythonesque. Yeah, I understand why you need to explicitly define self in a function, I just believe it's dumb and too verbose. But why can't I have a bit of syntax sugar ? Make .foo be a shortcut for self.foo ? At least that would also enforce the convention!

Python has such a big set of conventions that are not supported by the language. Do not use global variables, but look, there is a useful global keyword, even though you have nested namespaces.

On the other hand, it enforces some ugly conventions, suchs as the avoidance of assignments in conditionals by splitting statements and expressions. That distinction is so annoying that as time passes more and more things become both. Conditions are statements, so here is also the expression version. Functions are statements so here is the crippled lambda expression. Assignment is a statement so here are a handful of setters that avoid using the evil = symbol.

update: sorry, this got published by error, it was still largely incomplete, so I'll juust add some more comments

A lot of things that I dislike are in the "kernel library" design, and not syntax. len, map and so do not make the language less OO, I know, but they are ugly and polluting the top namespace, why can't they be made part of proper abstractions? And I hate not being able to use mutable values as key for dictionaries, even java manages to do that, it should not be that hard.

Something that I miss syntax wise instead is the lack of a case statemente, especially of a destructuring/pattern matching one. Python people will usually tell you that you just use a dictionary. Yeah, but why I have to? I can remove else-if from the language too, but it does not mean it makes sense. case/switch statements are actually a place where the language can provide very useful behaviours once someone get past the C/Java versions of it. Take a look at ruby, SML or Scala.

And, pet peeve: why I have to type ":" in definitions? the parser does not need that, and come on, it adds nothing readibility-wise.

See all comments

ActsAsAuthenticated, insecure by default?

ActsAsAuthenticathed is probably the most widely used (and deployed) plugin for managing user registration/authentication in a rails application.

As everything coming from Rick Olson it's great, giving you a complete authentication system in few steps, with a lot of tweaking points that allows you to make it suitable to your setup.

But I think the default configuration is a bit insecure.

Point is, the default encryption routine (done in #encrypt in model.rb) uses a SHA1 digest to cypher the password. But SHA1 is designed to be a fast digest function, not a password cypher. Moreover, the default password length is restricted in the 4..40 range.

Thus, supposing a user has a password with the standard characters in the [_-a-zA-Z0-9] range, the number of different combination for an acceptable password is 64^4< 17 milions.

This may seem a lot, but if you think about it is not so much, using a dumb ruby script on my old box I can find all the hashes for this kind of password in about three minutes. Yeah, in ruby, with gc kicking in and everything. Having a salt is of no importance, it just avoids finding multiple passwords at once.

Now, if you think that there are things like NSA@Home that will try all the possible passwords of 8 characters in one day (64^8 =~ 3e14), this does not sound really secure.

I'm not a security expert, but I believe this should not be like that. I'd say that to make it a bit more secure you could change the Model#encrypt method to do multiple iterations, say

def self.encrypt(password, salt)
  cypher = password
  1000.times do 
    cypher= Digest::SHA1.hexdigest("#{salt}#{cypher}")
  end
  cypher
end

But even there, I'm not a cryptanalist so I don't know if there is something like "the n iteration of SHA1(string of k elements) may be computed in time O(log(n*k))". Cryptopeople may do stuff like that, all the time, for what I know.

So this is basically a question: is AAA slightly insecure by default? If that is true, what would you use as the encrypt function?

See all comments

ECMAScript 4, the fourth system syndrome

The second system syndrome is that evil effect that often happens when redesign a small, working system so that it becomes a huge leviathan built by piling new features over new features.

Today I was reading the overview of ECMASCript 4 from ecmascript.org, and I got this very bad feeling that maybe the fourth version of ES, is suffering of an extremely strong case of this problem.

I believe that part of the success of ES in its current incarnation is that it is quite simple. Yeah, it has its shortcomings and oddities, but in general it is simple enough that everyone can learn it in no time.

ES4, on the other hand, seems to have included almost everything that came out from programming languages in the last 50 years, save Prolog and APL.

For example, it has prototypes, interfaces, classes, metaclasses, higher order types and generic functions, which for what I can tell entails all the work ever done on object-orientation (maybe predicate classes are missing, but they may be there too).

The argument list of a function may have named arguments, rest/variadic arguments, optional arguments, optional types including: non-nullable arguments, like arguments (this seems the same as in Eiffel, used to link the type of an object to another), wrap arguments that perform automatic conversion of an object of type X into another of type Y,

Whereas many languages I know provide a concept of Module or Package to handle namespacing issues, ES4 provides packages and namespaces and program units to support name hiding and modularity. Not only this, but you can introduce variables with var to have it in the object scope or with let to have it in a block, so even more namespace separation :-)

Finally, ES4 incorporates some cool features such as list comprehensions, a kind of destructuring assignment/pattern matching, python-like slicing, triple-quotes and generators (though AFAICT this are only one way generators like in older python releases, where you can yield but you can't receive values Thanks to Neil Mix for pointing out that they are complete coroutines, and support bidirectional value passing).

And operator overloading, program pragmas, required tail call elimination, a host of interesting keywords suchy as intrinsic to reify operators, dynamic to have classes that allow adding of new fields, static to have class-level functions, final to avoid inheritance and override to use it, internal, public and so on. And of course, 6 different values of falsity, with NaN, "", 0, false, null and undefined, but not {} and [].

ECMAScript 4 seems cool, I want to use a lot of those things (yay for multi method dispatch!), but maybe it is changing the language a little bit too much .

How many of the current user of ES in one of its incarnations have ever heard of product types? Will they grasp at once the logic behind the subtyping relation between functions, with all that covariant and contravariant stuff? Will they need it at all?

I hope the internet pipes will resist to the number of "metaclass vs meta namespace vs prototype vs superclass" questions on usenet.

See all comments

More Obscure Features of Ruby

First go look at Nick Sieger's post about strange perlisms in ruby, cause it may be interesting for you. But talking about strange features in ruby, I believe there are some that may result even stranger, cause they are not even inherited from other languages, but are matz' own creation, I believe.

super on builtin methods

if you're redefining a builtin method you can use super to access the original one:

>> def puts(*args)
>>  super(*args)
>>  super(*args)
>> end
=> nil
>> puts 123
123
123

yet if you try with your own:

>> def foo() puts "foo" end
=> nil
>> def foo() super end
=> nil
>> foo
NoMethodError: super: no superclass method `foo'
        from (irb):8:in `foo'
        from (irb):10

super without arguments

I knew this feature for long, but never used it in real coding, even if I keep thinking it's handy. super, when used without arguments, passes all the arguments, so the above example would become:

>> def puts(a,b)
>>  super
>>  super
>> end
=> nil
>> puts 345, 567
345
567
345
567
=> nil

The evil context-sensitive while and until modifiers:

Can you tell the difference between this two lines?

 puts 'hello' while false
 begin puts 'hello' end while false

Well, the difference is that the latter will print "hello", because the while modifier always does at least one evaluation of the expression when preceded by a begin..end block. The same happens with the until modifier. Luckily, this evil behaviour is supposed to disappear.

do something, handle exceptions.. or else?

Did you know that ruby's begin allows the definition of an else clause? The else clause is actually part of the rescue part of the block,. and is executed whenever an exception is not raised:

>> def check(x)
>>  begin
?>   raise if x==2
>>  rescue
>>   "error"
>>  else
?>   "ok"
>>  end
>> end
=> nil
>> check(1)
=> "ok"
>> check(2)
=> "error"

..and of course, you do not need begin..

because, I believe you know this, you can write:

>> def check(x)
>>   raise if x==2
>>  rescue
>>   "error"
>>  else
?>   "ok"
>> end
=> nil
>> check(1)
=> "ok"
>> check(2)
=> "error"

methods with whitespace, yay!

I find this quite useful, actually. If you define a method bypassing the ruby parser with define_method you can give it any name you want.

>> class K
>>  define_method("method: hard to get") { 'got!' }
>> end
=> #
>> K.new.send 'method: hard to get'
=> "got!"

You won't be able to call the method with normal ruby syntax, which makes it less or more useful depending on your problem space.

And finally, there is a whole slant of strange things that I believe are remnants of matz' experimenting with the language (is alias $global $other_global used somewhere outside of english.rb?), and even if some of them are quite frightening (if /regex/ anyone?) they will be phased out, so it's ok. If I recall correct ruby also had a glob operator ( <*.c> ) that was killed in the early days, so I trust matz to fix the oddities of the language sooner or later :)

See all comments

Spell Corrector in AliceML

It seems that writing a spell correcor is becoming my new post hello world program, so well, after having this in my hard disk for a while I thought I would publish my new solution, wrote using AliceML.

I'm really not good at ML, so this code must not be considered a good example of how to code, but I thing it's a good thing to keep track of my learning :)


import structure MkRedBlackSet  from "x-alice:/lib/data/MkRedBlackSet";
import structure MkRedBlackMap from "x-alice:/lib/data/MkRedBlackMap";

structure Set = MkRedBlackSet String;
structure Map = MkRedBlackMap String;

val wordlist = "/home/rff/wordlist.txt";
val alphabet = String.explode "abcdefghijklmnopqrstuvwxyz";

open List;

fun take2(i1,i2) = (fn cl => (take (cl,i1), drop (cl,i2)))

fun delete cl i = 
  let
    val (first, second) = take2 (i,i+1) cl
  in
    String.implode (first @ second)
  end

fun deletions cl = tabulate ((length cl), (delete cl));


fun substitute cl i = 
  let 
    val (first,second) = take2 (i, i+1) cl
    fun sub_char c = String.implode (first @ [c] @ second)
  in  
    map sub_char alphabet
  end 

fun substitutions cl =  concat( tabulate ((length cl), (substitute cl)));

fun insert cl i = 
  let 
    val (first, second) = take2 (i,i) cl
    fun ins_char c = String.implode (first @ [c] @ second)
  in  
    map ins_char alphabet
  end 

fun insertions cl =  concat( tabulate ((length cl)+1, (insert cl)));

fun transpose cl i = 
  let 
    val (first,second) = take2 (i,i+2) cl
    val c1 = nth (cl,i)
    val c2 = nth (cl,i+1)
  in  
    String.implode (first @ [c2] @[c1] @ second)
  end 

fun transpositions cl =  tabulate ((length cl)-1, (transpose cl));


fun edits1 word = 
  let 
    val w = String.explode word 
    val ws = deletions w @ transpositions w @ insertions w @  substitutions w
  in 
    foldl (Fn.flip Set.insert) (Set.empty) ws
  end 

fun insertOrUpdate map key = 
  case Map.lookup (map, key) of
     NONE => Map.insert (map, key, ref 1)
    |SOME value => (value := (!value +1) ; map)


(* train *)
fun train io =
  let 
    val chop = fn str => String.substring (str, 0, (String.size str) - 1)
  in
    case TextIO.inputLine io of
       NONE => Map.empty
      |SOME line => insertOrUpdate (train io) (chop line)
    end  

val nwords = train ( TextIO.openIn wordlist);

fun known_edits2  word = 
  let 
    fun set_edits set = Set.fold (fn (str,set) => Set.union (set, known (edits1 str))) Set.empty set
  in
    set_edits (edits1 word)
  end

fun look k = !(valOf (Map.lookup  (nwords, k)));


fun correct word =
  let 
    val candidates = find (not o Set.isEmpty) 
                           [ known (Set.fromList [word]),
                             known (edits1 word),
                             known_edits2 word]
     val sort = sort (fn (a,b)=>Int.compare ((look b), (look a))) o Set.toList
   in
     case candidates of
       SOME words => hd(sort words)
      |NONE     => word
   end  

correct "ciao" (*ciao match*);
correct "cao"  (*ciao edit 1*);
correct "mioo" (*miao edit 1*);
correct "miaoo"(*miao edit 1*);
correct "mooo" (*mao  edit 2 max value*);
correct "quux" (*quux no match*);

The worse part is the string manipulation, I think, and maybe the fact that I use references (aka mutable variables) when building the frequency count Map, but in the end I'm quite satisfied. Feel free to point out obvious errors, if you see them.

See all comments

darcs pull vs git pull

I mean, I'm not going to say that you should use $VCS1 over $VCS2, I'm not proficient enough with either. I just think that:

rff@ut:~/ramaze$ darcs pull
Pulling from \"http://manveru.mine.nu/ramaze\"...

Wed Sep 12 14:52:55 CEST 2007  Michael Fellinger <mail@foo.com>
  * Adding path for OSX to tool/tidy and improve readability of the spec for it a bit.
Shall I pull this patch? (1/1)  [ynWvpxqadjk], or ? for help: v
[Adding path for OSX to tool/tidy and improve readability of the spec for it a bit.
Michael Fellinger <mail@foo.com>**20070912125255] {
hunk ./lib/ramaze/tool/tidy.rb 18
+        /usr/lib/libtidy.dylib
hunk ./spec/ramaze/tidy.rb 10
-    Ramaze::Tool::Tidy.tidy(\"<html></html>\").should =~ %r{<html>\\s+<head>\\s+<meta name=\"generator\" content=\"HTML Tidy (.*?)\" />\\s+<title></title>\\s+</head>\\s+<body></body>\\s+</html>}
+    Ramaze::Tool::Tidy.tidy(\"<html></html>\").
+      should =~ %r{<html>\\s+<head>\\s+<meta name=\"generator\" content=\"HTML Tidy (.*?)\" />\\s+<title></title>\\s+</head>\\s+<body></body>\\s+</html>}
}

Wed Sep 12 14:52:55 CEST 2007  Michael Fellinger <mail@foo.com>
  * Adding path for OSX to tool/tidy and improve readability of the spec for it a bit.
Shall I pull this patch? (1/1)  [ynWvpxqadjk], or ? for help: y
Finished pulling and applying.


is slightly more clear than:

rff@ut:~/rubinius$ git pull
Fetching refs/heads/master from http://git.rubini.us/code using http
got 2fb92489ed4a0e58ea3d941a6f2ff8c7b8b44c2d
walk 2fb92489ed4a0e58ea3d941a6f2ff8c7b8b44c2d
got 6ae85832a699f3048ee260d9091aacc05c686fe4
got 6c0e0e63c0bb5979e2dd2b3df6e511b031656ef4
walk 6c0e0e63c0bb5979e2dd2b3df6e511b031656ef4
Getting alternates list for http://git.rubini.us/code
Getting pack list for http://git.rubini.us/code
Getting index for pack cf217ebdaa4f745cc827450e9cac23ec258d45f9
Getting pack cf217ebdaa4f745cc827450e9cac23ec258d45f9
 which contains cf987cd736618331bf421603c1491030b0fc8e35

got c77671cc8a43049bd61dd22f13fbbbc1ab4f96ec
... many more.. 
got 933282575047f8924edc6cc426c0a234bdbe16a3
* refs/remotes/origin/master: fast forward to branch \'master\' of http://git.rubini.us/code
  old..new: e85ecf8..2fb9248
Updating e85ecf8..2fb9248

Fast forward
 .gitignore                            |    1 +
 Makefile                              |    2 +-
 bin/sirb.rb                           |    1 -
 compiler/bytecode/compiler.rb         |   22 +-
 compiler/bytecode/primitive_names.rb  |    2 +-
 compiler/bytecode/rubinius.rb         |    1 +
 compiler/bytecode/system_hints.rb     |   20 +-
 compiler/translation/local_scoping.rb |    7 +-
 compiler/translation/normalize.rb     |   24 ++
 compiler/translation/states.rb        |   30 ++-
 kernel/core/compile.rb                |    6 +-
 kernel/core/compiled_method.rb        |    7 +-
 kernel/core/context.rb                |   26 ++-
 kernel/core/io.rb                     |    3 +
 kernel/core/string.rb                 |   91 ++++++--
 lib/bin/compile.rb                    |  176 ++++++++++++---
 lib/bin/sirb.rb                       |   22 +-
 lib/ext/syck/build.rb                 |    6 +
 lib/ext/syck/rbxext.c                 |   12 +-
 lib/stringio.rb                       |  413 +++++++++++++++++++++++++++++++++
 runtime/bootstrap.rba                 |  Bin 29758 -> 29986 bytes
 runtime/compiler.rba                  |  Bin 79208 -> 81314 bytes
 runtime/core.rba                      |  Bin 162952 -> 168854 bytes
 runtime/loader.rbc                    |  Bin 12565 -> 12651 bytes
 shotgun/lib/cpu.h                     |   13 +-
 shotgun/lib/cpu_primitives.c          |   18 ++
 shotgun/lib/cpu_task.c                |   11 +
 shotgun/lib/instructions.rb           |   13 +-
 shotgun/lib/methctx.c                 |    5 +-
 shotgun/lib/methctx.h                 |    2 +-
 shotgun/lib/primitives.rb             |   75 +++----
 spec/mini_rspec.rb                    |    8 +-
 32 files changed, 849 insertions(+), 168 deletions(-)
 delete mode 120000 bin/sirb.rb
 create mode 100644 lib/ext/syck/build.rb
 create mode 100644 lib/stringio.rb

But, hei, maybe it's just me :)

See all comments

Join the Tetris day

Just a quick note: if you are an italian reader, or if you're in italy in the end of september pick your piece and join us in the tetramine day :)

See all comments

AliceML concurrency

In these days it seem that Erlang is considered the end of all concurrency debates. and it actually seem to provides a very nice environment for concurrent programming, possibly because it was designed to do so :)

Yet there is another environment that was designed to provide good support for concurrent programming and that I find very interesting, but is not as "hyped". I'm thinking of AliceML.

I'll try to explain the basic concepts, but I'm not really proficient in ML and I may be wrong about something, so please feel free to correct my code.

A simple echo server in Alice is something like this


import structure Socket from "x-alice:/lib/system/Socket"

fun serve (socket, host, port) =
   let 
      val lineOpt = Socket.inputLine socket
   in
      case lineOpt of
          (* read something *)
           SOME(line) => print line
          (* read nothing *)
         | NONE => ()
      ;

      Socket.close socket
   end


val port = SOME 8802;
val (socket, port) = Socket.server (port, serve);

(I know the case line is somewhat strange, but keep in mind that Alice is a completely type safe programming language. Yes, no type declarations in the above code, Yay for type inference!)

Anyway, the above code will impose an ordering on the serving of clients, because client Y will be waiting for client X to finish before the serve function is called for it.

Now, in AliceML to make an expression concurrent you just need to prefix it with spawn, so for example you can write:

spawn print ( complex_calc () )

And you'll have the calculation happen in a concurrent thread.

So, how does this relates to our serve function? Simple, you can declare a function as being always computed in a different thread replacing fun with fun spawn.

By adding one word you have completed your transition from a serial server to a multithreaded uber-responsive concurrent HTTP server that competes with lighttpd, YAWS and ngix. Or, actually, not, but you have a concurrent echo server, which is nice.

Getting values

As of now there is little difference with pthread-style or unix-processes concurrency at all. The real difference is in the presence of a result in the spawned expression. Basically whenever a spawned expression is evaluated it returns a Future value, meaning something that is not yet a real value, but will become soon. It's like your void-ish concurrent stuff in C/Java/Ruby/Python suddenly could return something. the question is: what?

Well, a spawned expression will return something called a Future, that works as a placeholder for the real value.

The main computation will work concurrently with the spawned computation and it will lock just when it needs the actual value of the spawned computation. At that point:

  • the main computation waits
  • the concurrent computation finish its work
  • the Future in the main computation is replaced with the concurrently produced value
  • the main computation can resume its work and go on

This means that, for example, to concurrently transform a list you may do:


map (fn x => spawn calc x) [1,2,3,4]

And it will not lock as long as you don't access the list elements. Given the ease you can write this stuff, it is also ultra-simple to define your own parallel map like this:


fun pmap f l = map (fn x => spawn f x) l;

When trouble strikes

But wait: what happens if a Thread fails for some reason? Simple, the Future it returns will be a Failed Future and it will do exactly what you expect: it will cause a failure whenever it is accessed. So you have two chances:

  • the result is actually important, and a failure means the global result is invalid (i.e. using the values in a concurrently computed list). Then you are accessing the Failed Future and the error propagates, as expected.
  • if a single concurrent computation fails utterly you don't care (i.e. network server), so you just avoid handling the Future object and you will never know anything about the failure, somewhat like erlang's asynchronous message passing.

I like this, it seems like an evolutionary step from old-style concurrency that is not complicated yet works, plus it blurs the line between synchronous and asynchronous message passing, which is a great thing in my opinion.

There is more than this in Alice's concurrency, for example handling shared values, the difference between Thread and OS Processes, atomic state change and so on, but all built on top of this primitives, AFAICT. Take a look at it, it even comes with a GTK gui ;)

See all comments

My Tiny DocTest for ruby

I believe that doctest for python is one of the best test libraries available, because it pushes the cost to develop functional tests to zero.

While I’m writing a dummy object persistence layer I thought it would have been nice to have something like that, basically seeking some kind of literate testing process.

This is the first attempt at it (warning dirty, slow, duplicated code).

It somehow works, can be run from rcov/rake/ruby, loaded with multiple files, and allows writing nice tests like this one . As you can see in the code, everything that does not look like irb code is ignored, which allows adding comments, leave python code mixed with ruby, write formulas and so on.

The lib is really half-backed, for example you canì’t use multiline declarations in irb or print something to screen, but I think it is a nice small thing.

You can find a different take on sample/doc testing in manveru’s repository

See all comments

Using darcs with FTP and without SSH

darcs is my favourite Version Control System. I'm not chris and I have not tried a lot of them, but I just love darcs' cherry picking so everything that misses that is out of my list. Maybe monotone or subversion 1.5 would be interesting.

Anyway, my only issue with darcs is that it does not allow pushing changes to a dumb repository, where dumb means ftp.

Since I don't have ssh access on all my hostings I found the solution in sitecopy which is a nifty utility to keep a remote directory in sync with a local one by doing incremental uploads.

To use this simply install sitecopy (which is probably avilable through your linux/bsd flavour package manager) and create a file ~/.sitecopyrc with a content like this:


site myproject
  server  ftp.myserver.com
  remote  /www/darcs.myserver.com/myproject
  local   /path/to/local/repository
  username  joe
  password  123

and to create a directory ~/.sitecopy. The permission mask for the dir must be 0700 and for the rc file it must be 0600, otherwise sitecopy will complain about insecure files.

At this point you just need to init the remote repository by doing sitecopy --init myproject. It may take some time because the first time you'll be uploading all the old patches in the _darcs/ directory, but the next time you will do this, using sitecopy --update myproject it will be quite fast.

Obviously this approach works nicely only in a single-user environment, because if multiple users share the remote directory there will be inconsistencies, but it is useful to keep your copy of a projects' repository where you can have your patches and where you can point people that want them.

See all comments

Atom Threading Extension FeedFlare

As I was saying in the other article, I implemented a simple dynamic FeedFlare to show the number of comments in your feed, based on the Atom Threading Extensions. The flare provides a link to $yourPageUrl#comments, it could be made more modular if someone needs that.

Basically this means that you need a <link> in your atom feed with rel="replies" and thr:count="123". The flare is not really smart in that it does not take the xmlns declaration into account (yet) so declare it like xmlns:thr="http://purl.org/syndication/thread/1.0".

Experimentally, the flare is available for your own use by using the address:

http://flarez.riffraff.inf/ate/

Just add it through myfeeds->optimize->feedlare. Depending on load the flare may be cached for some hours so don't worry if you don't see updates immediately.

See all comments

How to add Atom Threading Extension to Mephisto

Mephisto, the software that I use for this blog is a great little work.

It doesn't do everything and more, but the default installation provides a very nice administration interface and the most useful functionalities of a blogging system, namely tagging, feeds, comments, and so on. it has a good themeing system, an extensible architecture and a lot of plugins.

The only thing that I believe is missing is a good plugin for syntax highlighting code. There are a couple of them but both support a very restricted set of grammars so I'm not really satisfied and I'm working on a plugin based on vim.

Back to the topic. I always liked FeedBurner's FeedFlares, especially the one that provides comment counting.

That flare is based on RSS' wfw:comments, and basically works by accessing the comment feed linked from the main one and parsing that.

The Atom Threading Extensions allow a more detailed control of this linkage between feeds, more metadata and in the specific, they allow the embedding of the comment count (not only comments, the correct word is "replies") in the main feed, freeing you from the need to parse another feed.

To add this to mephisto you need to change a couple of lines, it would be possible to repackage this as a plugin, but I don't have time to investigate that ATM. In case you want to use this hack, you can see the diff against svn HEAD here

See all comments

Rails vs Django: a non biased yet useless comparison

Lately I've been making my hands a little bit dirty with django, and since I already did a little bit of Rails I think I'm entitled to do a small comparison. No, this is a lie. I'm entitled to do that because I have a blog and that's it.

The non biased assertion is due to the fact that I like both frameworks and I do love both languages, the useless one is well, because you will still have to evaluate the things by yourself , cause I am not an expert at either and I think that my few readers are smart enough to understand that choosing an infrastructure requires more work than reading a random blog entry.

Both frameworks use the new classic MVC pattern (even if in django's lingo it's called MTV you will notice that it is 99.9% the same), and both framework provide some othe features, so I'll just split the comparison by these concepts.

* Model * The model layer in django and rails is basically built out of classes that map to DB tables, but the things are slightly different.

The model in rails is comprised of two things: an SQL definition and a Ruby definition. Yes I know about Dr Nic's magic models. You can also create the database in pure ruby by using the wonderful migrations' system that rails provides, but the model is still built out of the pair DB structure + Ruby code. AFAIK django doesn't have yet something on the level of Rails migrations, that allows you to programmatically move back and forth in time easily.

Django uses a single definition in python with more metadata, and provides some useful python datatypes that are mapped transparently on the DBMS, so that a Post class can have a SlugField, while a Comment can have EmailField and IPAddressField. Yet, you can still go down to the SQL level if you want.

It seem to me that the support for validation is quite similar under the surface for both frameworks: you can validate single fields ot whole objects at different times and stack different validators.

One big flaw in current django's models is that they don't allow inheritance, and so if you have a lot of models that differ just slightly you can't save work using this approach. Rails' ActiveRecord gets a big plus for this, but this should be solved soon in django.

* "the thing that does *which" ** Rails calls the module that chooses which data to show the Controller. For some reason Django calls it the View whereas the Controller is the underlying support software.

Rails which is made of two elements: Controller objects and actions. A request for a page is processed so that it instantiates a Controller object and setups variables appropriately, then the action method is called. At the class level you can define behaviour shared between the various action with a nice syntax, but I don't particularly love the :except and :only things.

In django an action is just a function which takes a fixed argument, the request, and an optional set of named arguments. I love the way named arguments work in python and I think that this approach provides much more readability, but to have that in ruby we will have to wait for ruby 2.0 (or use evil.rb which doesn't feel enterprisey).

The only thing I dislike in django's view is that you have to explicitly point out to a template file when rendering a view, whereas rails' convention over configuration in this case relieves the user of a repetitive and non-interesting operation.

I also think that not having the class Foo < Controller boilerplate is better, but the bad news is that django doesn't do magic requiring of modules and you have to do it yourself, so everything balance out.

Both systems allow caching but (for what I understood) Django mostly uses time-based cache invalidation, while rails provides only an event-based expiring behaviour.

Anyway there are plugins for rails that allow time based invalidation, and I believe that it should be possible to expire something in an event-based fashion in django too, cause the underlying mechanics are the same (CACHE.set(key,val), CACHE.get(key) and CACHE.del(key)).

It seems that django doesn't provide the fine-grained caching control that rails has, allowing just a whole-page caching or forcing the user to resort to the low level cache api, which I think is a bad thing.

Finally, django uses exceptions to handle error codes, which I believe is a far better solution than rails :status=>code, because it allows breaking out of an action from an utility method. This allows, the refactoring control in utility methods, having shortcuts such as get_object_or_404(Class,key=val), which simplify the writing of views.

* "the thing that does _how_" * The actual showing of data is usually done in both frameworks through templates, which rails call Views. Django uses an interestint template language while rails uses ruby embedded in XHTML by deafult, but different templating engines can be used as plugins very easily.

Both allow the composition of smaller units to enhance reuse and ease of maintenance and it I believe that apart from personal preferences there are not big differences in this area.

* Other things * I think that the main differences in rails and django can be appreciated going away from the basic elements and looking at the rest of the platform, where the frameworks differ greatly.

First, django provides internationalization as a builtin concept while in django you're forced to use external libraries such as Globalize. Sadly, I am convinced that this is such an important feature that it must be builtin and it is an error not to have it, because to do it right the framework must be engineered around it. It must be also noticed that python's support for unicode (and other text encodings) in general is far more advanced than ruby's, which basically just kind-of-supports utf-8 (wait for ruby2, again).

Second, django's automatic generation of an administration facility, complete with authorization support and a bunch of space for customization is amazing. Again, there are modules for rails that provide this kind of behaviour, but having such a feature builtin makes it a foundation and a reference against which every programmer can code, which makes coee sharing easier.

In general django has builtin support for a lot of functionalities that are common in modern web apps, not only admin and auth, but also sitemaps, syndication, comments and much more.

Rails takes a minimalistic approach on this and pushes all this stuff in plugins. The rails community is producing plugins at an incredible rate, and even if not all of them are compatible and high quality code there is a lot of choice.

In the old days rails' plugins used to have some issues and this was the reason for the existence of things like rails engines but as of 1.2 this problems are not there anymore, Django allows code sharing through the integration of different apps which is what the admin above mentioned features are, and each of this add-on can contain something as easy as a textilize() function to a whole application such as a wiki or a blog.

There are not so much django apps as there are rails plugins, and I believe that this depends on 3 factors

  • smaller community
  • slightly harder sharing (in rails you just user script/plugin install and you're done)
  • less duplication The latter is hardly dependent on django coming with more batteries included, so for example you don't need a plugin for creating slugs because there is a lready a slugify() function.

* Conclusion * I wish rails had more batteries included, and that ruby was a little bit more like python (i.e. modules, named args, function decorator syntax). And I wish django used more conventions/less typing, and python was more like ruby (blocks, functions call without parenthesis, implicit self). but I still like both, pick your choice or even better try both. This at least will make you ready to write your own framework ;)

See all comments

Understanding identity standards

this is just too funny not to deserve a link :)

See all comments

AddThis Social Bookmark Button