Showing posts with label regular. Show all posts
Showing posts with label regular. Show all posts

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.

Thursday, January 9, 2014

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.

Friday, December 20, 2013

Deploying Elixir

When any serious app is 100% done, there’s another 50% left to do, and that 50% is deployment. For complicated or large apps, there’s no easy way to do this.


A reader asked me about Elixir and deployment:



There is definitely a lot of excitement around Elixir and I like it. What I am concerned with is are their any production deployment issues with Elixir? I have not don’t one myself but Elixir depends a lot on Erlang and Erlang libraries which have some kind of unique release process or so I have been told. I am not sure if I understood it correctly but I believe Erlang is released in such a away that it is self reliant and doesn’t depend on any external dependencies. How would Elixir behave if the system Erlang version moves ahead?



And I responded:


Elixir is just Erlang, as far as Erlang is concerned. This means that Elixir code can be deployed alongside Erlang code—the two coexist.


However, you have to be careful when looking at Erlang deployments.  Up until now, these have tended to be large-scale, distributed, and highly redundant systems. The goal has been seriously high reliability. Now no system like this can be deployed just by pushing a button—there’s a lot of planning, and a lot of configuration and scripting.


As a result, a “classical” Erlang deploy can be a big beast. Your Elixir code can join in this fun if it wants to.


But Elixir also offers simpler options. For example, deploying an Erlixir web app to Heroku is just about as easy as deploying any app to Heroku—just push to a repository.


So the short answer is that deployment in any language is not just one topic—it varies greatly depending on the application’s characteristics. At the large scale end, Erlang (and by extension Elixir) has a great story—it is mature and proven. At the small scale, deployments such as Heroku make it easy. And in the middle—well, that’s where the interesting stuff will happen.


Friday, November 1, 2013

Pragmatic Royalties—2013 Edition

Back in 2009, I posted a summary of the breakdown of the royalties we paid on our titles. Susannah, our managing editor, has been suggesting for a while that I should update it. I was surprised by what I found.


Here are the 2009 numbers:


image



Compare with 2013:


image



Below $10k, the numbers are about the same. That’s not surprising—mostly they reflect the vanity titles that were around in 2009. But above the $10k mark, things are a little different.


In 2009, 70% of titles made more than $25k. By 2013, that number has grown to 74%.


In 2009, 41% of titles made over $50k. By 2013, it’s 46%.


And while roughly the same percentage of titles made between $75k and $100k (12% in  2009, 13% now), there’s a big increase in the $100–$200k wedge, up from 4% to 12%. The only drop at the top is the >$400k wedge, and that simply reflects that we haven’t had a title as big as the Rails and Ruby books recently, while the overall number of titles has grown.


These numbers were pleasantly surprising. I know that as a business we are insulated from the plummeting fortunes of more conventional publishers. But I hadn’t realized that were were even more attractive to authors now than back in 2009.


Maybe it’s time for you to consider writing a book

Wednesday, February 1, 2012

Smart Constants

I’ve been really enjoying James Edward Gray II’s Rubies in the Rough articles. Every couple of weeks, he publishes something that is guaranteed to get me thinking about some aspect of coding I hadn’t considered before.


His latest article is part I of an exploration of an algorithm for the Hitting Rock Bottom problem posed by  by Gregory Brown & Andrea Singh. At its core, the problem asks you to simulate pouring water into a 2D container, filling it using a simple set of rules.


As I was coding up my solution, I found I had code like


case 
when cave.cell_below == " " then cave.move_down
when cave.cell_to_the_right == " " then cave.move_right
# ...
else
cave.move_up
cave.move_left until cave.cell == "~"
# ...

Here ” “ is a cell containing air, and ”~” a watery cell. So clearly we should create some named constants for that:


AIR   = " "
WATER = "~"

case
when cave.cell_below == AIR then cave.move_down
when cave.cell_to_the_right == AIR then cave.move_right
# ...
else
cave.move_up
cave.move_left until cave.cell == WATER
# ...

