--- 
author: 
  email: ash@firemirror.com
  keyid: bfc7465ebdca5337
  name: Ash Berlin
categories: []

date: 2007-11-13T14:17:52Z
guid: E49FCDBE-91F2-11DC-A044-E9B3BA99506B
modified: 2007-11-13T14:41:15Z
raw: "Last night a friend of mine linked to an article on [Rand's In Repose](http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html), and naturally I opened up a few tabs to browse his past literary masterpieces. I eventually came across 'The Cave'.\n\nAnd this got me thinking.\n\nNot about my cave, but about The Place. His Place is World Of Warcraft. (My place certainly isn't a slow running train into London Paddington, but at least I have my precious intorwebnet thanks to my Nokia N95.) I've never got on with WoW. Its never quite felt right to me. Why I (don't) hear you ask? Because I'm still pinning after Ultima Online.\n\nFirst some backstory of my experience of Vegemites. (A numer of years ago there was an article on Penny Arcade that decided MMOPRG is such an awkward term to use, and advocated using the term Vegemite instead. I agreed with it.Edit: [web.archive.org++](http://web.archive.org/web/20060110120656/www.penny-arcade.com/morgantwo.php)) I suppose the first MMO that I played was Isengard - a text based MUD - some time around 1997. 1997, when we still had dial-up-modems and had to pay per minute for the telephone calls... luckily my dad also got hooked, so when the quarterly telephone bill came in at around £300, he was equally to blame - thank god.\n\nAround this time Ultime Online was released. And my god did I want. I'd been hooked on the Ultima series since Ultime VI (so much so that I memorized the answers to all the questions that Lord British could ask you.) And Holy of Holies! NTL also had a dial-up service where you didn't have to pay per minute to use it. I was hooked. Origin did indeed Create Worlds.\n\nBack in 1998/9 Ultima Online was a wildly different beast to what it is today - back before EA got thier gubby mits on it. There was just the one facet (Felluca. Each server basically had two copies of the world) - non of this namby-pamby weaker monsters and no PVP that later got introduced when Trammel was introduced.\n\nSo what in particular did I like about UO? The crafting. I do think I spent too much time in that game mining near Minoc, or wondering around the forests between Yew and Skara Brae with nothing but a battle axe, some carpentry tools and barely a loin cloth for protection, hoping that I would make it back to my house alive. Yes - player owned housing!\n\nHaving a house that you could keep your stuff in, decorate how you want and keep all your possessions in (yes there was a bank like there is in WoW, but it had limited space/weight) was nice, but it wasn't the reason why I would *still* prefer to play UO than WoW or any of the dozen odd MMOs that I have beta-tested since (me and a housemate at uni went thru a phase of trying to get on every single closed-beta, open-beta, pre-alpha or play test we could). \n\nIts was the leveling system. Or rather the lack of it. WoW you have skills directly related to your level - give or take variations on what skills the player chooses. Ultime Online had no concept of level. No clicking on a person and seeing they are 5 levels lower than you. Each player had a maximum of 700 skill points to distribute as they saw fit among more than around 40 different skills. Want to be proficient with both a sword and with magic? Fine, you can try it. You'd obviously not be as good as a pure mage or a pure fighter due to not having the complementary skills, but you could still kick ass if you did it right.\n\nThe other thing I miss about UO that i've not found anywhere else was its Fame and Notoriety system.  In UO you'd open the person's paper (or was it papal) doll and see \"The Glorious Lady Aliah, Grandmaster Stoic\". (She was my guild mistress.) Or \"The Dread Lord Azekial, Grandmaster Fighter\".\n\nSo much more character then \"Level 70 Night Elf\".\n\nOrigin, you truly did create worlds. Then the Destroyer came and pandered to the wimps who complained that they got ganked and had thier silver kryss of power stolen. Didums. You ruined it for all of us.\n"
signed: 1
summary: " Last night a friend of mine linked to an …"
tags: 
  - 
    bitching: 0
  - 
    games: 0
