Categories
Uncategorized

Spellchecking POD with TextMate

Trelane was asking on irc today about how to get TextMate to spell check POD. It doesn’t by default, which is annoying as it’s clever enough to check the spelling of strings.

The answer is fairly simple. Go into the Bundle Editor (^⌥⌘B) and open up the Perl category. Near the bottom you’ll see a “Comments” preferences item. Click on the plus box at the bottom of the screen and add another preferences item. Name it “Pod” and stick this in it:

    {    spellChecking = 1; }

In the “Scope Selector” field, type in comment.documentation.perl.

At this point, you have to restart TextMate. I’m not sure why, but you do. But afterwards, you should get lots of dotted red lines inside your pod.

Sadly, the Perl language definition inside TextMate doesn’t distinguish bits of pod much, so you’ll have to add words like “head1” to your dictionary (or fix the language definition).

Categories
Uncategorized

Constant Pain

Trelane was complaining about Image::Imlib2 the other day. Apparently, it accepts any method call without error. i.e. it’s a blackhole object.

A quick inspection of the source revealed two things:

  1. An AUTOLOAD() method, to resolve unknown method calls.
  2. A constant() function in the XS to resolve names to constant values. This was being called from AUTOLOAD().

As it turned out there was a bug in constant()—it wasn’t correctly reporting constants that didn’t exist. But, a one line patch fixed things:

  diff -ruN Image-Imlib2-1.08/lib/Image/Imlib2.xs Image-Imlib2-1.08-dom/lib/Image/Imlib2.xs
  --- Image-Imlib2-1.08/lib/Image/Imlib2.xs       2006-03-01 19:11:15.000000000 +0000
  +++ Image-Imlib2-1.08-dom/lib/Image/Imlib2.xs   2006-06-17 17:25:56.000000000 +0100
  @@ -25,6 +25,7 @@
           if (strEQ(name, "TEXT_TO_ANGLE")) return IMLIB_TEXT_TO_ANGLE;
           break;
       }
  +    errno = ENOENT;
       return 0;

   not_there:

But when questioned, the author (acme) didn’t know much about why the constant() function was there at all. And it turns out both constant() and AUTOLOAD() are created automatically by h2xs. Newer versions use ExtUtils::Constant instead of doing things directly.

However, the fact is that we’re still using AUTOLOAD() to load in a bunch of things that we already know. Kind of pointless. Thankfully, Trelane was slightly more determined that I am, and wrote a proper patch getting rid of AUTOLOAD() entirely and creating individual functions for each constant. As a result, we now have Image::Imlib2 1.09.

What’s the moral of this tale? Always question code that gets autogenerated for you. You absolutely have to understand what it’s doing for you. Don’t assume that the person who wrote the generator knew more about your problem than you do.

Categories
Uncategorized

JavaScript on OSX

So, after my little rant a few days ago, I’ve now gotten JavaScript::JSLint up and running. But that involves downloading a lot of Perl modules, and installing SpiderMonkey, which is a none too pleasant task. However, the Mac should already have JavaScript built in—JavaScriptCore, which is part of WebKit, which is used to build Safari.

So, I’ve spent an interesting couple of days learning Objective-C, Cocoa and nosing around the Apple developer documentation in order to see how to get at the JavaScriptCore. And, as far as I can see, you can’t.

The best I came up with is Using JavaScript From Objective-C. Which sounds nice and well, but from what I can make out, it’s predicated on having a window hanging around, which I want to avoid (I want a command line tool). It also doesn’t provide any interfaces to bind your own functions into the JavaScript interpreter.

Now, JavaScriptCore happens to be one of the Open Source parts of OSX. So, I can just download it, build my own wrapper, and so on. But it is annoying that I have to do so when the system comes with a perfectly good JavaScript interpreter of its own. Not only that, but it’s an alternative implementation to spidermonkey (based on KJS from KDE). And more implementations usually leads to a healthier ecosystem for a programming language.

In the meantime, anybody wanting (relatively) quick access to a lint for JavaScript on osx should probably look at javascriptlint instead. It still needs compiling, but it produces a single file which has no dependencies.

Mind you, I’m still glad at the time I’ve spent. Objective-C is rather nice (apart from the lack of garbage collection—refcounts make me nervous). And Interface Builder is the nicest GUI builder I’ve yet seen. Or at least it’s the only one that didn’t make me run away screaming.

Update: Looks like I missed JavaScript OSA. But that doesn’t look like it’s been updated in years.

Categories
Uncategorized

XML::Genx 0.21

I’ve released a new version, which fixes a blindingly obvious error: you couldn’t pass in characters between x80 and xff unless they had the UTF-8 flag turned on. I don’t know how I missed that. 😦

Categories
Uncategorized