But it occurred to me that we could use Ruby’s singleton methods to give AIR and WATER a little smarts:


WATER = "~"
AIR = " "
[WATER, AIR].each do |content|
def content.in?(cell)
cell == self
end
end

# ...
case
when AIR.in?(cave.cell_below) then cave.move_down
when AIR.in?(cave.cell_to_the_right) then cave.move_right
# ...
else
# ...
cave.move_left until WATER.in?(cave.cell) if AIR.in?(cave.cell)

Now you could argue that the cave object should do this: cave.watery?, or that the individual elements in the cave should be objects that know their moisture content, rather than simply characters. I don’t agree with the first (simply because the cave is the container, and the water/air is the separate stuff that goes into that container). I have a lot of sympathy for the second, and I’d probably end up there given a sufficiently large nudge during a refactoring. 


WATER = "~"
AIR = " "
[WATER, AIR].each do |content|
def content.in?(cell)
cell == self
end
end

# ...
case
when AIR.in?(cave.cell_below) then cave.move_down
when AIR.in?(cave.cell_to_the_right) then cave.move_right
# ...
else
# ...
cave.move_left until WATER.in?(cave.cell) if AIR.in?(cave.cell)

But, for the problem at hand, simply decorating the two constants with a domain method seems to result in code that is a lot more readable. It isn’t a technique I’d used before, so I thought I’d share.


(And remember to check out Rubies in the Rough…)

Saturday, November 12, 2011

Followup to my EMail experiment

So the Hacker News folks are having a discussion about my email experiment last April. Many interesting points were raised. One fair question is “how did the experiment work out?” 


In short, it worked incredibly well.


I was mostly worried about annoying the folks sending me email. But the only feedback I got was positive. 


I was also a little worried about folks abusing the [urgent] flag. But that didn’t happen, either. I had perhaps 5 or 6 urgent emails, and they were indeed things I needed to handle when I got back. Maybe I’m just lucky when it comes to the people who correspond with me.


The experiment had two positive effects on my life. First, the vacation was genuinely a lot nicer not having to worry about the sacks full of mail piling up for me when I got back. Was that selfish of me? Perhaps a little. 


I wasn’t expecting the other side effect. Since I returned from vacation, the quality of email I receive has improved, and the quantity I receive has dropped. I still enjoy interacting with all the people I need to interact with, and I still get to answer all the questions that need answering. It just seems that my inbox is somehow more focussed.


I have a theory. I think that, during the course of the preceding few years, I’d become something of a slave to my email. I’d answer stuff as it arrived. And those rapid responses would in turn trigger another round of email, and another. There was almost an adreneline rush to it.


So my vacation broke that cycle. And now things are sane (or at least closer to sane).

Thursday, April 14, 2011

So I'm trying an email experiment

For the next 2 weeks, here’s my vacation message:




Subject: I’m on vacation, and I’ve deleted your message—really


I know this sounds brutal, but here’s the deal.


I can’t remember the last time I took a vacation where I didn’t actually end up working a few hours each day handling e-mail. I felt I had to, because if I didn’t, the Inbox would just grow and grow, waiting for me when I got back—the idea that I’d be flying home to 5,000 messages would always be nagging at me, detracting from my holiday. So I worked (which also detracted from the holiday).


 This time, I’m taking a different approach. I’m asking for your help to make my break more enjoyable.


 I’m going to be discarding email I receive. That’s right—your email will be recycled into warm, fluffy bit-jackets for underprivileged children. I won’t see it.


If it’s something you think I really, really need to know, you can bypass this brutality by putting “urgent” in the subject line. But before you do:


  • if it is something that can be handled by the wonderful Pragprog support folk, could you send your message to support@pragprog.com

  • if it can wait until I get back on April 25, please resend your message then.


It’s an experiment. Bon voyage à moi!




Dave

Wednesday, April 8, 2009

Twitter Should Move Away from Ruby

Oh dear. The chattering classes are at it, talking about how the Twitter folks are dissing Ruby by announcing the replacement of some Ruby code with Scala code.