text: "\nLast night a friend of mine linked to an article on Rand's In Repose\n[1], and naturally I opened up a few tabs to browse his past literary\nmasterpieces. I eventually came across 'The Cave'.\n\nAnd this got me thinking.\n\nNot about my cave, but about The Place. His Place is World Of Warcraft.\n(My place certainly isn't a slow running train into London Paddington,\nbut at least I have my precious intorwebnet thanks to my Nokia N95.)\nI've never got on with WoW. Its never quite felt right to me. Why I (-\ndon't) hear you ask? Because I'm still pinning after Ultima Online.\n\nFirst some backstory of my experience of Vegemites. (A numer of years\nago there was an article on Penny Arcade that decided MMOPRG is such an\nawkward term to use, and advocated using the term Vegemite instead. I\nagreed with it.Edit: web.archive.org++ [2]) I suppose the first MMO\nthat I played was Isengard - a text based MUD - some time around 1997.\n1997, when we still had dial-up-modems and had to pay per minute for\nthe telephone calls... luckily my dad also got hooked, so when the\nquarterly telephone bill came in at around £300, he was equally to\nblame - thank god.\n\nAround this time Ultime Online was released. And my god did I want. I'd\nbeen hooked on the Ultima series since Ultime VI (so much so that I\nmemorized the answers to all the questions that Lord British could ask\nyou.) And Holy of Holies! NTL also had a dial-up service where you did-\nn't have to pay per minute to use it. I was hooked. Origin did indeed\nCreate Worlds.\n\nBack in 1998/9 Ultima Online was a wildly different beast to what it is\ntoday - back before EA got thier gubby mits on it. There was just the\none facet (Felluca. Each server basically had two copies of the world) -\nnon of this namby-pamby weaker monsters and no PVP that later got intro-\nduced when Trammel was introduced.\n\nSo what in particular did I like about UO? The crafting. I do think I\nspent too much time in that game mining near Minoc, or wondering around\nthe forests between Yew and Skara Brae with nothing but a battle axe,\nsome carpentry tools and barely a loin cloth for protection, hoping that\nI would make it back to my house alive. Yes - player owned housing!\n\nHaving a house that you could keep your stuff in, decorate how you want\nand keep all your possessions in (yes there was a bank like there is in\nWoW, but it had limited space/weight) was nice, but it wasn't the reason\nwhy I would still prefer to play UO than WoW or any of the dozen odd\nMMOs that I have beta-tested since (me and a housemate at uni went thru\na phase of trying to get on every single closed-beta, open-beta, pre-al-\npha or play test we could).\n\nIts was the leveling system. Or rather the lack of it. WoW you have\nskills directly related to your level - give or take variations on what\nskills the player chooses. Ultime Online had no concept of level. No\nclicking on a person and seeing they are 5 levels lower than you. Each\nplayer had a maximum of 700 skill points to distribute as they saw fit\namong more than around 40 different skills. Want to be proficient with\nboth a sword and with magic? Fine, you can try it. You'd obviously not\nbe as good as a pure mage or a pure fighter due to not having the com-\nplementary skills, but you could still kick ass if you did it right.\n\nThe other thing I miss about UO that i've not found anywhere else was\nits Fame and Notoriety system. In UO you'd open the person's paper (or\nwas it papal) doll and see \"The Glorious Lady Aliah, Grandmaster Sto-\nic\". (She was my guild mistress.) Or \"The Dread Lord Azekial, Grandmas-\nter Fighter\".\n\nSo much more character then \"Level 70 Night Elf\".\n\nOrigin, you truly did create worlds. Then the Destroyer came and pan-\ndered to the wimps who complained that they got ganked and had thier\nsilver kryss of power stolen. Didums. You ruined it for all of us.\n\n-- \n [1] http://www.randsinrepose.com/archives/2007/11/11/the_nerd_han-\n     dbook.html\n [2] http://web.archive.org/web/20060110120656/www.penny-\n     arcade.com/morgantwo.php\n"
title: The Place
type: markdown
uri: http://perlitist.com/articles/the_place
xhtml: "<p>Last night a friend of mine linked to an article on <a href=\"http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html\">Rand&apos;s In Repose</a>, and naturally I opened up a few tabs to browse his past literary masterpieces. I eventually came across &apos;The Cave&apos;.</p><p>And this got me thinking.</p><p>Not about my cave, but about The Place. His Place is World Of Warcraft. (My place certainly isn&apos;t a slow running train into London Paddington, but at least I have my precious intorwebnet thanks to my Nokia N95.) I&apos;ve never got on with WoW. Its never quite felt right to me. Why I (don&apos;t) hear you ask? Because I&apos;m still pinning after Ultima Online.</p><p>First some backstory of my experience of Vegemites. (A numer of years ago there was an article on Penny Arcade that decided MMOPRG is such an awkward term to use, and advocated using the term Vegemite instead. I agreed with it.Edit: <a href=\"http://web.archive.org/web/20060110120656/www.penny-arcade.com/morgantwo.php\">web.archive.org++</a>) I suppose the first MMO that I played was Isengard - a text based MUD - some time around 1997. 1997, when we still had dial-up-modems and had to pay per minute for the telephone calls... luckily my dad also got hooked, so when the quarterly telephone bill came in at around £300, he was equally to blame - thank god.</p><p>Around this time Ultime Online was released. And my god did I want. I&apos;d been hooked on the Ultima series since Ultime VI (so much so that I memorized the answers to all the questions that Lord British could ask you.) And Holy of Holies! NTL also had a dial-up service where you didn&apos;t have to pay per minute to use it. I was hooked. Origin did indeed Create Worlds.</p><p>Back in 1998/9 Ultima Online was a wildly different beast to what it is today - back before EA got thier gubby mits on it. There was just the one facet (Felluca. Each server basically had two copies of the world) - non of this namby-pamby weaker monsters and no PVP that later got introduced when Trammel was introduced.</p><p>So what in particular did I like about UO? The crafting. I do think I spent too much time in that game mining near Minoc, or wondering around the forests between Yew and Skara Brae with nothing but a battle axe, some carpentry tools and barely a loin cloth for protection, hoping that I would make it back to my house alive. Yes - player owned housing!</p><p>Having a house that you could keep your stuff in, decorate how you want and keep all your possessions in (yes there was a bank like there is in WoW, but it had limited space/weight) was nice, but it wasn&apos;t the reason why I would still prefer to play UO than WoW or any of the dozen odd MMOs that I have beta-tested since (me and a housemate at uni went thru a phase of trying to get on every single closed-beta, open-beta, pre-alpha or play test we could). </p><p>Its was the leveling system. Or rather the lack of it. WoW you have skills directly related to your level - give or take variations on what skills the player chooses. Ultime Online had no concept of level. No clicking on a person and seeing they are 5 levels lower than you. Each player had a maximum of 700 skill points to distribute as they saw fit among more than around 40 different skills. Want to be proficient with both a sword and with magic? Fine, you can try it. You&apos;d obviously not be as good as a pure mage or a pure fighter due to not having the complementary skills, but you could still kick ass if you did it right.</p><p>The other thing I miss about UO that i&apos;ve not found anywhere else was its Fame and Notoriety system. In UO you&apos;d open the person&apos;s paper (or was it papal) doll and see &quot;The Glorious Lady Aliah, Grandmaster Stoic&quot;. (She was my guild mistress.) Or &quot;The Dread Lord Azekial, Grandmaster Fighter&quot;.</p><p>So much more character then &quot;Level 70 Night Elf&quot;.</p><p>Origin, you truly did create worlds. Then the Destroyer came and pandered to the wimps who complained that they got ganked and had thier silver kryss of power stolen. Didums. You ruined it for all of us.</p>"
--- 
author: 
  email: ash@firemirror.com
  keyid: bfc7465ebdca5337
  name: Ash Berlin
categories: []

