Our grant task has commenced. Here's how our plan of attack looks for the coming weeks.
I started just throwing loose thoughts into a PLAN file. It is not complete by any means, but it has got me thinking about specifying. (wayland++ for contributing.)
Also, I've been visiting channels with web framework people and had fruitful discussions. One of these went on the november-wiki list for everyone to read. My overall impression is that people are very helpful and eager to share their experiences. ("Don't make the mistakes we make," they say. "Make new ones.")
The third thing I've done is try to quench my curiosity of Sinatra by reading the source. Ruby code is very cute, and quite readable most of the time even for an outsider like me. I think one of the first things I'll get working in Web.pm is this script, also found in the PLAN file above. That script is a direct translation of the script found here. Eager to find out how that get
call worked, I went and dug it out of the Sinatra source. Here it is:
def get(path, opts={}, &block) conditions = @conditions.dup route('GET', path, opts, &block) @conditions = conditions route('HEAD', path, opts, &block) end
In short, a call to another method called route
is made, and an instance variable conditions
is cloned and reinstated, probably because it was clobbered by the first call.
Ok, so how does route
look? I thought you'd never ask:
def route(verb, path, opts={}, &block) host_name opts[:host] if opts.key?(:host) user_agent opts[:agent] if opts.key?(:agent) accept_mime_types opts[:provides] if opts.key?(:provides) pattern, keys = compile(path) conditions, @conditions = @conditions, [] define_method "#{verb} #{path}", &block unbound_method = instance_method("#{verb} #{path}") block = lambda { unbound_method.bind(self).call } (routes[verb] ||= []). push([pattern, keys, conditions, block]).last end
A bit more code, but still not horribly much. What happens here? A few reasonable settings are made if they come in through opts
. We compile
the path (whatever that means), clobber conditions
just as we thought we would (actually, we clear it), create a closure which calls a method on self
, and then put it all into a routes
hash (and also return it).
It all seems quite straightforward. The only question that remains in my mind is what compile
does.
def compile(path) keys = [] if path.respond_to? :to_str pattern = URI.encode(path).gsub(/((:\w+)|\*)/) do |match| if match == "*" keys << 'splat' "(.*?)" else keys << $2[1..-1] "([^/?\.]+)" end end [/^#{pattern}$/, keys] elsif path.respond_to? :=~ [path, keys] else raise TypeError, path end end
This method concerns itself with stringlike things and matchlike things. If what it finds conforms to its expectations, it returns a regex and an array of keys. If I'm reading this correctly, the simple string 'hi'
in path
would enter the else
leg of the innermost if
statement, and 'hi'
would end up as the single element in keys
.
Hm, I'm one step closer to understanding this. It's basically a dispatcher. I'll talk more to Ilya about it; he's written November's dispatcher, and plans to do the one in Web.pm.
One final thing this week: the naming issue. The grant committee expressed slight doubts about the name Web.pm, so I wrote this and had this discussion on #perl6. After thinking a lot about this, I think we should keep the "Web.pm" name for the whole thing, but strive to name every component inside (dispatcher, tags library, templating engine, MVC framework, etc) to show that we really only provide these as reasonable defaults.
That ties in with our overall goal to make the Web.pm bundle a set of very reasonable defaults for web development. But most modules can be used outside the context of Web.pm as well, and conversely, modules in Web.pm can be replaced with other modules, and will work just as well as long as they adhere to some API. That's the idea anyway.
I wish to thank The Perl Foundation for sponsoring the Web.pm effort. We're very excited about this.
I think the project is great, but I don't care for the name Web.pm. It seems too all-encompassing, but at the end of the name, it's probably not that big of a deal. On the other hand, you can check synonyms from thesaurus.com:
cobweb, complexity, entanglement, fabric, fiber, filigree, gossamer, interconnection, interlacing, involvement, labyrinth, lacework, lattice, mat, matting, maze, mesh, meshwork, morass, net, network, plait, reticulation, screen, skein, snarl, tangle, texture, tissue, toil, trellis, warp, weave, webbing, weft, wicker, woof
I kind of like Lattice.pm or Trellis.pm, though Gossamer.pm sounds nice, too
Re:The Name
masak on 2009-03-09T10:34:30
Thank you for your suggestions. Some people don't care for the name Web.pm, some do, it seems. It might or might not be a good idea to discuss the merits of the name in the comments of this blog post.
:) I'll end here before I start to give reasons for liking Web.pm. I already did that in links from the post.