Please stop.

At the kinds of volumes that Twitter handles (and with what I assume is a somewhat scary growth curve), Twitter needs  to improve concurrency—it needs an environment/language with low memory overhead, incredible performance, and super-efficient threading. I don’t know if Scala fits that particular bill, but I know that current Ruby implementations don’t. It isn’t what Ruby’s intended to be. So the move away is just sound thinking. (I suspect it also took some courage.) I applaud Alex and the team for this.


Instead of defending Ruby when it’s clearly not an appropriate solution, let’s think about things the other way around.


The good folks at Twitter started off with Ruby because they wanted to get something running quickly, and they wanted to experiment. And Ruby gave them that. And, what’s more, Ruby saw them through at least two rounds of phenomenal  growth. Could they have done it in another language? Sure. But I suspect Ruby, despite the occasional headache, helped them get where they are now. 


And now they’ve reached the status of world-wide wunderkind, it’s time to move on. 


I for one wish them luck. I look forward to the day when our online store reaches the kind of size where we have to move away from Rails. I’ll tweet the fact with a tear in my eye, while my yacht sails me off to the sunset.

Tuesday, December 16, 2008

Ruby 1.9 can check your indentation

All Ruby programmers regularly encounter the mystical error “syntax error, unexpected $end, expecting keyword_end.” We know what it means: we left off an end somewhere in the code. As Ruby compiled our source, it keeps track of nesting, and when it reached the end of file ($end), it was expecting to see one more end keyword, and none was there.


So, we trundle back through the source, and after a while discover we’d deleted just one too many lines during that last edit.


Ruby 1.9 makes that easier. For example, here’s a source file:


class Example
  def meth1
    if Time.now.hours > 12
      puts “Afternoon”
  end
  def meth2
    # …
  end
end


Run it through Ruby 1.9, and you’ll get the same old error message:


dave[RUBY3/Book 8:26:48*] ruby t.rb   
t.rb:10: syntax error, unexpected $end, expecting keyword_end


But add the -w flag, and things get more interesting.


dave[RUBY3/Book 8:26:51*] ruby -w t.rb
t.rb:5: warning: mismatched indentations at ‘end’ with ‘if’ at 3
t.rb:9: warning: mismatched indentations at ‘end’ with ‘def’ at 2
t.rb:10: syntax error, unexpected $end, expecting keyword_end


It’s the small things in life…

Saturday, November 29, 2008

See Rails request paths in 'top'

During our sale, we had one particular request that came in and wedged the application: every time it hit, the mongrel process size zoomed steadily up to 500Mb, so we had to kill it. But finding out which request was doing this was tricky. The log files didn’t help—with the amount of traffic we were getting, it was a small needle and a large haystack.


Eventually, we found the culprit. But it would have been a lot easier if I’d thought of this hack on Friday, and not after the sale ended.

If you put this into your application controller:


before_filter :set_process_name_from_request

def set_process_name_from_request
$0 = request.path[0,16]
end

after_filter :unset_process_name_from_request

def unset_process_name_from_request
$0 = request.path[0,15] + "*"
end

then Ruby will set the cmd field in your process control block to the first 16 characters of the request path. You can then use top to see what request is being handled by each mongrel.


image

Once the request has been handled, an asterisk sign is appended, so you can see the last URL when a mongrel becomes idle. 


image



If your version of top doesn’t show the short command by default, use the c keyboard command to see it.


This is probably common knowledge, but I thought it was cool.

Wednesday, October 15, 2008

Fun with Ruby 1.9 Regular Expressions

I’ve reorganized the regular expression content in the new Programming Ruby, and added some cool new advanced examples. This one’s fairly straightforward, but I love the fact that I can now start refactoring my more complex patterns, removing duplication.


The stuff below is an extract from the unedited update. It’ll appear in the next beta. It follows a discussion of named groups, \k and related stuff.