date: 2007-09-29T21:58:51Z
guid: E6ABD362-6EB3-11DC-8EA1-D6A1BB7FECD7
modified: 2007-11-16T20:22:04Z
raw: "I spent most of last week preparing a new server to deploy a project onto a \nnice shiny new [1&1 Dedicated Server](http://www.1and1.co.uk/?k_id=10200518) \n(oh and if you buy something from that link I get a referral bonus - yay!) \nAll the boring stuff like bootstrapping a fresh Debian install onto the \ndisks from a rescue image; fighting the bootloader to make it work with no\nindication of errors when I make a mistake since I have no physical access to\nthe machine - you know: the ususal.\n\nSo once I'd finished those mundane tasks I had to setup the webserver. \nPreviously I'd have gone straight for Apache 2. However I'm deploying a\nCatalyst application to the machine, and although Catalyst will run under\nmod_perl, the recommended method is to use FastCGI since it turns out to be a\nlot less hassle in the long run.\n\n## Aims with FastCGI \n\nWhat I want from my FastCGI deployment:\n\n* to have two seperate FastCGI managers running, so that whenever I need to upgrade the code, I can shut one down, bring it back up with the new code, then do the same for the other - thus giving me the ability to upgrade the code with no downtime (assuming of course that there are no DB changes that might require downtime etc. etc.)\n* to have the static content served via the webserver, since this is what they do well\n* to not have fastcgi show up anywhere in the URL.\n\n## Apache...? \n\n\nDoing this with Apache+mod_fastcgi seems impossible though, since Apache's \nhandling of FastCGI isn't briliant. To do this in Apache you basically have to\ncreate two vhosts (and optionally give them ServerName's that dont resolve\nexternally) and then `Alias / /path/to/fastCGI/N.socket`. \n\nStill with me? 'cos we're not done yet. In the main vhost for the server (i.e. www.myapp.com) you\nthen have to create a [balanced proxy](http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#ProxyPass)\nlike the following:\n\n    ProxyPass / balancer://myapp-cluster\n    &lt;Proxy balancer://myapp-cluster>\n      BalanceMember http://myapp-1.internal\n      BalanceMember http://myapp-2.internal\n      Allow from all\n      Order Allow,Deny\n    &lt;/Proxy>\n\nComplex, no? And whats worse, is that it doesn't even cope with one of the \nbackend FastCGI servers being down - you just get a 500 page served to the \nuser. Bad Apache! Try the other (FastCGI) server please! \n\n## The Solution - Lighttpd\n\nAfter a bit of Googling, it seems like Apache just wont cope with this \nsituation. I've been hearing good things about Lighttpd, particularly that its\n[FastCGI](http://www.lighttpd.net/documentation/fastcgi.html) support is \nnative and much better.\n\nThe interesting bits of lighttpd config I've used:\n\n    lang:perl\n    server.moudles += (\n        \"mod_alias\",\n        \"mod_rewrite\",\n        \"mod_redirect\",\n        \"mod_setenv\",\n    )\n\nPretty self explanatory - load some of the modules we need. The rest of the\nconfig goes inside the `$HTTP[\"host\"] =~ \"www.mysite.com\"` directive.\n\n    lang:perl\n        # Let lighttpd take care of serving that static content\n        alias.url = (\n          \"/favicon.ico\" => \"/var/www/mysite.com/MySite/root/favicon.ico\",\n          \"/js/\"   => \"/var/www/mysite.com/MySite/root/js/\",\n          \"/css/\"  => \"/var/www/mysite.com/MySite/root/css/\",\n          \"/tour/\" => \"/var/www/mysite.com/MySite/root/tour/\",\n        )\n\n        # rewrite-once will stop processing after the first match\n        url.rewrite-once = (\n          \"^/((?:js|css|tour)/.*)\" => \"/$1\",\n          \"^/favicon.ico\" => \"/favicon.ico\",\n          \"^/(.*)\" => \"/fcgi/$1\"            \n        )\n    }\n\nThese two bits tell lighttpd to handle all the static content itself, and \nthen forward everything else off to the /fcgi path, which is defined as \nfollows:\n\n    lang:perl\n      fastcgi.server = (\n        \"/fcgi\" => (\n          ( \"host\" => \"127.0.0.1\", \"port\" => 3010, \"check-local\" => \"disable\"),\n          ( \"host\" => \"127.0.0.1\", \"port\" => 3011, \"check-local\" => \"disable\")\n        )\n      )\n    \nFairly obvious - everything under `/fcgi` is handled by the FastCGI servers.\nNote however that this will make Catalyst think it is based at \n`http://mysite.com/fcgi/` which it isn't, so we need to fix it:\n\n    lang:perl\n        $HTTP[\"url\"] =~ \"^/\" {\n          setenv.add-environment = ( \"SCRIPT_NAME\" => \"/\" )\n        }\n\nThat does the job - Catalyst now thinks its rooted at `/`, and lighttpd is now\nhandling all the static content itself.\n\nFor the completeness-sake, I've included the full config as a single block \nbelow.\n\n    lang:perl\n    $HTTP[\"host\"] =~ \"^mysite.com\" {\n        url.redirect = ( \"^/(.*)\" => \"http://www.mysite.com/$1\" )\n    }\n\n    $HTTP[\"host\"] =~ \"www.mysite.com\" {\n\n        # dir listings are bad\n        server.dir-listing = \"disable\"\n\n        server.errorlog    = \"/var/log/lighttpd/mysite.com.error.log\"\n        accesslog.filename = \"/var/log/lighttpd/mysite.com.access.log\"\n\n        # Let lighttpd take care of serving that static content\n        alias.url = (\n          \"/favicon.ico\" => \"/var/www/mysite.com/MySite/root/favicon.ico\",\n          \"/js/\"   => \"/var/www/mysite.com/MySite/root/js/\",\n          \"/css/\"  => \"/var/www/mysite.com/MySite/root/css/\",\n          \"/tour/\" => \"/var/www/mysite.com/MySite/root/tour/\",\n        )\n\n        # rewrite-once will stop processing after the first match\n        url.rewrite-once = (\n          \"^/((?:js|css|tour)/.*)\" => \"/$1\",\n          \"^/favicon.ico\" => \"/favicon.ico\",\n          \"^/(.*)\" => \"/fcgi/$1\"            \n        )\n\n        fastcgi.server = (\n          \"/fcgi\" => (\n            ( \"host\" => \"127.0.0.1\", \"port\" => 3010, \"check-local\" => \"disable\"),\n            ( \"host\" => \"127.0.0.1\", \"port\" => 3011, \"check-local\" => \"disable\")\n          )\n        )\n\n        $HTTP[\"url\"] =~ \"^/\" {\n          setenv.add-environment = ( \"SCRIPT_NAME\" => \"/\" )\n        }\n\n    }\n\n"
signed: 1
summary: " I spent most of last week preparing a new …"
tags: 
  - 
    lighttpd: 0
  - 
    catalyst: 0
  - 
    fastcgi: 0