JavaScript Gotchas

This just cost me and a colleague about an hour.

  var headers = mydiv.getElementsByTagName('h3');
  for (var i = 0; i < headers.length; i++) {
    // ...
  }

When run, this wasn’t going inside the for loop at all (in IE; firefox worked). So we stuck in an alert to see what headers.length came out as. [object] apparently.

After much chasing around the houses, we looked closer at the original HTML:

  <h3 id='length'>Some Header</h3>

It’s a miracle that this worked at all in firefox. What was happening is that the length property of the headers collection was being shadowed by the element with an id of length. That’s happening because the collection is an HTMLCollection, and the JavaScript DOM bindings specify that you can also index by id into that collection. And because functions and properties share the same namespace in JavaScript, disaster ensues.

So the lesson to take away from all this is that you should take great care to avoid using id’s that are the same as existing method or property names. Eric Meyer found the same things some time ago: Reserved ID Values.

Categories
Uncategorized

XML::Genx Plans

I was talking to Mark Fowler yesterday and XML::Genx came up. He had a couple of good points:

  • It’s not absolutely clear in the documentation that any valid Perl string will work correctly (be it UTF-8 encoded or not). I need to double check the tests for this and amend the docs.
  • The API is still fairly horrible. It mirrors the C api almost exactly, but this feels very odd as a Perl programmer. I need to have a think about what would be better. Ideally, I’d like something more like ruby’s builder. In fact, I actually wrote something similar to that before (XML::SAX::Builder), but that uses SAX, which is too slow in Perl.

I really appreciate the feedback. Apart from Aristotle, it’s the only feedback I’ve had since I released it.

If I can figure these out, I should probably slap a 1.0 on it.

I also reckon I should do a talk on “Why we need another XML writer”. There are quite a few on CPAN already and I should say why I wrote another one…

Categories
Uncategorized

New Releases

I’ve just done a couple of new releases of my modules:

  • JavaScript::JSLint 0.04, which is just renaming from Lint to JSLint to more accurately reflect where it’s come from (pointed out by Matthias Miller).
  • subatom 0.07 which switches from the baroque XML::Atom api to the much nicer XML::Atom::SimpleFeed (thanks, Aristotle).
  • subatom 0.08 because I am a doofus and left a warn statement in.
Categories
Uncategorized

JSLint Backlash

Typically enough, two days after I start on something, there’s a backlash. Dean Edwards (whom I respect highly) points out that JSLint is not a silver bullet in JSLint Considered Harmful.

(aside: everybody please read ‘Considered Harmful’ Essays Considered Harmful. Thank you)

The post he links to brings up a number of valid points about where valid uses of JavaScript can be flagged up by JSLint. This is perfectly reasonable. For example, you rarely want to use eval() in JavaScript, but when you need it, it’s the only way to do what you want. In that case, JSLint provides a flag to disable the warning.

But the real point is that you can’t just blindly follow results from a tool for what are ultimately stylistic issues like these. You have to use your knowledge as a programmer to interpret the output and agree / disagree with each point as appropriate. The purpose of JSLint is to flag areas that might be of concern, or perhaps be liable to bugs. It’s not saying “this is a bug, absolutely, for sure”.

One thing which might be useful (although I have no idea how easy it would be to implement) would be to be able to specify hints in the same manner that you could for C lint. There is already one example (declaring external definitions), but there could be more.

Whilst I am sure that it has it’s flaws, I’m extremely glad to see tools like JSLint being made available. Analysis tools like these help to move JavaScript from being “toy for websites” to “useful programming language”.

Now all I want is a JavaScript equivalent of perltidy

Categories
Uncategorized

Blog Buttons

I’ve seen links to “add this to del.icio.us” for some time now. I never use them. It’s a complete waste of time, my links toolbar is perfectly adequate.

A couple of months ago, I saw that people started adding more buttons to their blog posts. “Add to del.icio.us.” “Digg This!” “Reddit?”

Again, all a complete waste of time, and precious page space.

Unfortunately, today I have just witnessed this vile insanity:

Blog Buttons

I mean, really, what the hell are all those little things? And more to the point, who cares?

Categories
Uncategorized

JavaScript::Lint 0.02

I’ve just put together a new version of JavaScript::Lint. The main new thing is that you can now specify options to control how the lint works. You probably want to enable the undef option, for instance.

I also fixed a problem where I was covering up errors when the lint couldn’t do anything more (e.g. nested comments). After my mailing Douglas Crockford about it, he kindly pointed out that this was mentioned in the comments. I’d entirely missed it. Ah well. Anyway, it now returns a “cannot proceed” message.

Update: after spotting something rather stupid, I’ve now uploaded JavaScript::Lint 0.03 instead.