There’s a trick which allows us to write subroutines inside regular expressions. Recall that we can invoke a named group using \g<name>, and we define the group using (?<name>...). Normally, the definition of the group is itself matched as part of executing the pattern. However, if you add the suffix {0} to the group, it means “zero matches of this group,” so the group is not executed when first encountered.


sentence = %r{ 
(?<subject> cat | dog | gerbil ){0}
(?<verb> eats | drinks| generates ){0}
(?<object> water | bones | PDFs ){0}
(?<adjective> big | small | smelly ){0}

(?<opt_adj> (\g<adjective>\s)? ){0}

The\s\g<opt_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
}x

md = sentence.match("The cat drinks water")
puts "The subject is #{md[:subject]} and the verb is #{md[:verb]}"

md = sentence.match("The big dog eats smelly bones")
puts "The adjective in the second sentence is #{md[:adjective]}"

sentence =~ "The gerbil generates big PDFs"
puts "And the object in the last is #{$~[:object]}"

produces:


The subject is cat and the verb is drinks 
The adjective in the second sentence is smelly
And the object in the last is PDFs



Cool, eh?

Monday, September 8, 2008

Fun with Procs in Ruby 1.9

Ruby 1.9 adds a lot of features to Proc objects.


Currying is the ability to take a function that accepts n parameters and fffgenerate from it one of more functions with some parameter values already filled in. In Ruby 1.9, you create a curry-able proc by cthe curry method on it. If you subsequently call this curried proc with fewer parameters than it expects, it will not execute. Instead, it returns a new proc with those parameters already bound.


Let’s look at a trivial example. Here’s a proc that simply adds two values:


plus = lambda {|a,b| a + b}
puts plus[1,2]

I’m using the [ ] syntax to invoke the proc with arguments, in this case 1 and 2. The code will print 3.


Now let’s have some fun.


curried_plus = plus.curry n
# create two procs based on plus, but with the first parameter
# already set to a value
plus_two = curried_plus[2]
plus_ten = curried_plus[10]

puts plus_two[3]
puts plus_ten[3]

On line 1, I create a curried version of the plus proc. I then call it twice, but both times I only pass it one parameter. This means it cannot execute the body. Instead, each time it returns a new proc which is like the original, but which has the first parameter preset to either 2 or 10. In the last two lines, I call these two new procs, supplying the missing parameter. This means they can execute normally, and the code outputs 5 and 13.


You can have a lot of fun with currying, but that’s not why we’re here today.


Over the weekend, Matz added a new method to the Proc class. You can now use Proc#=== as an alias for Proc.call. So, why on earth would you want to do that? Well, remember that === is used to match terms in a case statement. Over of the AimRed blog, they noted that this feature could be used to make the matching in case statements actually execute code. In their example, they manually added the ===method to class Proc


class Proc
def ===( *parameters )
self.call( *parameters )
end
end

Then you can write something like


sunday = lambda{ |time| time.wday == 0 }
monday = lambda{ |time| time.wday == 1 }
# and so on...

case Time.now
when< sunday
< puts "Day of rest"
when monday
puts "work"
# ...
end

See how that works? As Ruby executes the case statement, it looks at each of the parameters of thewhen clauses in turn. For each, it invokes its === method, passing that method the original case discriminator (Time.now in this example). But with the new === method in class Proc, this will now execute the proc, passing it Time.now as a parameter.


While updating the PickAxe, I noticed that Matz liked this so much that it is now part of 1.9. And it means we can combine this trick with currying to write some fun code:


is_weekday = lambda {|day_of_week, time| time.wday == day_of_week}.curry

sunday = is_weekday[0]
monday = is_weekday[1]
tuesday = is_weekday[2]
wednesday = is_weekday[3]
thursday = is_weekday[4]
saturday = is_weekday[6]

case Time.now
when sunday
puts "Day of rest"
when monday, tuesday, wednesday, thursday, friday
puts "Work"
when saturday
puts "chores"
end

Is this incredibly efficient? Not really :) But it opens up quite an interesting set of possibilities.