text: "\nI spent most of last week preparing a new server to deploy a project on-\nto a nice shiny new 1&1 Dedicated Server [1] (oh and if you buy some-\nthing from that link I get a referral bonus - yay!) All the boring stuff\nlike bootstrapping a fresh Debian install onto the disks from a rescue\nimage; fighting the bootloader to make it work with no indication of er-\nrors when I make a mistake since I have no physical access to the ma-\nchine - you know: the ususal.\n\nSo once I'd finished those mundane tasks I had to setup the webserver.\nPreviously I'd have gone straight for Apache 2. However I'm deploying a\nCatalyst application to the machine, and although Catalyst will run un-\nder mod_perl, the recommended method is to use FastCGI since it turns\nout to be a lot less hassle in the long run.\n\nAIMS WITH FASTCGI\n\nWhat I want from my FastCGI deployment: to have two seperate FastCGI\nmanagers running, so that whenever I need to upgrade the code, I can\nshut one down, bring it back up with the new code, then do the same for\nthe other - thus giving me the ability to upgrade the code with no down-\ntime (assuming of course that there are no DB changes that might require\ndowntime etc. etc.)to have the static content served via the webserver,\nsince this is what they do wellto not have fastcgi show up anywhere in\nthe URL. APACHE...?\n\nDoing this with Apache+mod_fastcgi seems impossible though, since A-\npache's handling of FastCGI isn't briliant. To do this in Apache you\nbasically have to create two vhosts (and optionally give them\nServerName's that dont resolve externally) and then Alias / /path/to/-\nfastCGI/N.socket.\n\nStill with me? 'cos we're not done yet. In the main vhost for the server\n(i.e. www.myapp.com) you then have to create a balanced proxy [2] like\nthe following:\n\nComplex, no? And whats worse, is that it doesn't even cope with one of\nthe backend FastCGI servers being down - you just get a 500 page served\nto the user. Bad Apache! Try the other (FastCGI) server please!\n\nTHE SOLUTION - LIGHTTPD\n\nAfter a bit of Googling, it seems like Apache just wont cope with this\nsituation. I've been hearing good things about Lighttpd, particularly\nthat its FastCGI [3] support is native and much better.\n\nThe interesting bits of lighttpd config I've used:\n\nPretty self explanatory - load some of the modules we need. The rest of\nthe config goes inside the $HTTP[\"host\"] =~ \"www.mysite.com\" directive.\n\nThese two bits tell lighttpd to handle all the static content itself,\nand then forward everything else off to the /fcgi path, which is defined\nas follows:\n\nFairly obvious - everything under /fcgi is handled by the FastCGI\nservers. Note however that this will make Catalyst think it is based at\nhttp://mysite.com/fcgi/ which it isn't, so we need to fix it:\n\nThat does the job - Catalyst now thinks its rooted at /, and lighttpd is\nnow handling all the static content itself.\n\nFor the completeness-sake, I've included the full config as a single\nblock below.\n\n-- \n [1] http://www.1and1.co.uk/?k_id=10200518\n [2] http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#ProxyPass\n [3] http://www.lighttpd.net/documentation/fastcgi.html\n"
title: Catalyst with Lighttpd
type: markdown
uri: http://perlitist.com/articles/catalyst-with-lighttpd
xhtml: "<p>I spent most of last week preparing a new server to deploy a project onto a nice shiny new <a href=\"http://www.1and1.co.uk/?k_id=10200518\">1&amp;1 Dedicated Server</a> (oh and if you buy something from that link I get a referral bonus - yay!) All the boring stuff like bootstrapping a fresh Debian install onto the disks from a rescue image; fighting the bootloader to make it work with no indication of errors when I make a mistake since I have no physical access to the machine - you know: the ususal.</p><p>So once I&apos;d finished those mundane tasks I had to setup the webserver. Previously I&apos;d have gone straight for Apache 2. However I&apos;m deploying a Catalyst application to the machine, and although Catalyst will run under mod_perl, the recommended method is to use FastCGI since it turns out to be a lot less hassle in the long run.</p><h4>Aims with FastCGI</h4><p>What I want from my FastCGI deployment:</p><ul><li>to have two seperate FastCGI managers running, so that whenever I need to upgrade the code, I can shut one down, bring it back up with the new code, then do the same for the other - thus giving me the ability to upgrade the code with no downtime (assuming of course that there are no DB changes that might require downtime etc. etc.)</li><li>to have the static content served via the webserver, since this is what they do well</li><li>to not have fastcgi show up anywhere in the URL.</li></ul><h4>Apache...?</h4><p>Doing this with Apache+mod_fastcgi seems impossible though, since Apache&apos;s handling of FastCGI isn&apos;t briliant. To do this in Apache you basically have to create two vhosts (and optionally give them ServerName&apos;s that dont resolve externally) and then <code>Alias / /path/to/fastCGI/N.socket</code>. </p><p>Still with me? &apos;cos we&apos;re not done yet. In the main vhost for the server (i.e. www.myapp.com) you then have to create a balanced proxy like the following:</p><pre><code>ProxyPass / balancer://myapp-cluster\n&lt;Proxy balancer://myapp-cluster>\n  BalanceMember http://myapp-1.internal\n  BalanceMember http://myapp-2.internal\n  Allow from all\n  Order Allow,Deny\n&lt;/Proxy>\n</code></pre><p>Complex, no? And whats worse, is that it doesn&apos;t even cope with one of the backend FastCGI servers being down - you just get a 500 page served to the user. Bad Apache! Try the other (FastCGI) server please! </p><h4>The Solution - Lighttpd</h4><p>After a bit of Googling, it seems like Apache just wont cope with this situation. I&apos;ve been hearing good things about Lighttpd, particularly that its <a href=\"http://www.lighttpd.net/documentation/fastcgi.html\">FastCGI</a> support is native and much better.</p><p>The interesting bits of lighttpd config I&apos;ve used:</p><pre><code><span class=\"Normal\">server.moudles += (</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Operator\">&quot;</span><span class=\"String\">mod_alias</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Operator\">&quot;</span><span class=\"String\">mod_rewrite</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Operator\">&quot;</span><span class=\"String\">mod_redirect</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Operator\">&quot;</span><span class=\"String\">mod_setenv</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">)</span><span class=\"Normal\">\n</span></code></pre><p>Pretty self explanatory - load some of the modules we need. The rest of the config goes inside the <code>$HTTP[&quot;host&quot;] =~ &quot;www.mysite.com&quot;</code> directive.</p><pre><code><span class=\"Normal\">    </span><span class=\"Comment\"># Let lighttpd take care of serving that static content</span><span class=\"Comment\">\n</span><span class=\"Normal\">    alias.url = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/js/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">   =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/js/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/css/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">  =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/css/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/tour/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/tour/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Comment\"># rewrite-once will stop processing after the first match</span><span class=\"Comment\">\n</span><span class=\"Normal\">    url.rewrite</span><span class=\"Operator\">-o</span><span class=\"Normal\">nce = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/((?:js|css|tour)/.*)</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/</span><span class=\"Variable\">$1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/(.*)</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/fcgi/</span><span class=\"Variable\">$1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">            </span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">}</span><span class=\"Normal\">\n</span></code></pre><p>These two bits tell lighttpd to handle all the static content itself, and then forward everything else off to the /fcgi path, which is defined as follows:</p><pre><code><span class=\"Normal\">  fastcgi.server = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Operator\">&quot;</span><span class=\"String\">/fcgi</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">127.0.0.1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">port</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Float\">3010</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">check-local</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">disable</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">),</span><span class=\"Normal\">\n</span><span class=\"Normal\">      ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">127.0.0.1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">port</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Float\">3011</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">check-local</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">disable</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">)</span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">  )</span><span class=\"Normal\">\n</span></code></pre><p>Fairly obvious - everything under <code>/fcgi</code> is handled by the FastCGI servers. Note however that this will make Catalyst think it is based at <code>http://mysite.com/fcgi/</code> which it isn&apos;t, so we need to fix it:</p><pre><code><span class=\"Normal\">    </span><span class=\"DataType\">$HTTP</span><span class=\"Normal\">[</span><span class=\"Operator\">&quot;</span><span class=\"String\">url</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">] =~ </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> {</span><span class=\"Normal\">\n</span><span class=\"Normal\">      setenv.add</span><span class=\"Operator\">-e</span><span class=\"Normal\">nvironment = ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">SCRIPT_NAME</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> )</span><span class=\"Normal\">\n</span><span class=\"Normal\">    }</span><span class=\"Normal\">\n</span></code></pre><p>That does the job - Catalyst now thinks its rooted at <code>/</code>, and lighttpd is now handling all the static content itself.</p><p>For the completeness-sake, I&apos;ve included the full config as a single block below.</p><pre><code><span class=\"DataType\">$HTTP</span><span class=\"Normal\">[</span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">] =~ </span><span class=\"Operator\">&quot;</span><span class=\"String\">^mysite.com</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> {</span><span class=\"Normal\">\n</span><span class=\"Normal\">    url.redirect = ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/(.*)</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">http://www.mysite.com/</span><span class=\"Variable\">$1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> )</span><span class=\"Normal\">\n</span><span class=\"Normal\">}</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"DataType\">$HTTP</span><span class=\"Normal\">[</span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">] =~ </span><span class=\"Operator\">&quot;</span><span class=\"String\">www.mysite.com</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> {</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Comment\"># dir listings are bad</span><span class=\"Comment\">\n</span><span class=\"Normal\">    server.dir</span><span class=\"Operator\">-l</span><span class=\"Normal\">isting = </span><span class=\"Operator\">&quot;</span><span class=\"String\">disable</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    server.errorlog    = </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/log/lighttpd/mysite.com.error.log</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">\n</span><span class=\"Normal\">    accesslog.filename = </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/log/lighttpd/mysite.com.access.log</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Comment\"># Let lighttpd take care of serving that static content</span><span class=\"Comment\">\n</span><span class=\"Normal\">    alias.url = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/js/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">   =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/js/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/css/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">  =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/css/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/tour/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/var/www/mysite.com/MySite/root/tour/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Comment\"># rewrite-once will stop processing after the first match</span><span class=\"Comment\">\n</span><span class=\"Normal\">    url.rewrite</span><span class=\"Operator\">-o</span><span class=\"Normal\">nce = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/((?:js|css|tour)/.*)</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/</span><span class=\"Variable\">$1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/favicon.ico</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">,</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/(.*)</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/fcgi/</span><span class=\"Variable\">$1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">            </span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    fastcgi.server = (</span><span class=\"Normal\">\n</span><span class=\"Normal\">      </span><span class=\"Operator\">&quot;</span><span class=\"String\">/fcgi</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; (</span><span class=\"Normal\">\n</span><span class=\"Normal\">        ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">127.0.0.1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">port</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Float\">3010</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">check-local</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">disable</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">),</span><span class=\"Normal\">\n</span><span class=\"Normal\">        ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">host</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">127.0.0.1</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">port</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Float\">3011</span><span class=\"Normal\">, </span><span class=\"Operator\">&quot;</span><span class=\"String\">check-local</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">disable</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">)</span><span class=\"Normal\">\n</span><span class=\"Normal\">      )</span><span class=\"Normal\">\n</span><span class=\"Normal\">    )</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"DataType\">$HTTP</span><span class=\"Normal\">[</span><span class=\"Operator\">&quot;</span><span class=\"String\">url</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">] =~ </span><span class=\"Operator\">&quot;</span><span class=\"String\">^/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> {</span><span class=\"Normal\">\n</span><span class=\"Normal\">      setenv.add</span><span class=\"Operator\">-e</span><span class=\"Normal\">nvironment = ( </span><span class=\"Operator\">&quot;</span><span class=\"String\">SCRIPT_NAME</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> =&gt; </span><span class=\"Operator\">&quot;</span><span class=\"String\">/</span><span class=\"Operator\">&quot;</span><span class=\"Normal\"> )</span><span class=\"Normal\">\n</span><span class=\"Normal\">    }</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">}</span><span class=\"Normal\">\n</span></code></pre>"
--- 
author: 
  email: ash@firemirror.com
  keyid: bfc7465ebdca5337
  name: Ash Berlin
