{ |one, step, back| } 2 of 2 articles Syndicate: full/short

Cautiously Optimistic   23 Sep 04
[ print link all ]
I am cautiously optimistic that a minor change in UseMod wiki code that I am using for feedback may have slowed down the wiki spam bots a bit. The fix is very simple. I just require that any links on the wiki page spell the protocol portion of their link URL in upper case.

For example, if I wish to link to http://onestepback.org on a wiki page, then I must spell the link as HTTP://onestepback.org. Otherwise the updated page will be rejected.

Since the wiki spammers currently use lower case for "http", their page updates are rejected. Now this will only work until the spammer catch on and start uppercasing the HTTP. As long as the number of sites that enforce this rule is small, it should be a while before they catch on (one hopes).

Since I have implemented this patch a week ago, I have had only one instance of spamming. Yes, the spammer used an upper case HTTP. I don’t know if that particular spammer always uses upper case, or just responded intelligently to my error message. But that hasn’t been repeated. Like I say, I’m cautiosly optimistic.

You can find the patch here:

The patch was created against version 1.0 of UseMod wiki.

By posting this, I’ve (probably) increased the number of sites using this anti-spam technique and have brought the day closer to when the spammers figure it out. Oh, well. We will worry about that when it happens.



comments

Staying Simple   13 Sep 04
[ print link all ]
One of the most important lessons I have ever learned as a software developer is to keep things simple. It’s also one of the hardest lessons to remember, because as programmers, we revel in the complex. Sometimes I am forced to reconsider designs where I let my love of complexity override my good sense for simplicity.

Revisiting Builder

Here’s one small example where complexity got away from me. My last blog entry mentioned BuilderObjects used to build XML markup. It turns out that these builders are really useful and I’ve been making good use of them in my latest web project.

However, as I was using, I discovered a rather annoying feature. If you recall, builders depended on the method_missing feature of Ruby to implement arbitrary XML tags on the fly. But, in order for code like this …

   builder.p { em("Hello World") }

to work, the em message must be sent to the builder object. Normally unadorned messages are sent to self. However, the builder object evaluated its block in a special way to hijack the value of self to point to itself.

It is really cool that we just need to mention the tag name and it automatically gets generated. But there is a downside. Suppose we replace the literal "Hello World" with a method called greet that dynamically determines the proper form of greeting. Now the code looks like this…

  builder.p { em(greet) }   # greet is a method

Now, not only em, but also greet gets sent to the builder. This is wrong, greet is a method defined on the current object, not the builder. To get around this, we must save the value of self outside the block and make it available under a different name. Perhaps like this…

  s = self
  builder.p { em(s.greet) }

As I was using builder I notice I was doing the s = self step on almost everytime I used a builder. And when I forget to use the s, I would get weird bugs in my HTML output.

Clearly I was being too clever (in my defense, I just copied the Groovy design for their builders). So I fixed the builder to use normal blocks with normal evaluation and the number of accidental bugs went way down. The greet example now reads like this under the new version of builder:

  builder.p { builder.em(greet) }

Now, since is it awkward to keep mentioning the builder name over and over, it would be nice to have a shortcut. Hence builders pass themselves as a parameter to the blocks. This gives us the opportunity to use a shorter name, but only with in the block. Again, the greet example is

  builder.p { |xml|  xml.em(greet) }

(The shorter name isn’t a big advantage here, but is a big convenience when many tags are created.)

So, it gets back to that old adage: KISS — Keep It Simple Stupid!

Postscript …

Builder is availble as a gem. Version 1.0.0 has the new, simpler interface. Because Builder is a gem, you can install both versions and use either, as long as you don’t mix their usage in a single application. To use the new version (after installing), just say

  require_gem 'builder', '~> 1.0'

This allows you to use any version greater than 1.0 but less that 2.0. To use the old interface, say …

  require_gem 'builder', '~> 0.1'

This allows any version 0.1 or later, but rejects version 1.0 and up. The ~> operator is called the Pessimistic version constraint is is helpful when versions of software have incompatible interfaces. The RubyGems wiki has more information about pessimistic version constraint and about versioning policies.



comments

 

Formatted: 04-Dec-08 15:31
Feedback: jim@weirichhouse.org