Tuesday, January 28, 2014

Class factories in Coffeescript

There’s a neat trick for dynamically constructing heterogeneous classes using a single factory function in CoffeeScript.
(This is probably a common pattern among Coffeescript cognoscenti, but I hadn’t bumped into it, so I thought it was worth jotting down.)
I’m in the middle of writing a CoffeeScript application which handles a variety of related but different user interface widgets. I’d normally treat each as an independent class, and use mixins for the common functionality. But in this particular app, it turns out to be incredibly convenient to have a single factory method that takes a DOM element and uses a data-type attribute to generate an object of the correct class. That is, given

<article class="widget" data-type="Wibble">     … </article>
I’d want an object of class Wibble, and given
<article class="widget" data-type="Wobble">

    … </article>
I’d want a Wobble object.
The initialization code to create these objects will look something like

$(".widget").map(function (_,el) {      return Widget.for_element($(el)) })
Here’s what I came up with for the for_element factory method.

class Widget     @for_element: (el) ->         type = el.data("type")         new @[type](el)      constructor: (@el) ->  class Widget.Wibble extends Widget     constructor: (el) ->         # subclass-specific stuff         super  class Widget.Wobble extends Widget     constructor: (el) ->         # subclass-specific stuff         super
The fun part of this is that by namespacing the individual widget subclasses in the parent Widget class, I can use new @type to look up the subclass in the factory, and then instantiate the object.

Monday, January 6, 2014

I'm sick of site spam

Is this a way of fighting back?


The pragprog.com site tries to make it easy for our readers. We don’t want them to have to jump through hoops to register an account, post to forums, or note an erratum.  We don’t want to ban external links—they are useful when people want to reference some resource or gist.


And, of course, that means we attract out share of spammers, adding links to external sites and products. 


I spend a bit of time each week searching this out and deleting it. But I sometimes miss things, particularly when it is a site link in a user’s profile.


But Google notices, and it complains. Not to me, but to the owner of the site the links reference. That’s fair—the site owner paid someone to spam us, and Google complains to them, threatening to put their page rank in the crapper unless they remove the spam link.


But they can’t remove it, because it was added by some kid in link factory somewhere.


So instead they write to us. Here’s a typical email. 


from: Mr Woc <webmaster@worldofchat.co.uk>


Hi,


I work for the company touchlineban.co.uk.


Your web page:


http://forums.pragprog.com/users/73905


is linking to our domain and we have been given an email from Google regarding our linking habits!


Since this letter from Google our site is suffering very badly, I need to get this link removed.


Therefore I politely request that you remove the link to our site touchlineban.co.uk immediately or as soon as is possible.


Many thanks for your cooperation in advance.


If you have any questions please contact me here:


webmaster@touchlineban.co.uk


Also if you have any other domain linking to us please can these links be removed too?


Kind regards


I get these emails quite frequently.


So, this time I responded:


I will remove the link if you give me the name of the company you employed to add it in the first place.


I got a wonderful response:


from: Woccy <webmaster@touchlineban.co.uk>


It was a long long time ago i have no idea sorry, ive got thousands of links and hired 100s of people over the years.


Far easier for you to remove them otherwise i just have to put the url on a disavow file, which is never good for any site, as I have to get rid of the links one way or another


Ive replied from the touchlineban email too so you know its my site.


Many thanks


Jc


Oh, my heart bleeds. The poor fellow. He’s hired 100s of people to spam sites like ours, and has polluted the web with thousands of links to his football management site. He can’t be expected to remember any details.


So, here’s my thinking. What would happen if I create a page on our site where I collect every single spam link I find, and leave those links active forever?


Would this cause some pain to the folks who spammed us in the first place?


And would it hurt our own page rank? Is there a way to let Google know what we’re doing?

Saturday, January 4, 2014

Reactive systems have no top

Back when I used to consult into projects in trouble, there was a trick that always worked, Look for classes or modules named XxxManager. These puppies would always be at the epicenter of the structural spaghetti. Invariably they’d be doing too much, with lots of conditional code and a fair amount of poking into the business of the things they were supposed to be managing.


So we’d pick them apart, split out functionality, and see if there was a way to either eliminate them, or turn them into something less coupled (my favorite approach when appropriate would be to turn each into a state machine).


But, as they say, the cobbler’s children have no shoes. I fell into the trap myself this week.


Over the Christmas break, I’ve been amusing myself by writing a terminal emulator in Coffeescript. Part of the intent is to allow me to record and then play back interactive sessions. The playback will have a bunch of bells and whistles (including fast forward, rewind, step-by-step and so on).


image


To manage all this (yes, there’s that word) I wrote a class called Driver.


Perhaps it was the eggnog, but the usual alarm bells were muted. I happily coded away for half a day, hacking more and more stuff into the driver. We had events, callbacks, a little RxJS, and lots of asking other objects for status.


And it bogged down. Every change got more difficult. Every test harder to write. And it wasn’t fun.


So I took the dog for a walk, and the dog told me I was being stupid. I’d written a manager class. It wasn’t called PlaybackManager—that would have been a giveaway. I’d called it Driver. That kind of pathetically meaningless name should also have been a giveaway, but until the dog pointed it out, I’d kinda spaced it out.


So I got back, gave the dog a treat, rolled back the code to the start of day, and looked for a good name for a class that would drive the playback. I ended up with VcrControls. What did it control? A class called Player. The Player class had methods such as play()rewind(), and step(). The VcrControls object sat between the UI and the player. And the code just fell into place.


In a way, this is a variant of the “tell, don’t ask” rule. 


Reactive systems have no top—they are lots of components that transform data and events. There’s no place for anything called a manager in such a system. And careful naming (cf Driver…) is a quick way of working out when you break the rule.