categories: []

date: 2007-09-05T12:49:07Z
guid: 5B4C0FBC-5B99-11DC-94D7-AB27370D5E4E
modified: 2007-09-05T12:49:07Z
raw: "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nLast week at YAPC::EU I saw a few interesting talks, including Stevan's [Moose](http://www.iinteractive.com/moose/yapc_eu_2007_slides/start.html) introduction. I found this talk really helpful, maybe in part because I had read through Moose's documentation and cookbook examples once a month or so ago.\n\nSo I wanted to learn Moose a bit better, and I'm a firm believer of learning new technologies by actually writing something using them, so I needed a project - not to complex, but also not trivial. And I had just the thing - something I made a start on in June, but sadly only ever existed on my laptop that got stolen. I present the following code snippet for consideration taken from a test suite at work:\n\n    lang:perl\n    my $mech = WWW::Mechanize->new;\n\n    ok( $mech->get(\"$base/index\") );\n    ok( $mech->content =~ m{<div id=\"header\">Welcome To My Site</div>} );\n\nWhat's wrong with it? Well for a start, it should be using Test::WWW::Mechanize which fixes a few problems. But its still parsing XHTML (you *do* write XHTML web sites don't you.) using a regexp, which is always a bad idea. What happens if you change the ID of the element, or add a class to it? It'll stop working and your tests will break. My solution? [WWW::Mechanize::TreeBuilder](http://search.cpan.org/dist/WWW-Mechanize-TreeBuilder/lib/WWW/Mechanize/TreeBuilder.pm):\n\n\n    lang:perl\n    my $mech = Test::WWW::Mechanize->new;\n    WWW::Mechanize::TreeBuilder->meta->apply($mech);\n\n    $mech->get_ok(\"$base/index\");\n    is( $mech->look_down(_tag => 'div', id => 'header')->as_trimmed_text, 'Welcome To My Site');\n\nMuch better.\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.7 (Darwin)\n\niD8DBQFG3qdSv8dGXr3KUzcRAkvnAJ9rXeqgm0GJy8f0hi3M373REu6X4QCfcBnv\njAS13SadFxbyLKwGY8tf8hQ=\n=cbld\n-----END PGP SIGNATURE-----\n"
signed: 1
summary: " Last week at YAPC::EU I saw a few interesting …"
tags: 
  - 
    perl: 0
  - 
    testing: 0
  - 
    cpan: 0
  - 
    moose: 0
text: "\nLast week at YAPC::EU I saw a few interesting talks, including Stevan's\nMoose [1] introduction. I found this talk really helpful, maybe in part\nbecause I had read through Moose's documentation and cookbook examples\nonce a month or so ago.\n\nSo I wanted to learn Moose a bit better, and I'm a firm believer of\nlearning new technologies by actually writing something using them, so I\nneeded a project - not to complex, but also not trivial. And I had just\nthe thing - something I made a start on in June, but sadly only ever ex-\nisted on my laptop that got stolen. I present the following code snippet\nfor consideration taken from a test suite at work:\n\nWhat's wrong with it? Well for a start, it should be using\nTest::WWW::Mechanize which fixes a few problems. But its still parsing\nXHTML (you do write XHTML web sites don't you.) using a regexp, which is\nalways a bad idea. What happens if you change the ID of the element, or\nadd a class to it? It'll stop working and your tests will break. My so-\nlution? WWW::Mechanize::TreeBuilder [2]:\n\nMuch better.\n\n-- \n [1] http://www.iinteractive.com/moose/yapc_eu_2007_slides/start.html\n [2] http://search.cpan.org/dist/WWW-Mechanize-\n     TreeBuilder/lib/WWW/Mechanize/TreeBuilder.pm\n"
title: WWW::Mechanize::TreeBuilder
type: markdown
uri: http://perlitist.com/articles/www-mechanize-treebuilder
xhtml: "<p>Last week at YAPC::EU I saw a few interesting talks, including Stevan&apos;s <a href=\"http://www.iinteractive.com/moose/yapc_eu_2007_slides/start.html\">Moose</a> introduction. I found this talk really helpful, maybe in part because I had read through Moose&apos;s documentation and cookbook examples once a month or so ago.</p><p>So I wanted to learn Moose a bit better, and I&apos;m a firm believer of learning new technologies by actually writing something using them, so I needed a project - not to complex, but also not trivial. And I had just the thing - something I made a start on in June, but sadly only ever existed on my laptop that got stolen. I present the following code snippet for consideration taken from a test suite at work:</p><pre><code><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$mech</span><span class=\"Normal\"> = </span><span class=\"Function\">WWW::Mechanize</span><span class=\"Normal\">-&gt;new;</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"Normal\">ok( </span><span class=\"DataType\">$mech</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">get</span><span class=\"Normal\">(</span><span class=\"Operator\">&quot;</span><span class=\"DataType\">$base</span><span class=\"String\">/index</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">) );</span><span class=\"Normal\">\n</span><span class=\"Normal\">ok( </span><span class=\"DataType\">$mech</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">content</span><span class=\"Normal\"> =~ </span><span class=\"Operator\">m{</span><span class=\"Others\">&lt;div id=&quot;header&quot;&gt;Welcome To My Site&lt;/div&gt;</span><span class=\"Operator\">}</span><span class=\"Normal\"> );</span><span class=\"Normal\">\n</span></code></pre><p>What&apos;s wrong with it? Well for a start, it should be using Test::WWW::Mechanize which fixes a few problems. But its still parsing XHTML (you do write XHTML web sites don&apos;t you.) using a regexp, which is always a bad idea. What happens if you change the ID of the element, or add a class to it? It&apos;ll stop working and your tests will break. My solution? <a href=\"http://search.cpan.org/dist/WWW-Mechanize-TreeBuilder/lib/WWW/Mechanize/TreeBuilder.pm\">WWW::Mechanize::TreeBuilder</a>:</p><pre><code><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$mech</span><span class=\"Normal\"> = </span><span class=\"Function\">Test::WWW</span><span class=\"Normal\">::</span><span class=\"Function\">Mechanize</span><span class=\"Normal\">-&gt;new;</span><span class=\"Normal\">\n</span><span class=\"Function\">WWW::Mechanize</span><span class=\"Normal\">::</span><span class=\"Function\">TreeBuilder</span><span class=\"Normal\">-&gt;meta-&gt;apply(</span><span class=\"DataType\">$mech</span><span class=\"Normal\">);</span><span class=\"Normal\">\n</span><span class=\"Normal\">\n</span><span class=\"DataType\">$mech</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">get_ok</span><span class=\"Normal\">(</span><span class=\"Operator\">&quot;</span><span class=\"DataType\">$base</span><span class=\"String\">/index</span><span class=\"Operator\">&quot;</span><span class=\"Normal\">);</span><span class=\"Normal\">\n</span><span class=\"Normal\">is( </span><span class=\"DataType\">$mech</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">look_down</span><span class=\"Normal\">(_tag =&gt; </span><span class=\"Operator\">&apos;</span><span class=\"String\">div</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">, id =&gt; </span><span class=\"Operator\">&apos;</span><span class=\"String\">header</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">)</span><span class=\"Operator\">-</span><span class=\"Normal\">&gt;as_trimmed_text, </span><span class=\"Operator\">&apos;</span><span class=\"String\">Welcome To My Site</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">);</span><span class=\"Normal\">\n</span></code></pre><p>Much better.</p>"
--- 
author: 
  email: ash@firemirror.com
  keyid: bfc7465ebdca5337
  name: Ash Berlin