Sunday, June 15, 2008

Monday, June 9, 2008

Screencasting Ruby Metaprogramming

image



I’ve been teaching Ruby (and in particularly, metaprogramming Ruby) for almost 7 years now. And, in that time, I’ve gradually found ways of cutting through all the confusing stuff to the actual essentials. And when you do that, suddenly things get a lot simpler. I’ve always know that Ruby didn’t really have class methods and singleton methods, for example, but until recently I didn’t have a simple way to explain that.


Then, when preparing to give an Advanced Ruby Studio, my thinking crystalized. Metaprogramming in Ruby becomes simple to explain if you focus on four things:


  • Objects, not classes.

  • There is only one kind of method call in Ruby. The “right-then-up” rule covers everything.

  • Understanding that self can only be changed by a method call with a receiver or by a class or module definition makes it easy to keep track of what’s going on when metaprogramming.

  • Knowing that Ruby keeps an internal concept of “the current class” which is where def defines its methods. Knowing what changes this makes it easier to know what’s going on.

I tried this approach in a number of Studios, and refined it during some talks for RubyFools in Copenhagen and Oslo.


So Mike Clark, who’s producing our new series of screencasts, started pushing me to put this description into video. Last week I finally cleared the decks enough to record the first three episodes.


First, I have to say it was a blast. I’d never recorded this many minutes of screencast before, and I was blown away by the amount of time it takes. I was also surprised at the level of detail involved, from microphone setup (which I messed up for a couple of segments) to color matching between codecs, it was fun to learn a whole new set of technologies.


I was also surprised at how hard it was to talk to a microphone. When we write books, we always try to write as if the reader was sitting there next to us. I tried to to the same approach with the screencasts, but it takes a whole new set of skills…


What I really liked was the way that I could live code examples to illustrate points. The first episode has maybe 50/50 code and exposition, and the second and third episodes are mostly code. And the code acts as a great skeleton on which to hang the concepts. Apple-R also keeps me honest.


So, if you’re interested in how the Ruby object model really works, and want to improve your metaprogramming chops, why not check them out?

Thursday, May 22, 2008

New lambda syntax in Ruby 1.9

I’m slowly getting used to the new -> way of specifying lambdas in Ruby 1.9. I still feel that, as a notation, it could be clearer. (I’d personally like just plain backslash, because that looks pretty close to a real lambda character, but that’s not going to happen.) But having punctuation, rather than the wordlambda, makes a surprising difference to the way my eyes read code.




For example, you could write a method that acts like a while loop.


def my_while(cond, &body)
  while cond.call
    body.call
  end
end   

In Ruby 1.8  and 1.9, you could call this as


a = 0
my_while lambda { a < 5 } do
   puts a
   a += 1
end

But my brain finds that seriously hard to scan. The Ruby 1.9 -> syntax makes it slightly (just slightly, mind you) better:


a = 0
my_while  -> { a < 5 }  do
   puts a
   a += 1
end

I suspect this is just a question of time. In a year or so, we’ll parse the -> syntax in our heads without thinking twice. Once it does become natural, I suspect we’ll find all sorts of new uses for procs.



Sunday, May 18, 2008

Code in Presentations, Part II

OK, enough people asked, so…


http://github.com/pragdave/codex/tree/master


Every good relationship starts by establishing some basic ground rules. Here’s ours: you’re on your own. Totally, bleakly, and emptily on your own. No support. No requests for enhancements. No cards on your birthday. And I want to continue to see other developers.


But I will consider patches. In particular splitting it up so it can be installed as a Gem would be really nice. You’d probably need some kind of generator to create a new slide show. I’d guess would contain just a Rakefile, a slides/ directory and an html/ directory.


Enjoy.

Thursday, May 15, 2008

Our take on presenting code

Back in March, Jim Weirich posted some notes on a clever technique for getting code into Keynote presentations. It struck a chord with me, because I’ve been suffering the same problem for a long time now. Eventually, the pain of putting together the Studio content with Mike Clark and Chad Fowler drove me to find a solution. (The pain wasn’t working with Mike and Chad—it was creating and keeping up to date many hundreds of slides, most of which contained code.)