categories: []

date: 2007-07-30T10:08:34Z
guid: 0B9DEC2E-3E84-11DC-866F-CDAFE7958AD2
modified: 2007-07-30T10:08:34Z
raw: "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\nPlease direct all questions about Fotango to Gina Jones, European Corporate Public Relations Manager at Canon Europe (Ph +44 (0) 208 588 8000).\n\nThat is all.\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.7 (Darwin)\n\niD8DBQFGrbiPv8dGXr3KUzcRAmzCAJ4ulnJpuQo8sA9tlV12Dod3T2+M9wCfSuMO\nRjlG4Z1bpZ8xbl0vCVi3KQ0=\n=8U1W\n-----END PGP SIGNATURE-----\n"
signed: 1
summary: "Please direct all questions about Fotango to Gina Jones, European …"
tags: 
  - 
    fotango: 0
  - 
    canon: 0
text: "Please direct all questions about Fotango to Gina Jones, European Corpo-\nrate Public Relations Manager at Canon Europe (Ph +44 (0) 208 588 8000).\n\nThat is all.\n"
title: Fotango
type: text
uri: http://perlitist.com/articles/fotango
xhtml: <p>Please direct all questions about Fotango to Gina Jones, European Corporate Public Relations Manager at Canon Europe (Ph +44 (0) 208 588 8000).</p> <p>That is all.</p>
--- 
author: 
  email: ash@firemirror.com
  keyid: bfc7465ebdca5337
  name: Ash Berlin
categories: []

date: 2007-07-26T10:21:22Z
guid: B532CCCE-3B5E-11DC-951E-B900E57C4965
modified: 2007-07-26T10:21:22Z
raw: "-----BEGIN PGP SIGNED MESSAGE-----\nHash: SHA1\n\n=pod\n\nSo in a bit of down time today between projects, a colleague was working on\nmodifying his blog to syndicate photos from Vox, instead of using flickr as he\ncurrently does.\n\nBelow is the perl code he used to extract the photos and associated meta-data\nfrom the Atom feed the Vox publish. It uses the best (i.e. fully featured and\ncompliant) perl XML parser available - XML::LibXML. Take a look at the\nfollowing:\n\n lang:Perl\n my $parser = XML::LibXML->new();\n\n my $xpc = XML::LibXML::XPathContext->new;\n $xpc->registerNs('atom', 'http://www.w3.org/2005/Atom');\n\n my $library = $parser->parse_file( $library_file )->documentElement();\n my $entries = $xpc->find('/atom:feed/atom:entry',$library);\n\n for my $entry ( $entries->get_nodelist ) {\n   my $data = { \n     map { \n      $_ => $xpc->findvalue('atom:'.$_, $entry)\n     } qw( id title content published )\n   };\n\n   my $link = $xpc->findvalue('atom:link[ @rel = \"alternate\" ]/@href', $entry);\n  \n   # Do stuff with the photo now...\n }\n\nThe code is a bit... verbose. Or rather it seems like it should be possible to\nmake it cleaner. But its not really - this is just how you have to process\nthat XML to get the required data out. (Just to be clear, this is in no part a\ndig at Vox's atom layout.)\n\nIn glancing over his shoulder and wincing, we both agreed that it is in\nsituations like this that E4X really comes into its own. Don't believe me?\nWell then consider the following JavaScript code which does the same as the\nabove perl fragment.\n\n lang:JavaScript\n default xml namespace = 'http://www.w3.org/2005/Atom';\n var entries = new XML(library_file)..entry;\n \n for each (let entry in entries.*) {\n   var data = { };\n   for each (let key in ['id', 'title', 'content', 'published'] )\n     data[key] = entry[key];\n \n   link = entry.link.(@rel=\"alternate\").@href;\n \n   // Do stuff with link and data\n }\n\nMuch cleaner and easier to see what's going on isn't it? Not only that but its\nabout half as many lines. If that was all that needed doing, then JavaScript\nwould have been perfect for the job. Sadly, this was not the case - the next\nstep alluded to by the C<Do stuff with link and data> comment involves\ndownloading the image and creating a thumbnail of it. Not possible with\nserver-side JavaScript. Yet.\n\nAs I mentioned in a post about\nL<mod_js|http://blog.fotango.com/blog/2007/07/09/re-inventing-the-wheel>\ncreating a JavaScript target for SWIG seemed like a good idea. It still does.\nWe looked at L<Helma|http://www.helma.at> - a Rhino/Java based server-side\nJavaScript platform. It looks good, it really does.\n\nHowever to me, I would be slightly loathe to use it for three reasons:\n\n=over\n\n=item *\n\nIt's Java, and running Tomcat or some other JVM is a bit memory hungry for\nmy co-lo box.\n\n=item *\n\nRhino isn't quite up-to-date with features that I like using from\nJavaScript 1.7, such as the following:\n\n   [a,b] = [1,2]\n\nWhile that example is slightly contrived, not having destructive assignment is\na bit annoying.\n\n=item *\n\nIt's a Framework, not just a platform. This means that if you want to do\nsomething that the framework is L<not designed\nfor|http://trimpath.com/blog/?p=56>, it's either very hard or actually\nimpossible. I've heard that Ruby on Rails also suffers from this problem to\nsome extent. As Tom points out, this is my perlitism coming out again.\n\n=back\n\nBack to the point of SWIG, Helma should be able to use SWIG since you can\ngenerate wrappers for Java already. Saying that, the need to use SWIG with it\nis reduced since you can (I assume) use native Java.\n\nBut B<I> would still like the ability to use SWIG from Spidermonkey, my JS\nEngine of choice. Watch this space - I'll be working on it.\n\n-----BEGIN PGP SIGNATURE-----\nVersion: GnuPG v1.4.7 (Darwin)\n\niD8DBQFGqHQBv8dGXr3KUzcRAp9xAJ92riXdvM4ZOqgiOUkyOaGPVCUM2gCdGXBn\nTrjF8qgdc8gB4FRJMTkceHY=\n=EopZ\n-----END PGP SIGNATURE-----\n"
signed: 1
summary: " So in a bit of down time today between …"
tags: 
  - 
    helma: 0
  - 
    swig: 0
  - 
    javascript: 0