The solution we went with was based on the way we do code in the Bookshelf books. Rather than embedding the code in the slides, we write regular old programs. Then, in the slide material, we reference the source file (and optionally say which section of that source file), and the appropriate code gets dragged into the slide, syntax highlighted, and hyperlinked back to our editor. Here’s how it works.


Create Your Material


We’ve given up using Keynote and Powerpoint. They’re a pain with version control, and they make it easy to fall into the eye-candy trap, favoring glitz over content. Instead, we create our material is plain text files using Textile markup. Typically we use one file per major topic, and the use an index file to bring all these individual files together into a single overall presentation.


Within the material, we can include material from external files using the :code directive.


Here’s the source for an individual slide:


h1. const_missing
Correctly handles nested modules
:code code/meta/const_missing.rb

and here’s what appears on the screen:


image


The code gets inserted onto the slide and is syntax highlighted. The blue text below the box shows the file name (so attendees can find it in their collateral material). It’s also a txmt: hyperlink—click it and the file opens in Textmate, so we can edit and run it.


image



Using Parts of a Source File


You often just want to show part of a larger source file. We do that by including START:tag and END:tagcomments in the original source. (This works in any language, and not just Ruby source). In the slide markup, you indicate the part(s) you want to include in square brackets after the file name:


h1. method_missing
:code code/meta/my_ostruct.rb[impl class="code-small"]

This says to look at the source file code/meta/my_ostruct.rb and only include on the slide the stuff between START:impl and comments. We’ll also display it using the CSS class code-small.


The ability to include parts of code is invaluable when you’re doing a sequence of slides that builds a solution: you can show each part of a source file in turn.


Building the Presentation


The toolchain that takes all this is remarkably simple, because most of the work is done for us. We use a simple Ruby script that takes our original slides, embeds the source code from external files, and then runs Textile to produce an HTML version. We then add a header to that HTML that drags in two incredibly useful Javascript libraries.


For the presentation itself, we use Eric Meyer’s S5 system. It gives us nice looking slides, simple to use navigation, and lets us present in our own browsers or (potentially) on our students’.


For the syntax highlighting of code, we use SyntaxHighlighter. This clever piece of code doesn;t require you to mark up the code elements inthe HTML. Instead you just flag your <pre> blocks with an appropriate class and it does the parsing and highlighting in the browser. It means that really large decks can be a little slow to load (but the still beat Keynote on elaspsed time), but it also means your HTML is really clean.


Finally, we have a Rake task that lets us built the whole presentation or just individual chapters.


The whole thing took about 4 hours to get working, and probably another 4 hours on and off to tweak it based on experience. The code’s not really in a state that can be released (so please don’t ask), but it wouldn’t take much to produce something you could do the same with.


It Actually Works in Practice!


So far, we’ve done two studios using this stuff (Advanced Ruby and Erlang), and I’ve used it in a number of conference presentations. I wouldn’t switch back to regular presentation software for any code-based talk. (I’ll still use Keynote for non-code slides, though.)


A Few More Slides


Here’s the source:


h1. initialize_copy
Container wrappers such a OStruct have a potential problem
:code code/meta/my_ostruct_problem.rb[class=code-small]

h1. initialize_copy

:code code/meta/my_ostruct_ic.rb[impl class=”code-small”

h1. const_missing

* Module method whenever undefined constant references in that module
** (Module is a module, and acts as a global place for @const_missing@)
* Mostly used to autoload classes
* Not as easy as it looks (Rails’ @dependencies.rb@ is 500 lines long

h1. const_missing

:code code/meta/const_missing_autoload.rb[class=code-small]

And here are the resulting slides:


image


image


image


image

Sunday, April 27, 2008

Shoulda used this earlier

In many ways, testing software is like going out and getting exercise. You know you should do it, and you know it does you good, but it’s also pretty easy to find an excuse to skip it (I’ll make it up tomorrow).


So anything that makes testing easier is good, because it cuts down on the excuses not to do it.


One thing I’ve never really liked about the conventional xUnit-style testing frameworks was the setup and teardown structure. In these frameworks, a test case is a class, and setup and teardown are implemented by methods in that class. Each test is also a method, so the basic flow is


  for each test method in the class
run setup
run the test method
run teardown
end

Nice and simple. Each test method got the benefit of a standard environment created by the setup method, and the teardown method got the job of tidying up after.


Except… when I’m writing tests, I typically want to set up lots of different scenarios. I’ll want A and B and C, then A and B but not C, then A and not B, then A and D, and so on. I had two choices—write lots of test case classes, using subclassing to inherit common setup behavior, or write per-test method setup code (often factored out into helpers). In the end, I almost always did the latter, And that was tedious, and it made it harder to see the tests for the setup code.


I flirted with RSpec. Its spec framework seemed to have what I wanted. But I just couldn’t get myself to enjoy using it. (I think it’s a cat people/dog people kind of thing)


Enter shoulda


Then, a couple of weeks back, Mike Clark and Chad Fowler introduced me to shoulda. Shoulda isn’t a testing framework. Instead, it extends Ruby’s existing Test::Unit framework with the idea of testcontexts. A context is a section of your test case where all the test methods have something in common. At it simplest, a context could be simply used as an annotation device (and, yes, this is a silly example):


context "My factorial method" do
should "return 1 when passed 0" do
assert_equal 1, fact(0)
end
should "return 1 when passed 1" do
assert_equal 1, fact(1)
end
should "return 6 when passed 3" do
assert_equal 6, fact(3)
end
end

The stuff in a context can share common setup code—just write a setup block.


class CartTest < Test::Unit::TestCase

context "An empty cart" do
setup do
@cart = orders(:wilmas_empty_cart)
end

should "have no line items" do
assert_equal 0, @cart.line_items.size
end

should "have a zero price" do
assert_equal 0, @cart.price
end
end

context "Some other context..." ...
end
end

So now, within a single test case I can set up multiple contexts, and each context can have its own environment.


But, take it back to my original problem. I often want to set up hierarchies of related environments for my tests. The shaoulda code handles this wonderfully, because it lets me nest contexts. For example, I’m adding a feature to our store that gives customers some additional information if, during checkout, their credit card transaction was initially rejected because the address was wrong, and was then accepted when they fixed the address. I wanted two tests, one without the prior address error, and one with.


To set up this environment, I needed to set up a shopping cart, create a dummy response from our payment gateway, and post that response to the application. In the case of the prior address error, I also wanted to inject an entry containing that error into the transactions associated with the order prior to generating the response.


With shoulda, I simply created some nested contexts. The top level context did the shared setup, and the inner contexts then set up appropriate environments for their tests. It looked like this:


  context "Checking out"  do
setup do
@cart = cart_named(:freds_full_cart)
@cart.prepare_for_store_authorize!
@params = approved_authnet_response(@cart)
end

context "with no AVS errors in CC transaction history" do
setup do
post :post_from_authnet_authorize, @params
end

should_redirect_to "{:action => :receipt}"
end

context "with AVS errors in CC transaction history" do
setup do
avs_error = CcTransaction.new(:response_code => 2, :response_reason_code => 27)
@cart.cc_transactions << avs_error
post :post_from_authnet_authorize, @params
end

should_redirect_to "{:action => :explain_avs_mismatch}"
end
end

The outer setup gets run before the execution of each of the inner contexts. And the setup in the inner contexts gets run when running that context. And shoulda keeps track of it all, so I get very natural error messages if an assertion fails. For example, if the test in the second context above fails, I’d get


Checking out with AVS errors in CC transaction history should 
redirect to "{:action => :explain_avs_mixsmatch}".

So, now, I can finally set up my hierarchies of test environments in a natural way. It isn’t revolutionary. It’s just one less excuse for not testing…