text: "    So in a bit of down time today between projects, a colleague was\n    working on modifying his blog to syndicate photos from Vox, instead\n    of using flickr as he currently does.\n\n    Below is the perl code he used to extract the photos and associated\n    meta-data from the Atom feed the Vox publish. It uses the best (i.e.\n    fully featured and compliant) perl XML parser available -\n    XML::LibXML. Take a look at the following:\n\n     lang:Perl my $parser = XML::LibXML->new();\n\n     my $xpc = XML::LibXML::XPathContext->new; $xpc->registerNs('atom',\n     'http://www.w3.org/2005/Atom');\n\n     my $library = $parser->parse_file( $library_file )->documentElemen-\n     t(); my $entries = $xpc->find('/atom:feed/atom:entry',$library);\n\n     for my $entry ( $entries->get_nodelist ) { my $data = { map { $_ =>\n     $xpc->findvalue('atom:'.$_, $entry) } qw( id title content pub-\n     lished ) };\n\n       my $link = $xpc->findvalue('atom:link[ @rel = \"alternate\" ]/@hre-\n       f', $entry);\n\n       # Do stuff with the photo now...\n     }\n\n    The code is a bit... verbose. Or rather it seems like it should be\n    possible to make it cleaner. But its not really - this is just how\n    you have to process that XML to get the required data out. (Just to\n    be clear, this is in no part a dig at Vox's atom layout.)\n\n    In glancing over his shoulder and wincing, we both agreed that it is\n    in situations like this that E4X really comes into its own. Don't\n    believe me? Well then consider the following JavaScript code which\n    does the same as the above perl fragment.\n\n     lang:JavaScript default xml namespace = 'http://www.w3.org/2005/A-\n     tom'; var entries = new XML(library_file)..entry;\n\n     for each (let entry in entries.*) { var data = { }; for each\n     (let key in ['id', 'title', 'content', 'published'] ) data[key]\n     = entry[key];\n\n       link = entry.link.(@rel=\"alternate\").@href;\n\n       // Do stuff with link and data }\n\n    Much cleaner and easier to see what's going on isn't it? Not only\n    that but its about half as many lines. If that was all that needed\n    doing, then JavaScript would have been perfect for the job. Sadly,\n    this was not the case - the next step alluded to by the Do stuff\n    with link and data comment involves downloading the image and creat-\n    ing a thumbnail of\n    it. Not possible with server-side JavaScript. Yet.\n\n    As I mentioned in a post about mod_js creating a JavaScript target\n    for SWIG seemed like a good idea. It still does. We looked at Helma\n    - a Rhino/Java based server-side JavaScript platform. It looks good,\n    it really does.\n\n    However to me, I would be slightly loathe to use it for three rea-\n    sons:\n\n      * It's Java, and running Tomcat or some other JVM is a bit memory\n        hungry for my co-lo box.\n\n      * Rhino isn't quite up-to-date with features that I like using\n        from JavaScript 1.7, such as the following:\n\n         [a,b] = [1,2]\n\n      While that example is slightly contrived, not having destructive\n      assignment is a bit annoying.\n\n      * It's a Framework, not just a platform. This means that if you\n        want to do something that the framework is not designed for,\n        it's either very hard or actually impossible. I've heard that\n        Ruby on Rails also suffers from this problem to some extent. As\n        Tom points out, this is my perlitism coming out again.\n\n    Back to the point of SWIG, Helma should be able to use SWIG since\n    you can generate wrappers for Java already. Saying that, the need\n    to use SWIG with it is reduced since you can (I assume) use na-\n    tive Java.\n\n    But I would still like the ability to use SWIG from Spidermonkey, my\n    JS Engine of choice. Watch this space - I'll be working on it.\n"
title: Server Side JavaScript
type: pod
uri: http://perlitist.com/articles/server_side_javascript
xhtml: "<div class=\"pod\">\n<p>So in a bit of down time today between projects, a colleague was working on\nmodifying his blog to syndicate photos from Vox, instead of using flickr as he\ncurrently does.</p>\n<p>Below is the perl code he used to extract the photos and associated meta-data\nfrom the Atom feed the Vox publish. It uses the best (i.e. fully featured and\ncompliant) perl XML parser available - XML::LibXML. Take a look at the\nfollowing:</p>\n<pre><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$parser</span><span class=\"Normal\"> = </span><span class=\"Function\">XML::LibXML</span><span class=\"Normal\">-&gt;new();</span>\n\n<span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$xpc</span><span class=\"Normal\"> = </span><span class=\"Function\">XML::LibXML</span><span class=\"Normal\">::</span><span class=\"Function\">XPathContext</span><span class=\"Normal\">-&gt;new;</span><span class=\"Normal\">\n</span><span class=\"DataType\">$xpc</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">registerNs</span><span class=\"Normal\">(</span><span class=\"Operator\">&apos;</span><span class=\"String\">atom</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">, </span><span class=\"Operator\">&apos;</span><span class=\"String\">http://www.w3.org/2005/Atom</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">);</span>\n\n<span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$library</span><span class=\"Normal\"> = </span><span class=\"DataType\">$parser</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">parse_file</span><span class=\"Normal\">( </span><span class=\"DataType\">$library_file</span><span class=\"Normal\"> )</span><span class=\"Operator\">-</span><span class=\"Normal\">&gt;documentElement();</span><span class=\"Normal\">\n</span><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$entries</span><span class=\"Normal\"> = </span><span class=\"DataType\">$xpc</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">find</span><span class=\"Normal\">(</span><span class=\"Operator\">&apos;</span><span class=\"String\">/atom:feed/atom:entry</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">,</span><span class=\"DataType\">$library</span><span class=\"Normal\">);</span>\n\n<span class=\"Keyword\">for</span><span class=\"Normal\"> </span><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$entry</span><span class=\"Normal\"> ( </span><span class=\"DataType\">$entries</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">get_nodelist</span><span class=\"Normal\"> ) {</span><span class=\"Normal\">\n</span><span class=\"Normal\">  </span><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$data</span><span class=\"Normal\"> = { </span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"Function\">map</span><span class=\"Normal\"> { </span><span class=\"Normal\">\n</span><span class=\"Normal\">     </span><span class=\"Variable\">$_</span><span class=\"Normal\"> =&gt; </span><span class=\"DataType\">$xpc</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">findvalue</span><span class=\"Normal\">(</span><span class=\"Operator\">&apos;</span><span class=\"String\">atom:</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">.</span><span class=\"Variable\">$_</span><span class=\"Normal\">, </span><span class=\"DataType\">$entry</span><span class=\"Normal\">)</span><span class=\"Normal\">\n</span><span class=\"Normal\">    } </span><span class=\"Operator\">qw(</span><span class=\"Normal\"> id title content published </span><span class=\"Operator\">)</span><span class=\"Normal\">\n</span><span class=\"Normal\">  };</span>\n\n<span class=\"Normal\">  </span><span class=\"Keyword\">my</span><span class=\"Normal\"> </span><span class=\"DataType\">$link</span><span class=\"Normal\"> = </span><span class=\"DataType\">$xpc</span><span class=\"Normal\">-&gt;</span><span class=\"DataType\">findvalue</span><span class=\"Normal\">(</span><span class=\"Operator\">&apos;</span><span class=\"String\">atom:link[ @rel = &quot;alternate&quot; ]/@href</span><span class=\"Operator\">&apos;</span><span class=\"Normal\">, </span><span class=\"DataType\">$entry</span><span class=\"Normal\">);</span><span class=\"Normal\">\n</span><span class=\"Normal\">  </span>\n\n<span class=\"Normal\">  </span><span class=\"Comment\"># Do stuff with the photo now...</span><span class=\"Comment\">\n</span><span class=\"Normal\">}</span>\n</pre>\n<p>The code is a bit... verbose. Or rather it seems like it should be possible to\nmake it cleaner. But its not really - this is just how you have to process\nthat XML to get the required data out. (Just to be clear, this is in no part a\ndig at Vox's atom layout.)</p>\n<p>In glancing over his shoulder and wincing, we both agreed that it is in\nsituations like this that E4X really comes into its own. Don't believe me?\nWell then consider the following JavaScript code which does the same as the\nabove perl fragment.</p>\n<pre><span class=\"Keyword\">default</span><span class=\"Normal\"> xml namespace = </span><span class=\"String\">&apos;</span><span class=\"Char\">http://www.w3.org/2005/Atom&apos;</span><span class=\"Normal\">;</span><span class=\"Normal\">\n</span><span class=\"Keyword\">var</span><span class=\"Normal\"> entries = </span><span class=\"Keyword\">new</span><span class=\"Normal\"> XML(library_file)..entry;</span><span class=\"Normal\">\n</span><span class=\"Normal\"> </span>\n\n<span class=\"Keyword\">for</span><span class=\"Normal\"> each (let entry </span><span class=\"Keyword\">in</span><span class=\"Normal\"> entries.*) {</span><span class=\"Normal\">\n</span><span class=\"Normal\">  </span><span class=\"Keyword\">var</span><span class=\"Normal\"> </span><span class=\"DataType\">data</span><span class=\"Normal\"> = { };</span><span class=\"Normal\">\n</span><span class=\"Normal\">  </span><span class=\"Keyword\">for</span><span class=\"Normal\"> each (let key </span><span class=\"Keyword\">in</span><span class=\"Normal\"> [</span><span class=\"String\">&apos;</span><span class=\"Char\">id&apos;</span><span class=\"Normal\">, </span><span class=\"String\">&apos;</span><span class=\"Char\">title&apos;</span><span class=\"Normal\">, </span><span class=\"String\">&apos;</span><span class=\"Char\">content&apos;</span><span class=\"Normal\">, </span><span class=\"String\">&apos;</span><span class=\"Char\">published&apos;</span><span class=\"Normal\">] )</span><span class=\"Normal\">\n</span><span class=\"Normal\">    </span><span class=\"DataType\">data</span><span class=\"Normal\">[key] = entry[key];</span><span class=\"Normal\">\n</span><span class=\"Normal\"> </span>\n\n<span class=\"Normal\">  </span><span class=\"Reserved\">link</span><span class=\"Normal\"> = entry.</span><span class=\"Reserved\">link</span><span class=\"Normal\">.(@rel=</span><span class=\"String\">&quot;alternate&quot;</span><span class=\"Normal\">).@href;</span><span class=\"Normal\">\n</span><span class=\"Normal\"> </span>\n\n<span class=\"Normal\">  </span><span class=\"Comment\">// Do stuff with link and data</span><span class=\"Comment\">\n</span><span class=\"Normal\">}</span>\n</pre>\n<p>Much cleaner and easier to see what's going on isn't it? Not only that but its\nabout half as many lines. If that was all that needed doing, then JavaScript\nwould have been perfect for the job. Sadly, this was not the case - the next\nstep alluded to by the <code>Do stuff with link and data</code> comment involves\ndownloading the image and creating a thumbnail of it. Not possible with\nserver-side JavaScript. Yet.</p>\n<p>As I mentioned in a post about\n<a href=\"http://blog.fotango.com/blog/2007/07/09/re-inventing-the-wheel\">mod_js</a>\ncreating a JavaScript target for SWIG seemed like a good idea. It still does.\nWe looked at <a href=\"http://www.helma.at\">Helma</a> - a Rhino/Java based server-side\nJavaScript platform. It looks good, it really does.</p>\n<p>However to me, I would be slightly loathe to use it for three reasons:</p>\n<ul>\n\t\t<li>It's Java, and running Tomcat or some other JVM is a bit memory hungry for\nmy co-lo box.\t</li>\n\t\t<li>Rhino isn't quite up-to-date with features that I like using from\nJavaScript 1.7, such as the following:\n<br /><br /><pre><span class=\"Normal\">[a,b] = [</span><span class=\"Float\">1</span><span class=\"Normal\">,</span><span class=\"Float\">2</span><span class=\"Normal\">]</span>\n</pre>\n<br /><br />While that example is slightly contrived, not having destructive assignment is\na bit annoying.\t</li>\n\t\t<li>It's a Framework, not just a platform. This means that if you want to do\nsomething that the framework is <a href=\"http://trimpath.com/blog/?p=56\">not designed for</a>, it's either very hard or actually\nimpossible. I've heard that Ruby on Rails also suffers from this problem to\nsome extent. As Tom points out, this is my perlitism coming out again.</li>\n</ul>\n\n<p>Back to the point of SWIG, Helma should be able to use SWIG since you can\ngenerate wrappers for Java already. Saying that, the need to use SWIG with it\nis reduced since you can (I assume) use native Java.</p>\n<p>But <strong>I</strong> would still like the ability to use SWIG from Spidermonkey, my JS\nEngine of choice. Watch this space - I'll be working on it.\n</p>\n\n\n</div>"
