DABlog

a dump/archive of David A. Black's original weblog

2006-2011

The articles are listed below, in chronological order. The first few are undated. I'm not sure why&emdash;maybe they're in twice?

Enjoy.

Training techniques and practices (Undated)

Training 1: Background and ramp-up (Undated)

Training 2: Handling mixed student levels (Undated)

Training 3: Hands-on, lectures, and demos (Undated)

Training 4: When things go wrong.... (Undated)

Corrected link to The Compleat Rubyist (Undated)

Training, part 1: Dealing with uneven levels of preparation (Undated)

Training: Introduction to a series of articles (Undated)

"Advancing with Rails" gets off to a fine start! (Undated)

Training, part 3: Advice on lecturing and topic presentation (Undated)

The night before (Tue Jun 20 21:32:00 2006)

Submit!! (a proposal for a RubyConf talk, that is) (Thu Jun 22 07:18:00 2006)

Modeling many-to-many: I guess I was right the first time.... (Sun Jun 25 08:20:00 2006)

The agony and the ectasy (of RubyConf proposals, that is) (Sat Jul 1 09:16:00 2006)

Why I am conservative about changes to Ruby (Sat Jul 1 12:18:00 2006)

10/10 review of Ruby for Rails on Slashdot (Wed Jul 12 17:35:00 2006)

The laptop stratum: thoughts from (half of) OSCON (Thu Jul 27 10:25:00 2006)

Regional Ruby Conference grants from Ruby Central (Fri Jul 28 13:09:00 2006)

Special offer for Ruby users groups, from Ruby Power and Light (Sat Jul 29 12:25:00 2006)

No more comments for the moment (Thu Aug 10 20:07:14 2006)

No, really: my book is Ruby for Rails!! (Sat Aug 12 12:14:46 2006)

Home from the Michigan Ruby Conference (Sun Aug 27 15:23:00 2006)

Free Rails workshop in Malmo, Sweden! (Mon Sep 11 10:29:00 2006)

RailsConf Europe and beyond.... (Mon Sep 18 05:08:00 2006)

Dinner for three (Sun Sep 24 12:03:33 2006)

Have fun (without me) at RubyConf! (Wed Sep 27 15:55:02 2006)

[Postponed] One-day Rails intro workshop in Toronto, December 15 (Sun Nov 19 16:34:22 2006)

More A than R: reconsidering the "new" AR object (Sat Dec 23 08:57:00 2006)

Enough already with freaking out over people's sex (Wed Jan 3 19:30:58 2007)

Will trade Ruby/Rails tutoring for website design work! (Wed Jan 3 20:35:39 2007)

Meta, shmeta: learning Ruby horizontally (Sun Jan 7 10:20:49 2007)

Emerging Tech conference coming up (Wed Feb 7 10:26:37 2007)

The Magic Pens of Ruby (Sun Feb 18 14:01:00 2007)

Sudoku solutions: who cares? (Sun Feb 25 23:47:00 2007)

DABlog now using Mephisto (Sun Feb 25 23:52:00 2007)

Rails training by Ruby Power and Light! (Tue Mar 27 14:43:00 2007)

The L in DSL: langue ou langage? (Tue Apr 17 18:19:00 2007)

Tough love from Verizon (Mon May 14 12:57:00 2007)

Boston Early Music Festival wrapup (Sat Jun 16 23:44:00 2007)

The Stupidity Tax (Wed Jul 4 12:47:00 2007)

Bang methods; or, Danger, Will Rubyist! (Wed Aug 15 11:35:00 2007)

Reflections on Wikipedia (Tue Sep 4 12:53:00 2007)

Upcoming Rails training in New Jersey! (Fri Sep 14 07:00:00 2007)

"Advancing with Rails" training in Berlin, Nov. 19-22 (Fri Oct 19 12:13:00 2007)

Upcoming Rails training, 2008! (Sat Mar 22 19:17:00 2008)

Splitting hairs over "resource": the case for the affirmative (Part 1) (Sun Mar 23 00:49:00 2008)

A short-circuit (||=) edge case (Tue Mar 25 15:11:00 2008)

Short-circuit (||=) post -- CORRECTION (Wed Mar 26 13:46:00 2008)

Getting out of Ruby's way: code beauty and/or greatness (Fri Mar 28 09:40:00 2008)

Splitting hairs over "resource": the case for the affirmative (Part 2) (Thu Apr 24 11:55:00 2008)

Death of a racehorse (Sun May 4 13:59:00 2008)

Slide words (if that's really what they're called) (Sat Jun 7 15:22:00 2008)

July 6-12 is "Link To Something Other Than Wikipedia" Week! (Sat Jul 5 01:27:00 2008)

Co-Training with Erik Kastner (Sun Jul 20 12:31:00 2008)

Pseudo-persuasion in online discourse (Wed Aug 6 11:57:00 2008)

Back from RailsConf Europe 2008 (Sat Sep 6 08:07:00 2008)

Tracks a-go-go at RubyConf 2008! (Sat Sep 13 10:00:00 2008)

Why I am suspicious of the bailout bill (Fri Oct 3 21:14:00 2008)

RESTful Rails for the restless (Mon Nov 24 12:18:00 2008)

Probative Programming: the physical unification of code and tests (Sun Nov 30 13:05:00 2008)

On the menu this season: Muslims and gays (Sun Dec 21 15:59:00 2008)

Cool wishlist management at WishSight! (Mon Dec 29 15:13:00 2008)

10 things to be aware of in moving to Ruby 1.9 (Wed Jan 14 19:21:00 2009)

Son of 10 things to be aware of in Ruby 1.9! (Fri Jan 16 14:20:00 2009)

RailsConf registration (and a hiatus year for RailsConf Europe) (Fri Jan 23 22:31:00 2009)

Why athletes thanking God for victories is stupid (Tue Feb 3 01:38:00 2009)

Ruby training in Atlanta, April 1-3! (Mon Feb 16 14:50:00 2009)

Did I mention Ruby training in Atlanta, April 1-3? (Sat Mar 14 14:21:00 2009)

Is this an early use of the slang "cool"? (Sat Mar 21 01:22:00 2009)

Envycasts featuring David A. Black: Ruby 1.9: What You Need To Know (Tue Apr 21 23:10:00 2009)

"The Well-Grounded Rubyist" now available in PDF! (Tue Apr 21 23:15:00 2009)

My new Ruby book is out! (Wed Jun 10 23:57:00 2009)

The wise Latina comment in historical perspective (Thu Jul 16 22:05:00 2009)

Ruby training: for the non-beginner? (Tue Jul 21 21:11:00 2009)

The Compleat Rubyist: what's it all about? (Sat Oct 17 14:57:00 2009)

Starting a new job in December (Fri Nov 13 13:23:00 2009)

AccrediDation (Wed Mar 24 01:07:00 2010)

Training: a series introduction (Mon Jan 24 22:52:00 2011)

Training, part 2: Handling mixed levels of student experience in a class (Thu Jan 27 12:51:00 2011)

Training, part 3: The lecturing component of presentation (Fri Feb 4 10:34:00 2011)

Training, part 4: Live code demos (Sat Feb 26 13:13:00 2011)

Training techniques and practices

Undated

This is the first in a four-part series of DABlog entries on the subject of training in Ruby and Rails. Who’s it for? If you are:

interested in teaching/training as a subject unto itself;

active, or thinking of being active, as a Ruby/Rails instructor;

curious what the stuff going through the head of someone who’s in this field might be;

an incurable weblog junkie;

these articles might be of interest to you. In writing them, I’m envisioning a reader who’s a trainer. But that’s not a requirement, as long as you don’t mind my referring to “you” as if “you” were a trainer.

The four parts will be:

1) Teaching and/or training: some introductory notes and ideas 2) Accomodating different backgrounds and levels in the classroom 3) Hands-on vs. lecture: a delicate balance 4) When things go wrong; or, how to sharpen your wits and thicken your skin

I don’t have sections for comments, but I’d be glad to hear from you directly if you have any comments or questions.

Happy reading!

Back to top

Training 1: Background and ramp-up

Undated

For thirteen years, I made my living as a teacher. I was a member of the Department of Communication at Seton Hall University from 1992 to 2005. In the Fall of 2005, I was starting a year-long sabbatical. I took a long, hard look at where I was at in life, and I decided that instead of taking my sabbatical, I would resign and go full-time into Ruby and Rails consulting and training.

At the time, I was writing Ruby for Rails , so the first several months were more about writing than consulting and training. But then the book got done, and the other stuff started up in earnest. By February of 2006 I was traveling on Ruby and Rails business; and by the end of the year I had visited something like twenty-three cities in North America and Europe, almost all for Ruby/Rails purposes of one kind or another.

I’m in the wonderful position of having turned a hobby—albeit an already passionate, semi-professional one—into a career. But I’ve also turned a career into a career. A lot of what I do nowadays is training; which is to say, teaching. So there’s continuity with my previous career, as well as change.

I’m enjoying the training side of my career because, on the one hand, I’m completely at home in any classroom situation and, on the other hand, it’s really quite different from undergraduate teaching. For one thing, I don’t have to give grades. As my mother, a professor and former Ivy League Law School Dean, has put it, “Grading is the part they pay us for.” I don’t miss it.

Training engagements are also shorter term than college courses. They’re intense, but they typically last five days or less. The intensity is challenging, but I like it. Having fed the history of broadcasting to communication students forty-five minutes at a time, three times a week for thirteen years, I rather like being able to spend entire days on a topic.

Another difference between college teaching and professional training is that in the latter situation you’re not responsible for discipline or character development. I was a rather in-your-face college teacher. I would say things to students—and it wasn’t an act; I meant every syllable of it—like, “When you cheat on an exam, you’re sending me the message that what I have chosen to do with my life is a waste of time!” I was deeply invested in the process.

I still would be, if I were teaching college. And I still am… but not in that way. I’m passionate about the subject matter and the process of putting it across. But I’m not called upon (indeed, not invited) to participate in the moral and ethical blossoming of my students. It’s a relief not to be. To each his own; I think thirteen years of teaching in that milieu was enough for me (at least for the next thirteen years). Right now I’m very happy just being in a room with a bunch of adults who are generally motivated and attentive, and whom I do not have to reprimand when they’re not.

Now and then I used to get a college student who would tell me that they should have a better grade because they paid for the course. (No, really; I did have at least one who said that outright, and many who strongly implied it.) My stock response was: you don’t pay a doctor to tell you you’re well, but to tell you whether you’re well.

In the professional training world, there’s a little more substance to the “The client is always right” axiom. It’s a different situation; each course exists in the first place because a client arranged for it. But I see this as part of the scenery, not a big stumbling block in practice. By the time the course is delivered, there’s a very good chance that it’s what the client wants. In theory, if a client told me in mid-stream that everything had to be changed drastically, I’d have to take the request quite seriously. But it hasn’t happened yet. (I’m probably jinxing myself, but so be it.)

But enough about me. You get the picture: I’m a career teacher who’s shifted careers, and I’m also, for better or worse, someone who thinks a lot about the nature of the process of teaching.

In the upcoming articles in this series, I’ll be talking about specific aspects of training. The focus is on Ruby and Rails training. Some of my comments will, however, be general—because teaching, when you get right down to it, is teaching.

Back to top

Training 2: Handling mixed student levels

Undated

Let’s dive into the deep end. Without any doubt, the hardest thing about the kind of training I do- hardest for the trainer, that is -is accomodating people who come to the class at different skill levels and from different backgrounds.

This problem is not specific to professional training. As I said at the end of Part 1, teaching is teaching. And unless the teaching is one-on-one, you’re going to be dealing with people who differ at least somewhat in what they bring to the table.

It’s also not specific to Ruby and/or Rails. But Rails does tend to attract people from different backgrounds: the coders, the designers, the database people, the managers. Sometimes it’s because everyone wants to know what this new thing is that the company has decided to use. It’s also because Rails cuts a wide path across many layers- MVC, to start with -and at least parts of it are of interest to people who do very different things. That still leaves you, as a trainer, with a potential grab-bag of students, and the need to teach a cogent course.

The problem is often very acute. I’ve taught beginning Rails courses where one or two people out of perhaps five or ten already had Rails applications in production. I’ve had people raise their hands while I’m explaining how to assign a value to a variable in Ruby and ask me a question about reimplementing Capistrano. (Well, that’s a slight exaggeration, but only slight.) I’ve had classes with people in them who had never used a command line, and other people who could pinpoint topics in Rails books by chapter.

It’s not just that some people have read a couple of blog posts and the others haven’t. I’m talking about very different backgrounds. In these situations, you open your mouth to speak, and you realize that there is literally nothing, except perhaps, “It’s raining,” that you can say that can possibly address the needs of everyone in the room.

So you have to make choices. But it’s not all at the moment of opening your mouth. There are lots of things you can do.

1. Before the course

A. Make requirements clear

When you’re describing the course, and discussing the skill level required, you need to use tough love and be clear and firm about the requirements. It’s in everyone’s interest.

For a Rails course it’s important to be clear about the role of Ruby. You can teach Rails to people who know Ruby, or people who don’t- either is OK -but mixing the two is problematic. And for some reason it seems that people are more likely to assume that prior Ruby knowledge is not a factor in a Rails class than they would be to assume that, say, Java knowledge is not a factor in a Struts class. So it’s good to be specific.

B. Try to control the teacher/student ratio

To the extent that you can, keep the teacher/student ratio at 1/15 or higher. Beyond fifteen, in my experience, one starts to hit a critical mass where the amount of help needed expands beyond the confines of the available time.

This is ancient wisdom, of course; universities like to brag about their tiny class sizes and all of that. And with training classes (as with universities, incidentally), you can’t always control it. But if you’re presented with, say, the prospect of providing hands-on, closely coached Rails training for twenty-five or thirty people, see if you can find another instructor—or at least a lab assistant who can troubleshoot installation and other matters so that you’re not doing everything.

2. Have extra material in reserve; encourage extra projects.

When I perceive a major level gap in a class, and sometimes even when I don’t, I encourage students to come up with a Rails project of their own, above and beyond the ones in my workbook, so that they have something to do if they get through the exercises quickly. But it’s by no means just a way to pass the time. Working on a new project from scratch is a logical and beneficial next step for students who have worked through examples. Ideally, everyone would do it in every course. Things don’t tend to work out that way, time-wise; but it’s all to the good if some students do at least get a start on a project of their own.

(And it does help them pass the time!)

3. Enlist the help of the more advanced students.

I’m thinking of situations where, say, someone is clearly over-qualified for the exercises in the workbook, and someone else is struggling. It’s possible that the best course of action is for the over-qualified student to pair up with the struggling one and help them out.

This is a tricky strategy, though. It’s your job, not theirs, to do the teaching. The situation has to be really right before you ask students to teach each other.

But it often is really right. For one thing, teaching something really does help you learn it—so everybody wins. And some people would rather spend the time engaged in an activity with someone else than go off and work on what might be, in fact, just another Rails application out of many that they’ve written.

As the teacher, though, you have to make sure that the result is at least as great as the sum of its parts. You don’t want it to backfire and have both students think you’re trying to brush them aside.

4. Get good at not answering advanced questions.

One of the toughest things is when an advanced student asks questions that are over the heads of everyone else in the class. You don’t want to tell the person that they can’t ask questions, but you don’t want to alienate the rest of the class or make them anxious that the material is zooming by faster than they can grab hold of it.

There’s no hard and fast rule, but I tend to come down on the side of answering these questions very quickly. It’s always possible for the advanced person to ask you later; but you only have one shot at making the dynamics of the classroom work for everyone. I’ll often just tell the student that I don’t want to go into it in depth right now, but here’s a bit of info and let’s talk about it later.

5. Focus on stuff they probably don't really know, like Ruby.

I have a natural inclination to think that everyone else knows more than I do. Call it modesty, inferiority complex—whatever. Ironically, it sometimes makes me come across as sort of a knowledge snob; I’ll make references in conversation to things that I know about that other people don’t, because I assume that if I know about it, so does everyone else.

This quirk is relevant here because in order to become a teacher, I had to overcome it. I had to discover for myself that talking to someone who knows less than you do doesn’t mean you’re talking down to them. If you’re in a room full of undergraduates who have never heard of Jack Benny, then it’s appropriate and teacherly to explain Jack Benny to them. You’re not insulting their intelligence; you’re helping them.

When I ask people in a Rails class how much Ruby they know, it’s no problem getting them to answer accurately. The challenge for me is to act on the fact that I almost certainly know more than they do. And that’s as it should be—and I love explaining the language to them.

I can’t help thinking of one of my favorite undergraduate students ever, a wrestling champ (now a New Jersey State Trooper) who undertook to teach me how to use some of the weight machines at the gym. When he first suggested doing this (after listening to me grumbling about how little exercise I did), I demurred; I didn’t want to impose on him, didn’t want him to waste time, and so on.

His response, which I can still hear in my head, was:

“I’ve got knowledge. What am I gonna do, keep it to myself?”

6. Make it easy to move around the materials (e.g., staged code).

For the main do-as-you-go application in my workbook, I’ve got about 25 code stages. Each one represents the state of the application at a particular point in the book. If a student falls a bit behind, or wants to skip a section they already know about, they can move to a later chapter or section and swap the most recent code stage into their working code directory.

For that matter, if I want to skip over something, I can pick up from a particular code stage and keep going. I don’t normally do this, but sometimes I’ll compress something that was an exercise into a short demo (for time reasons), and having code stages enables me to do get us back on track, and in sync with the application code, easily.

7. Make a virtue of necessity; people might realize that they're not going to grasp everything. Let, e.g., database people dwell on that stuff--or on the stuff they don't know, or whatever.

Back to top

Training 3: Hands-on, lectures, and demos

Undated

In general, students like the training to consist largely of hands-on exercises. I like it too; you can’t really learn something like Rails by hearing someone talk about it, any more than you can learn the cello by hearing someone describe how to play it.

At the same time, it doesn’t pay to get too obsessed with trimming the time you spend demonstrating and explaining things. Lecturing for a while doesn’t mean you’ve disserved the students—as long as your lecture segments are good.

Don’t say too much at once

When you’re dealing with a system, it’s hard to know where to stop. The controller instantiates an ActiveRecord object, which it tries to save, which it may or may succeed in doing because of validations… and if it does, then it gives it to the view, which uses special templating language to embed it, and that looks like this….

The art of not explaining things, at least until it’s really time to explain them, is as important as the art of explaining things. You may have to bite your tongue; it’s not easy, for example, to show people:

def update user = User.find(params[:id]) user.update_attributes(params[:user]) redirect_to user_url(user) end

with no validation tests, if you’re used to doing a more full-blown version of updating. You feel like you’re concealing something, or even lying.

But take page from the book of Don Knuth. He warns you up front that he’s going to lie to you. The lying is in the service of the learning. There’s no point giving students a thick, complete account of what’s going on. It doesn’t work; they won’t learn anything.

Moreover…

My cello teacher used to characterize the relation between consecutive phrases with the word moreover. For example, the second Suite of Bach begins with three notes, rising:

Then comes the “moreover” part, leading even higher:

And if that didn’t convince you:

One thing builds on another. You cannot find too many opportunities to bring out this kind of structure, whether in music or teaching or any other art. Don’t just stockpile tips and tricks. Look for the joins, the connective tissue that lets you build one thing on top of another:

Ruby has attributes.

ActiveRecord objects have attributes too.

pause

And they work like all Ruby attributes, except...

... they come from the database column names, instead of names you invent!

Do live code demos

I’ve never been a slide person. I have a hard time creating good slides, and I find most slides in other people’s talks unhelpful. The nadir of slide usefulness must have been the years when my college students had discovered PowerPoint. If I’d kept teaching, I probably wouldn’t have prohibited it. Most of the time, what they did was to cut-and-paste material from the Internet, put it on the screen, and read it out loud to the class. (The cut-and-paste practices are another, fairly disturbing story unto themselves.)

I never use slides in professional training. I don’t even really know whether other people do or not. I don’t. But I do use the projector, mostly for live code demos.

Live code demos always involve a bit of risk. I’d venture to say that’s part of why they’re absorbing. Not that people are rooting for the code not to work—but a little danger adds spice.

Irb is a great tool for live code demos, both in its default form and in its capacity as the Rails application console.

Do semi-live code demos

There are certain things I don’t like doing from scratch live. Deployment with Capistrano is one of them. It never seems to go right all the way along. I’ll take the fall for this—I have no reason to assign blame to Capistrano—but I have to live with the fact that live Capistrano demos are, for me, too risky.

So I have a “canned” demo. It’s actually live, but I prepare a lot in advance (it’s the permission settings and passwords that always get me with Capistrano). And I have a list of steps that I consult while I’m doing the demo. Nor do I hide the list from the class; there’s no detrimental effect to their seeing it, and if they think my use of a script like this means that I’m inadequately skilled, then at least now they know!

The cooking show approach

On TV cooking shows, you often see the chef mixing the ingredients, but then there’s a kind of fast-forward to the finished product, especially with baking. The idea is that you don’t really want to wait in real time for the baking to happen, and even if the show isn’t broadcast live it’s probably being taped with a live audience, and they don’t want to wait either.

The cooking show approach can be very handy for in-class demos. It’s particularly suited to cases where you want to demonstrate how to do something relatively small, and then want to show how it fits into a finished application. Rather than have the students sit through the writing of the whole application, you can write the bit you’re talking about—a data validation directive in a model file, perhaps— and then run the whole application and show that it fails when the data is invalid.

Training isn’t as linear as baking, though. As a session progresses, you’ll keep going back to the “ingredients” level, and then back to the “cake” level. So you can’t always apply cooking show logic literally.

Still, it’s a helpful way to think about the pace of training, and also a reminder that while you’ll be teaching details, you don’t want to get bogged down in irrelevant details. It’s better to jump from a small example to a big application, than to try to fit everything in before you grant a glimpse of a finished product.

Back to top

Training 4: When things go wrong....

Undated

Back to top

Corrected link to The Compleat Rubyist

Undated

Like the space cadet I am, I mistyped a link (twice) in my last blog post. Thanks to Jim James for pointing out the error.

The correct link is… (drumroll)... The Compleat Rubyist.

And the article, with the link now corrected, is here.

Hoping to see many of you at The Compleat Rubyist in January!

Back to top

Training, part 1: Dealing with uneven levels of preparation

Undated

For me, the most challenging thing about training is accomodating people who come to a class from different backgrounds and at sometimes vastly different levels of knowledge.

I remember a Rails class whose members included a participant in that year’s “Rails Day” contest (i.e., a very experienced Rails developer), side-by-side with someone who had literally never written a computer program and never seen a command line. The latter person was a front-end designer, and I have every reason to think she was skilled and successful. But she did not belong in that class.

Given a room with that kind of diverse population, what you can say? I mean, literally, what can you say? What sentence can you formulate that makes sense to everyone in the room, and holds everyone’s attention?

It always comes down to the same dilemma: anything you say is either going to confuse the people who are less advanced, or bore the more advanced ones.

So what should you do? How can you minimize the difficulties going in, and handle them (whether minimal or not) once you’re there?

Here are some ideas.

Make the requirements clear in advance

When you’re describing the course to the client, and discussing the skill level required, show some tough love: be clear and firm about the prerequisites. It’s in everyone’s interest. Don’t try to be all things to all people. Use terms like “not suitable” or “too advanced” when discussing who from their team you think should not be in the course. Use them politely, but use them. Prerequisites don’t have to be fine-grained, but they do have to be clear. “Everyone in the course should already be experienced with at least one object-oriented programming language” is an example of a reasonable pre-requisite. So is “The participants need to be at least somewhat comfortable in a Unix-like environment.” You don’t need to know whether they know all the command line options for xargs . You just need to establish the basic requirements. If you’re teaching Rails, address the role of Ruby. You can teach Rails to people who know Ruby, or people who don’t—either is OK—but mixing Rubyists with non-Rubyists is problematic. It’s possible that potential participants won’t realize that Ruby knowledge is a factor, so it’s good to be clear. As it is with the Ruby/Rails relationship, so it is with any case where you’ve got one technology built on another. Make sure you’re clear about the expected starting-point. As it is with the Ruby/Rails relationship, so it is with any case where you’ve got one technology built on another. Make sure you’re clear about the expected starting-point.

Stick with what got you there!

The starting point and frame of reference always has to be the curriculum you’ve promised to deliver. You can’t zoom ahead just because the material is familiar to someone who’s already done it, and you can’t spend more than a small amount of time on remedial instruction for those who aren’t prepared. If the whole class is at the same level, and the level they’re at isn’t the level you were expecting, then of course you can make a big, overall adjustment. I remember doing that with a programming team who had much more experience than I’d expected. They were too polite to come out and say that they were too advanced for the curriculum, but it wasn’t hard to figure out. (When you set a challenge like implementing attr_accessor , and they all do it correctly in about two minutes, that’s a clue.) So we changed gears and spent the remaining days on more advanced topics and code critique. But given the true mixed-level situation, you have to be guided primarily by what you have promised to deliver. But given the true mixed-level situation, you have to be guided primarily by what you have promised to deliver.

Try to control the teacher/student ratio

To the extent that you can, keep the teacher/student ratio at 1/15 or better. Beyond about fifteen (more or less, depending on the subject matter and pace), you hit critical mass: the amount of help needed by the students expands beyond the confines of the available time for one instructor, so you fall further and further behind. This is ancient wisdom, of course. Universities like to brag about their tiny class sizes and all of that. And with training classes (as with universities, incidentally), you can’t always control it. But if you’re presented with, say, the prospect of providing hands-on, closely coached Rails training for twenty-five or thirty people, see if you can find another instructor—or at least a lab assistant who can troubleshoot installation and other matters so that you’re not doing everything.

Have extra material in reserve

Try to have some ideas for extra projects up your sleeve, above and beyond any in your stated curriculum, particularly for students who are too advanced for the course. Bring a few books with you, and if someone isn’t feeling challenged enough, point them to a chapter that you think they can learn from. They won’t feel shunned; they’ll feel relieved. (Besides, the whole premise here is that the too-advanced person shouldn’t be there in the first place, so anything you do to help them not be bored is in their interest.) In the same vein, put up a webpage somewhere with some links for further study—and when you choose those links, try to choose ones likely to interest people who are somewhat too advanced for your curriculum.

Enlist the help of the more advanced students

I’m thinking of situations where, say, one student is clearly over-qualified for the exercises in the workbook, and another student is struggling. It’s possible that the best course of action is for the over-qualified student to pair up with the struggling one and help them out. This is a tricky strategy, though. It’s your job, not theirs, to do the teaching. The situation has to be really right before you ask students to teach each other. But it often is really right. For one thing, teaching something helps you consolidate your own knowledge—so everybody wins, including the student-teacher. And some people would rather spend the time engaged in an activity with someone else than go off and work on an application or read a book. As the teacher, though, you have to make sure that the result is at least as great as the sum of its parts. You don’t want it to backfire and have both students think you’re trying to brush them aside. Be circumspect about this option, but keep it in mind for the right situation. Asteacher, though, you have to make sure that the result is at least as great as the sum of its parts. You don’t want it to backfire and have both students think you’re trying to brush them aside. Be circumspect about this option, but keep it in mind for the right situation.

Master the art of not answering questions

Of course I intend that header as an attention-grabber. In general you want to answer questions. But what about questions from either the too-advanced or the inadequately-prepared students? When I get a too-advanced question, I usually answer it quickly and, if need be, incompletely. I don’t want to digress too far from the curriculum—and, above all, I don’t want to make the less advanced students feel anxious because they can’t follow what I’m saying. You can always ask the advanced student to talk to you about their question later; but you only have one shot at making the dynamics of the classroom work for everyone. So answer the question quickly; offer to go into it privately later; don’t get into a lot of examples and demos based on the question (that can really make the other students feel abandoned); and move on. Questions that reflect inadequate preparation are harder to deal with. In fact, it may be through such questions that you find out about the preparation-level problems in the first place. This may be a good time to consider a temporary ad hoc “buddy system,” where someone else in the class helps the person, assuming it’s something that can be communicated relatively quickly (like how to start Ruby from the commandline, creating a MySQL database from scratch, etc.). Questions that reflect inadequate preparation are harder to deal with. In fact, it may be through such questions that you find out about the preparation-level problems in the first place. This may be a good time to consider a temporary ad hoc “buddy system,” where someone else in the class helps the person, assuming it’s something that can be communicated relatively quickly (like how to start Ruby from the commandline, creating a MySQL database from scratch, etc.).

Make it easy to move around the materials (e.g., staged code)

For the main do-as-you-go application in my workbook, I’ve got about twelve code snapshots. Each one represents the state of the application at a particular point in the book. If a student falls a bit behind, or wants to skip a section they already know about, they can move to a later chapter or section and swap the most recent code stage into their working code directory. For that matter, if I want to skip over something (if time is shorter than I’d planned), I can pick up from a particular code stage and keep going. I don’t normally do this, but sometimes I’ll compress something that was an exercise into a short demo (for time reasons), and having code stages enables me to do get us back on track, and in sync with the application code, easily.

Talk to the person in charge

You’ll probably have a discussion at the end of each day with the manager who set up the training. You should absolutely bring preparation-level issues to that person’s attention. Ninety-nine percent of the time, they’ll say, “Yeah, I was afraid of that. I just didn’t want to leave those people out”, or words to that effect. The manager knows the team. None of this is going to be a huge surprise. Be sympathetic, though. They didn’t do this to make your life hard. At worst, they just didn’t think it through in terms of preparation and were eager to get the most value out of your skills. Everyone’s acting in good faith. Sometimes, the manager will take someone out of the training after the first day. I always feel a pang of guilt at this—but I shouldn’t, and you shouldn’t. It’s a correction that will make things easier and more productive for everyone, including the person who shouldn’t have been in the training in the first place. Sometimes, the manager will take someone out of the training after the first day. I always feel a pang of guilt at this—but I shouldn’t, and you shouldn’t. It’s a correction that will make things easier and more productive for everyone, including the person who shouldn’t have been in the training in the first place.

Summary

Handling the mixed-level classroom successfully is not easy. You need to stay alert and to keep applying energy to the situation to make it as good as it can be for everyone, while delivering what you promised to deliver. A mixed-level group requires agility and adaptability, but with structure.

Some of the training companies I subcontract with do Likert scale evaluations (“Strongly agree, Agree, Neutral…”—that kind of question). One of the questions is often about the pace of the class. In a mixed-level class, I don’t expect everyone to say the pace was perfect. I aim, though, for the best result possible. I want the curve to peak at “Perfect”. I want to look at it and conclude that if it were displaced to the right or the left, it wouldn’t be as good a result.

Then I know I’ve done my best.

Back to top

Training: Introduction to a series of articles

Undated

What follows this Introduction is the first in a series of instrutional articles about training: specifically, technical training and, even more specifically, training computer programmers.

I’ve been making most of my living as a Ruby and Ruby on Rails trainer for four years. Before that, I spent thirteen years on the faculty of the Department of Communication at Seton Hall University, teaching media history and research to undergraduates. So teaching, in one form or another, has been much of my life story in recent decades.

In 2005 I changed careers: I left the academic world and started to earn my living as a Ruby consultant, author, and trainer. I’d been programming computers since 1972 (with some gaps, but pretty steadily since 1990), and I’d become a Ruby and Ruby on Rails expert. I had a book contract ( Ruby for Rails ). By 2005, computer stuff was exerting a much greater pull on my attention and passion, by then, than my academic work was. I had a sabbatical leave coming up, and little enthusiasm for doing the kind of research that the university would have expected of me. So I resigned at the beginning of my leave, in Fall 2005, and moved on.

I figured I’d finish Ruby for Rails and then get a programming job. I did finish the book, but I never got that job. Instead, I set up a one-man consultancy, Ruby Power and Light, and started taking on short-term contracts—and a lot of training jobs. I trained and trained. In 2006, I traveled to something like twenty-three cities, from California to Sweden, training people in Ruby and Rails.

And it’s continued from there. It’s been an extraordinary four years, and I hope it keeps up.

In this series, I’ll be focusing on the professional/technical training side of things. Even if you’re not a Ruby/Rails trainer, you’ll find points of interest. All of the anecdotes and examples I adduce, however Ruby-specific, carry some kind of general message about the teaching process.

As you’ll learn if you read this series, I’m the kind of teacher who not only teaches but also thinks deeply and widely about the process of teaching, and who likes to share insights. And I don’t draw any kind of sharp line between “teaching” and “training.”

It’s all teaching.

Back to top

"Advancing with Rails" gets off to a fine start!

Undated

I’ve now taught my new course “Advancing with Rails” twice, once in New Jersey and once in Berlin, Germany. It’s gone very well; I think it hits a sweet spot.

The target audience are people who’ve done a good amount of Rails—written apps, read books, quite possibly have things in production—and who have one or more of the following goals:

learn advanced Rails techniques, and how to orchestrate them in an application;

get deeper into Ruby (my motto is: There’s no such thing as an advanced Rails developer who is not also an advanced Ruby programmer)

learn how to advance with Rails.

That last one is subtle, but important. It’s one of the reasons I don’t call the course “Advanced Rails”. Part of the goal is to learn how to adapt to the fact that Rails is in development, growing, a moving target—however you want to put it. It’s not like learning, say, advanced TeX, where you can come up with an unchanging list of “advanced” topics and learn them. Both Rails and Ruby are growing, living things. That’s part of the fun, and part of the challenge.

Advancing with Rails has a definite curriculum, and a definite agenda. At the same time, I like to keep it a bit fluid. Rails courses attract people with very different backgrounds and different starting-points—and if that’s true even for beginner courses (which it is), it’s all the more true for intermediate and advanced ones. Everyone has different questions; everyone has differently developed “Rails muscles”.

As I’ve said at the beginning of both “Advancing” classes: At some point during the course, you’ll hear something that you already knew—but you’ll also hear a lot that you didn’t know, and you’ll get to work with an interesting group of like-minded developers with a lot in common as well as complementary backgrounds.

It certainly keeps it fun for me!

If you’re interested, look on http://www.rubypal.com for upcoming dates (or contact me about on-site training).

Back to top

Training, part 3: Advice on lecturing and topic presentation

Undated

Back to top

The night before

Tue Jun 20 21:32:00 2006

Tomorrow morning I’m off to Chicago for RailsConf, and from Chicago on to Toronto to do some Rails training. So it seemed like a great evening to inaugurate DABlog.

I’ve never been a fan of the term “blog”, so I’m doing an end run around it by naming this log after myself. Anyone who wants to think of it as “Da Blog” may do so, and I get to think of it as the log of David A. Black. So everyone is happy.

Ruby rules in my life, these days. I’m having a great time: training, programming, consulting, and enjoying the first months in the life of my new book, Ruby for Rails: Ruby techniques for Rails developers. And I’m as involved as ever (and then some) with Ruby Central, Inc., the non-profit Ruby support organization that produces RubyConf and RailsConf, and of which I am a founder and director.

It’s a great feeling to have such a full plate and to have it all be connected with something I love so much.

The Ruby/Rails convergence in Chicago this week promises to be great (other than the fact that the hotel doesn’t have a reservation for me, but whatever). Look for many reports, all over the place, as the event progresses!

Back to top

Submit!! (a proposal for a RubyConf talk, that is)

Thu Jun 22 07:18:00 2006

We (that’s “we” as in Ruby Central) have opened up the presentation proposal process for RubyConf 2006.

Now we need proposals!

You don’t need to be a Ruby core developer, author, guru, whatever…. We welcome proposals from anyone and everyone who has about 45-50 minutes worth of ideas, code, plans, experiences—anything Ruby-related. And part of that 45-50 minutes can (and even should) be questions and discussion.

So please propose a talk, or contact me if you have questions.

The deadline is June 30, 2006. (That may get flexed a little, but not much.)

Back to top

Modeling many-to-many: I guess I was right the first time....

Sun Jun 25 08:20:00 2006

Last night, David Heinemeier Hansson delivered the final keynote address at RailsConf 2006. He talked about the mapping of HTTP methods (get/post/put/delete) to CRUD operations, and gave us a guided tour of some of the facilities awaiting us in near-future Railses for layering the various CRUD-esque suites of names and actions on top of each other.

I won’t try to encapsulate the whole talk, which I’m sure will be made available (and I’ll make up for my laziness later by trying to find it…).

One thing of particular interest that David talked about was the modeling of many-to-many associations; that is, representing the associations themselves as models, rather than just as two-key records. This is familiar to users of recent Rails releases in the form of things like:

class Section < ActiveRecord::Base has_many :enrollments has_many :students, :through => "enrollments"

where you’ve also got:

class Enrollment < ActiveRecord;:Base belongs_to :student belongs_to :section

and Enrollment may have all sorts of attributes of its own, beyond the two foreign keys. David’s chief point about this was that having an actual model for the convergence of two other models makes it much easier not to overload the two original models with namespace functionality and asymmetrical, lop-sided operations.

So if you have an Enrollment entity, you don’t have to do things like:

class StudentController < ApplicationController def enroll_in

or

class SectionController < ApplicationController def enroll_student

Instead, you have:

class EnrollmentController < ApplicationController def create

In other words, you fall back on vanilla CRUD. In fact, the way David presented it was almost the other way around: by sticking to the tenet that (almost) everything you want to do can be represented by CRUD operations, and experimenting with keeping that principle as an invariant, you’re forced to come up with new ways of doing things that are actually better than what you might have done before.

But wait…. Are these ways so new?

My first Rails application was a simple message-board tool, for private student/teacher communication. I had to grapple with the question of how to model messages. To whom did a message belong? Sender? Receiver? Student? Teacher? Which controller should deal with creating and updating messages?

The solution I hit on was very similar to the kinds of things DHH was talking about last night: a Correspondence model. A Correspondence belongs to a sender and a receiver. It also has many messages, and has (or has room for) as much further embellishment as one wants.

I didn’t have :through, of course (this was in 2004), but it wasn’t too hard to navigate through the tables and find what I needed. Nor did this solve all the design problems…. There was still the matter of mapping the sender/receiver roles to the teacher/student roles, and dealing with certain asymmetries in that realm while trying to make everyone a User object.

In any case, it’s kind of gratifying to see Rails conventions moving in something very like the direction I took on my first Rails app. Mind you, Rails was perfectly capable of accomodating this model from day 1; it’s not that I came up with some non-Railsy way of modeling that Rails later realized was OK. Still—it’s nice to see it all becoming more and more established and doable.

Back to top

The agony and the ectasy (of RubyConf proposals, that is)

Sat Jul 1 09:16:00 2006

Wearing my Ruby Central director’s hat:

We’ve received a record-smashing 73 talk proposals for RubyConf 2006. That’s more than twice the number we got last year—and last year was about double the previous high.

It’s absolutely great to see all the interesting work that’s being done. I’m feeling buzzed and inspired in a way I usual am after RubyConf.

It’s also agonizing to have to select not much more than a handful of talks. We’ll do it, and the program will be great, but it’s not easy.

RubyConf is a gem of a conference: small (not tiny, but small compared to many), one-track, intense, fun, collegial, coherent, unified. We want it to stay that way; it’s an event many people look forward to and treasure.

The fact that we’ve received 73 proposals doesn’t change that—but it does set us the challenge, as an organization, of looking for more and more ways to get the community together and to let people know what others are doing.

Back to top

Why I am conservative about changes to Ruby

Sat Jul 1 12:18:00 2006

I have a probably well-deserved reputation for being conservative about changes to Ruby. I’ve even been accused of wanting to kill Ruby (or thinking it should be dead, or some other subtle variant of the charge) because I’ve opposed this or that idea.

I am conservative about changes to Ruby—not because I think Ruby in five years should be exactly the same as Ruby today, but because I think the number of changes Ruby needs is tiny, compared with the number of suggestions that are made.

The biggest question I have about future versions of Ruby is…

Have we reached the non-line-noise saturation point?

Why is this? Didn’t a lot of us take to Ruby in large part because it didn’t $look(&:like) -> @@this;; ?

I’ve started wondering whether maybe Ruby has reached a saturation point, where all that can be done without excessive line noise has been done. Maybe if we want Ruby to stay clean, we simply can’t have every imaginable possible nuance of scope, namespace, symbolic reference, and and left-to-right logic forking. Maybe it’s a choice.

That’s fine with me. I’m not big on looking at Ruby as a “Swiss-army chainsaw”, the way people look at Perl. I’m happy looking at it as the kind of blender that master chefs like to use: three or four speeds, rather than fifteen or twenty. You can do anything with it, if you know what you’re doing.

I trust Matz not to turn Ruby into a bunch of uppercase numbers. (The -> lambda arrow has been dropped from the development branch, which is great news.) Assuming he doesn’t, I think it will be because he doesn’t introduce a lot of the changes being contemplated, not because they don’t use punctuation. A lot of them do. I think that may be a sign of the saturation point I’m talking about.

If I’m right, I hope we’ll just live without some of the language-level special-case handling.

Back to top

10/10 review of Ruby for Rails on Slashdot

Wed Jul 12 17:35:00 2006

My book Ruby for Rails was very favorably reviewed today on Slashdot. The review ends:

This is a great book, that’s very easy and enjoyable to read. It’s a stunningly well written explanation of real-world Ruby skills for Rails development

The reviewer, Simon P. Chappell, really gets the fact that this is a Ruby-skills book for Rails practitioners—as opposed to a full-blown Rails guide or a full Ruby reference work. When I conceived and wrote the book, I knew I was creating a whole book category, not just writing a book in a category. And it’s great to see that effort understood and appreciated.

I believe this review will help spread the word about what the book is trying to do. And, in turn, it will be more widely read, and its goal of raising the level of Ruby mastery among Rails developers will be increasingly met! Win-win!

Back to top

The laptop stratum: thoughts from (half of) OSCON

Thu Jul 27 10:25:00 2006

I’ve been here in Portland since Saturday, which means I got here early for OSCON (happened to be traveling in this part of the country anyway), and I’m leaving today, which is a couple of days early (have to do stuff back home and then come back to the West Coast next week).

It’s been interesting and fun. I’ve hung out a lot with many of my fellow Rubyists, including Pat Eyler, Jim Weirich, the Prags, and Phil Tomson; surreptitiously (or otherwise) watched people leaf through my book at the Powell’s Bookstore table in the conference venue; had dinner on Saturday with conference organizer Nat Torkington and a couple of his friends; went to FOSCON last night; and generally had a great time.

Jim Weirich and I were talking yesterday about the culture(s) of the event, and of the various communities that make it up. There’s certainly a lot of potential interest to social scientists and analysts.

One thing I find particularly intriguing is the undercurrent of laptop use, especially during the presentations themselves. This isn’t school, so I’m not out to stop people from doing it (as I was during my professorial days; I didn’t allow laptops in the classroom at all). What interests me about it is wondering what’s actually getting done. People talk at OSCON and other conferences about synergy, networking, and all the rest of it—and I have a suspicion that a lot of this goes on in laptop sessions during talks. But when it takes that form, it’s not celebrated. It’s accepted (or at least tolerated) as a corollary of the existence of laptops. But it’s actually a bit taboo, I think, to make too much of it.

I wonder…. I remember starting to learn Rails by sitting at a conference talk and conducting a private chat session with David Heinemeier Hansson, who was sitting one row behind me and coaching me through the rudiments of the MVC architecture. That was a real and substantive moment in my development as a developer. I wonder what else is going on. I have a feeling the laptop stratum is at least as rich as the “BOF” sessions and acts of hallway networking, when it comes to personal and community growth.

Back to top

Regional Ruby Conference grants from Ruby Central

Fri Jul 28 13:09:00 2006

Ruby Central, Inc., parent organization of RubyConf and RailsConf, has announced the 2006 Regional Conference Grant Program. Ruby users groups can get grants of up to $1500 for expenses connected with putting on a regional conference.

It’s a timely program (if I say so myself, being one of the people behind it). RubyConf is a gem of a conference, and we want to keep it that way—but that also means it can’t be all conference-related things to all conference-going people.

We’re aiming to become Ruby Centrifugal. (Not literally, but metaphorically.) A distributed effort makes sense.

So if you’re involved in a Ruby users group - or even if you’re not, but feel motivated to try to put on an event - have a look at the guidelines (link above) and let me know what you think (dblack@rubypal.com).

Back to top

Special offer for Ruby users groups, from Ruby Power and Light

Sat Jul 29 12:25:00 2006

My consultancy, Ruby Power and Light, LLC, has an offer going, whereby a local Ruby users group can fly me in, have me talk at their meeting, and arrange a Ruby and/or Rails workshop (non-free) to be taught by me, to offset the expenses.

Details at Ruby Power and Light.

Back to top

Thu Aug 10 20:07:14 2006

Sigh—I have to suspend comments, at least for now, because of spam. If it becomes possible to resume them at some point, I will.

Back to top

No, really: my book is Ruby for Rails!!

Sat Aug 12 12:14:46 2006

I got the weirdest review over on Amazon.

The reviewer gave my book one star out of five—which I can live with (though I was fond of the half star in my four-and-a-half, and now I’m down to just four). Along with the one star was a review, the gist of which was that the reviewer had only read a few chapters, because he (or she; I’ll say he) realized my book wasn’t what he’d been looking for.

Specifically, my book bums this person out because it isn’t a step-by-step guide to Rails application development for people already familiar with other MVC frameworks. That’s what this reader had hoped it would be - based on what, I can’t say (he says he didn’t read the earlier Amazon reviews, and apparently didn’t read the title either…) - and apparently his having been wrong about the content of my book is, in his view, grounds for giving the book one star.

It’s weird when someone gets mad at you because you didn’t write a particular book. It would actually be easier to deal with disgruntlement at what my book is, rather than what it isn’t.

The reviewer does take the time to say that the book is verbose and rambling. The main example of this is my discussion of command-line switches for the Ruby interpreter.

But I want to talk at some length about command-line switches. If I had written the hypothetical Rails instruction manual that this person thinks I should have written, then perhaps that section would not have pulled its weight. But in my book - my book, not some imaginary replacement for my book - it actually makes sense to include it.

The bottom line is:

If you are involved in Rails development and want to learn more about the Ruby programming language - principally, but not exclusively, to help you understand Rails better and write better Rails applications - read my book! If you’re not sure, you can get some sample chapters at the book’s website at Manning.

And it’s been said that Ruby for Rails is a great Ruby intro, whether you’re interested in Rails or not. Far be it from me to take exception to people’s judgments….

Back to top

Home from the Michigan Ruby Conference

Sun Aug 27 15:23:00 2006

“Home” is an exaggeration; I’m actually in the Grand Rapids airport.

The Michigan conference was very successful. There were about 65 people there. It was a one-track event, with three talks in the morning and six in the afternoon—a demanding but very rewarding day.

Congrats to Zach Dennis and the rest of the organizers for putting together an exemplary regional ruby conference!

Which reminds me….

You (dear reader) should consider putting together a regional Ruby conference where you live, and apply for a Ruby Central Regional Conference Grant to help with expenses. I won’t say it isn’t a lot of work to put on even a small conference, but it’s definite doable, and it’s a way to do something really cool and constructive.

Keep in mind that the Regional Conference Grants are only intended to offset out-of-pocket net expenses for the organizers. That means that if you get sponsorship, the maximum possible amount of the grant goes down, possibly to zero. Still—if a conference takes place, that can’t be bad!

Back to top

Free Rails workshop in Malmo, Sweden!

Mon Sep 11 10:29:00 2006

I’m going to be conducting a free (but limited enrollment) Ruby on Rails workshop in Malmo, Sweden, on September 17th.

Details the Polar Rose website.

Back to top

RailsConf Europe and beyond....

Mon Sep 18 05:08:00 2006

As you may already know, the first RailsConf Europe was a big success. Ruby Central had the easy job: we were in on the planning at a fairly general level, and we chose the talks. Credit for actually arranging and running the even goes to Wendy Devolder and her team at Skills Matter, the London-based training company that teamed up with us for this event.

I didn’t go to as many talks as I would have liked to, as I was doing event-related things much of the time; but I went to all the keynotes and enough sessions to be very impressed. I was also taking mental notes on the fact that the keynotes, which were attended by about 300 people, didn’t feel like they were mobbed or overcrowded. This has a bearing on my thoughts about the upcoming RubyConf 2006, which is going to have upward of 300 people in attendance and one track.

I’m now in Copenhagen, having given a Rails workshop in Malmo, Sweden, yesterday. The workshop, hosted by Polar Rose, went very well. Afterwards I checked into my hotel in Copenhagen; and as I was getting in to the elevator, I heard a voice call, “David!” Usually it’s safe to ignore that, in cities where you don’t know anyone, since it probably isn’t you—but in this case it was me, and the person calling me was David Heinemeier Hansson. He’s staying at the same hotel, it turned out.

And I, and I think also DHH, will be going to tomorrow evening’s meeting of the Copenhagen Ruby Brigade, which I’m looking forward to a lot.

Back to top

Dinner for three

Sun Sep 24 12:03:33 2006

Now this was fun.

In London, the past Wednesday evening, I had dinner with two old friends: writer and critic Nicolette Jones and literature scholar-turned-banker Gurdon Wattles.

I met Nicolette in 1981, when I was a senior at Yale and she had come over to do a year at Yale as part of her graduate work in English at Oxford. So we’ve known each other for about 25 years. Nicolette and her family are among the friends I spend the most time with in London; indeed, I’ve spent more time with them over the years than with any number of my friends who live in, say, New York, less than fifty miles from me.

Gurdon I’ve known for forty years. We met when we were seven. My family was living in Cambridge, England, for several months, and I was going to school there. Gurdon and I became best mates at school. Over the years we’ve seen each other, either with our families or on our own, only three or four times, the most recent being in 1988. It’s only in the past few weeks that we’d been back in touch at all.

Here’s the funny thing, though: Nicolette and Gurdon, quite independently of me, have been good friends since their university days back in the late seventies or so. How did we figure out that we all knew each other? It was back in 1982, in the Spring of the year that Nicolette spent at Yale. She and I were sitting across from each other at a table in a student dining hall, and she was writing a postcard. Postcards are fair game, right? So I glanced at it, and saw that it was addressed to my old friend from Cambridge, Gurdon Wattles. That broke the ice, you may be sure.

Now it’s 2006, and the three of us were together in one place for the first time. And it was really fun. A long time in the making, and an absolute delight. More of the same to follow, I hope!

Back to top

Have fun (without me) at RubyConf!

Wed Sep 27 15:55:02 2006

I’m going to miss RubyConf, for the first time ever.

This is happening for two reasons. The second reason erases the first—that is, it would be sufficient in itself.

The first reason is, or was, that I accidentally scheduled a training course in conflict with the first day of RubyConf. That was just dumb—though I’m happy to be doing the course, which is a 4-day Ruby/Rails intro in Alexandria, VA>

The second reason is that a dear friend of mine is having her 80th birthday party on October 21, the second day of RubyCOnf. So that pretty much takes me out of the picture.

It feels weird to miss a RubyConf. I’m one of only seven people who have been to all of them. Even Matz has missed one. (He had a good excuse: his wife was about to have a baby.)

But it’s definitely in a good cause. And you’ll all be very well looked after, as always, by Chad, Rich, and the hotel staff.

Back to top

[Postponed] One-day Rails intro workshop in Toronto, December 15

Sun Nov 19 16:34:22 2006

[This event got postponed, hopefully to take place in Spring 2007.]

I’m going to be conducting a one-day Rails workshop in Toronto on December 15. It will be an introduction to Ruby language essentials and the Ruby on Rails framework.

Topics will include:

Ruby language basics

Rails application creation and startup

â€œRails-friendlyâ€ database design

HTML templating for Rails views

templating for Rails views Data validation, testing, Ajax basics, and more

The cost is $375 (Canadian). More information and registration here..

Back to top

More A than R: reconsidering the "new" AR object

Sat Dec 23 08:57:00 2006

I’ve been noticing that this is becoming a common controller idiom:

def new @person = Person.new end

Of course it’s for the sake of the view—specifically, for the benefit of simply_helpful, which lets you do:

<% form_for(@person) ... %>

and will create the right form for you, with the right HTTP method, based on whether @person is a new record or an existing one.

That “new” method, though, bothered me the first time I saw it, and it still does. What I don’t like about it is that it creates a new Person object, while having no intention whatever of saving that object.

Of course there’s no rule that says you have to save AR instances. But doing Person.new just so that you have an object that can answer a couple of questions about itself is overkill. Seeing that code gives me the same feeling I get when I see global variables (or even instance variables) used where a local variable would do. It works, but it’s a loose fit.

It reminds me of, say, walking into a health club and buying a membership so that you can go inside and use their bathroom once. The membership system is in place, and it will serve that purpose, but it wasn’t put in place for that purpose and it’s manifestly a kind of better-than-nothing solution to the problem being solved.

What we’ve got, I think, is the tail (the view) wagging the dog (the controller) a bit too much. I have no problem with the underlying idea of having the form creation be intelligent, but I’m not comfortable with this idiom for doing it.

I’m also willing to bet that someone—a lot of people, I would guess—see this:

@person = Person.new

and have trouble getting a handle on the fact that this has nothing whatever to do with the fact that, at the end of the whole process (new plus create), a new Person will have been created. It’s almost like this new Person is pretending to be THE new Person.

So, what are some alternatives?

I started out by thinking about flipping the whole thing so that the instance variable was no longer at the heart of it. (The docs for form_for do say, after all, “The big news is that form_for allows us to more easily escape the instance variable convention” :-) I ended up kind of reinventing what already exists. Also, Dave Goodlad pointed out that a benefit of querying an actual Person object, even a new one, is that you can pick up default values for attributes (at least those defined via overrides in the model).

My next thought—and this is what I currently favor—is to add a “proto” constructor to ActiveRecord. So instead of Person.new, you would do:

@person = Person.proto

The proto-person would essentially be an unsaveable Person object. Its reason for existence would be exactly the use to which you’re going to put it. When I see Person.new in this context, I always think: this is here because there’s no good way to do this, and creating a new instance is the closest thing available. My reaction to that is: if we’re going to be using a lot of AR objects that are more A than R, let’s design that into the system. The “proto” constructor would be a way to do that.

I also consider it more in keeping with the somewhat anomalous position of the “new” action in the RESTful context. new serves as a kind of table-setter for create. The main event hasn’t started yet; this is just a preliminary step. Viewing it in that context, I think the somewhat anomalous nature of the proto-Person is in fact exactly right.

Criticisms include:

Get a life :-)

No one’s going to accidentally save the object, so .new is OK.

Another constructor is potentially just clutter.

I disagree with all of them, obviously, but I thought I’d list them just to indicate I’m aware of them.

Back to top

Enough already with freaking out over people's sex

Wed Jan 3 19:30:58 2007

Just spotted on the on-screen program guide for Cablevision: “When a female Secret Service agent is killed, detectives investigate clients of her husband, a well-connected lobbyist.”

Years ago, there was a kind of riddle or puzzle in circulation—something to the effect of:

A father and son are in a car crash. They’re taken to the hospital. The doctor comes into the room, looks at the boy in the bed, and exclaims, “My son!” How can this happen?

I’d like to think that that riddle is obsolete. But I wonder. Apparently television blurb writers still feel the need to specify that a character is a female Secret Service agent, not just a Secret Service agent, even though reference is made to “her husband” in the same sentence.

I can understand alluding to a character’s sex—or ethnicity, age, sexual preference—if it’s materially relevant to the plot. The dramas of our culture involve these things, and there’s no reason that dramatic representations can or should be expected not to revolve around them. If an episode of a show is about child pornographers, I don’t expect the description not to mention children. If it’s about a serial murderer of gays, I don’t expect the description to be poker-faced on the matter of who the victims are.

So there are cases where the issue is the message, so to speak.

I don’t know, because I haven’t seen it, but I suspect the “female Secret Service agent” episode isn’t one of them. But just for the sake of argument, let’s say it is. That still leaves the question: what the hell could the “her” in “her husband” mean, except that the agent is female? Even if the plot does hinge specifically on the femaleness of the agent, “her” conveys that femaleness completely and unambiguously. There is literally no possible reason for the presence of the word “female” in that blurb.

I dislike the implication that it’s unacceptable to keep the femaleness of a Secret Service agent unrevealed even for a handful of words. That’s no good. If people find themselves thinking it must be a man and then revising their view later in the sentence, so be it. They should have to do that, if they assume that “Secret Service agent” means male agent, or that “teacher” means white teacher, or that “man” means heterosexual man.

Enough already with these regressive habits.

Back to top

Will trade Ruby/Rails tutoring for website design work!

Wed Jan 3 20:35:39 2007

Update

I’ve come to an agreement with someone. Thanks to those of you who offered your services. I hope I’ll meet up with many of you around Ruby/Rails-space.

(Old announcement)

I’d like to trade hours of Ruby/Rails tutoring, at any level, for hours of website design work, on a 1-to-1 hour ratio. I’m envisioning something in the 3-5 hour range on both sides.

If you’re interested, let me know. I do have some requirements and expectations (like that all pages will validate—I’m not sure my current ones do, but if they don’t that’s something I want to fix and not be complacent about—and that things are visually interesting but not oversaturated and all info is as accessible as possible). But I’m also ready to look at real designs and not just impose my own somewhat limited design imagination on the project.

Please email me at dblack at wobblini dot net if interested in chatting about the possibility.

Back to top

Meta, shmeta: learning Ruby horizontally

Sun Jan 7 10:20:49 2007

One of the great accomplishments of Ruby is that its object and class model bring about a wonderful unity and simplicity. Even things that might seem like they should be hard or obscure are actually very transparent, once you have the hang of how the model works.

Unfortunately, there’s a trend toward drawing an increasingly sharp line between regular programming and “metaprogramming” in Ruby discussions, where metaprogramming is understood to mean… well, I’m not sure what it’s understood to mean, the way it’s getting used in connection with Ruby, and that’s the problem.

There’s no natural separation between programming and metaprogramming in Ruby, and no reason to make life harder by breaking them apart. The thrust of Ruby’s design is to dissolve complexities, so that even things that appear to be “wizardly” or full of “dark magic” actually make perfect sense in terms of a relative small number of underlying language principles.

I’m not saying it’s all a snap to learn. But I do consider it counterproductive to posit some kind of special barrier or fortification surrounding a particular set of Ruby programming techniques. Learning Ruby isn’t like scaling a mountain. It’s more like exploring a plain, with interesting features and a distant but very attractive horizon. One thing leads to another, but not in a way that requires you to fight gravity to get there.

Horizontal learning: class_eval and class

You can get a feel for this horizontal, energy-efficient way of learning Ruby by looking at pairs of closely-related techniques, where one is the kind of thing you learn on the first day of studying Ruby and the other…isn’t.

A good example of such a pair is the class keyword and the class_eval method. class_eval often comes up as an example of a metaprogramming technique, and therefore as something obscure and difficult and wizardly. It isn’t. Let’s probe it systematically, and in context.

We’ll start with the class keyword, one of the bread-and-butter techniques of Ruby—the basic:

class MyClass # stuff end

Certain things happen when you start a class definition block:

you start a new local scope

the special object self is the class object itself

is the class object itself any methods you define with the def keyword are instance methods of the class

All of this is easily visible and verifiable. Here’s a little testbed:

# Just for demo, we'll create a local variable in the # outer scope. x = 1 # Now the class definition block. class Teacher # Examine the value of self puts self # Try to examine the local variable x -- but it will # raise an exception, because we're in a new local scope # (so we rescue the exception). puts x rescue puts "x is from a different scope!" # Define some instance methods. def initialize(name) @name = name end def name @name end end # Run some demo code. t = Teacher.new("David") puts t.name

The output from this little program is:

Teacher x is from a different scope! David

Everything works as expected.

Now, let’s look at class_eval .

class_eval is a method, rather than a keyword. You don’t do this:

class_eval Teacher # No!

Rather, you call it as a method, and give it a code block:

Teacher.class_eval do # code block! end

Now, rather than get all panicked about how this is “metaprogramming”, let’s look at what’s actually happening, and why.

As we’ve seen, the class keyword ( class Teacher ) brings about certain conditions involving self , scope, and the effect of defining methods. So let’s use the same criteria to examine what happens with class_eval :

y = 1 Teacher.class_eval do puts self puts y rescue "y is from a different scope!" def subject "History" end end t = Teacher.new("David") puts "#{t.name} teaches #{t.subject}."

(We’ve got all teachers teaching history, but we’ll live with that for the sake of the demo.)

When you run this code, you get:

Teacher 1 David teaches History.

What does this tell us? It tells us that when you use class_eval :

you do NOT start a new local scope; you’re in the same one

start a new local scope; you’re in the same one the special object self is the class object itself

is the class object itself any methods you define with the def keyword are instance methods of the class

Consequently, you now know that if you want to add instance methods to a class while still retaining access to local variables in the outer scope, you should use class_eval . If you don’t need those local variables, you can use the class keyword.

There’s a little more to it….

There are of course more differences between class and class_eval (including the fact that class_eval can operate on a string as well as a code block, and that it’s very handy for anonymous classes). But note that as we study class_eval , we’re not in a different universe, or higher up a mountain and running out of air. We’re actually still playing in the same ballpark we were playing in when we looked at the class keyword.

The relation between class and class_eval , from the point of view of someone interested in using them, is a horizontal, lateral relation. You hold one technique in one hand, and the other in the other hand, and you heft them and compare them and decide what you want to do. Nothing is gained by putting class_eval on a pedestal and getting all worked up about how “meta” it is. All you have to do is study it a little and then use it when it’s the correct choice for accomplishing what you’re trying to accomplish.

Back to top

Emerging Tech conference coming up

Wed Feb 7 10:26:37 2007

I’m going to be speaking at the Emerging Technologies conference in Philadelphia. The conference is being held March 28-29, at Drexel University, and is produced by Chariot Solutions.

I’ll be speaking on Rails routing, a topic that’s becoming dear to my heart as I”m working on some materials on it for publication, and also giving a tutorial on it at RailsConf 2007.

Back to top

The Magic Pens of Ruby

Sun Feb 18 14:01:00 2007

I’ve recently found myself describing single objects yielded by iterators as “magic pens.” Though it may sound more psychodelic than technical, it’s actually proven to be a good way to explain these objects and give people a feel for why an iterator would only yield one object in the first place.

I don’t mean cases where you iterate through a collection that happens to have only one element. I mean methods that, by design, yield one and only one object, every time they’re run.

create_table do |t| t.column :first_name, :string t.column :last_name, :string end

The create_table method is being supplied with a block, so it’s an iterator. (Ask any method: iterator? and it will tell you true if you’ve given it a block, even if it never yields to it.) But what is it iterating over, or through? How many times? Once? Why bother iterating, then? Why not just call a method and use the return value?

t = create_table t.column :first_name, :string t.column :last_name, :string

The answer—the admittedly very high-level answer, but the one I’ve found most effective in nailing into place exactly what’s going on—is that create_table works by handing you a magic pen. The pen has magic only for the duration of the code block. While you have the magic pen, you use it to do things you wouldn’t normally do, like bring about changes in your database tables and columns. (Not the records (though those too, if you wish): the tables and columns themselves.)

The magic pen idiom is very elegant, for at least two reasons.

First, it throws the spotlight on what you’re doing. The delimitation of the code block, during which you have the pen, puts the specialness of the process in high relief. You have to get the pen to do what it needs to, all in one place and time. (You might say that the code block is itself a magic “pen”—that is, a magic enclosure….)

Second, the magic pen idiom saves you trouble. Think about the method that hands you the pen. At some point, it has to yield to your code block. But before and after it yields, it can do any amount of set up and tear down—which, consequently, you don’t have to worry about.

Let’s look at an illustration of this second point up close.

Inside a magic pen

The magic pen you get from create_table is actually an instance of the class TableDefinition. You can see exactly how create_table hands you the magic pen if you look at the source code for the first segment of the method create_table, which is in schema_statements.rb (comments added):

def create_table(name, options = {}) table_definition = TableDefinition.new(self) table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false yield table_definition # You get the magic pen!

The yield triggers execution of your code block, and the local variable t is assigned to the TableDefinition object that’s been yielded. You need this object because it’s the one that has a “column” method. And it’s your magic pen.

The magic itself (the process of changing the database) happens back in create_table, after your code block ends. Here’s the rest of create_table:

if options[:force] drop_table(name, options) rescue nil end create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE " create_sql << "#{name} (" create_sql << table_definition.to_sql create_sql << ") #{options[:options]}" execute create_sql end

The routing magic pen

While we’re on the subject of magic pens in Rails: you also get a magic pen to help you write your application’s routing rules. Here’s the default config/routes.rb file, minus comments:

ActionController::Routing::Routes.draw do |map| map.connect ':controller/service.wsdl', :action => 'wsdl' map.connect ':controller/:action/:id.:format' map.connect ':controller/:action/:id' end

The magic pen is “map”, which is a Mapper object. It’s by handling this object that you bring about changes in the routing tables. Like the migration magic pen, the routing magic pen is yours only for a time. But during that time, it gives you a lot of power. When you write named routes and resource routes, you see even more of the power:

# Create a method called profile_url that generates a URL # of the form profile/id which is bound to the user/show # action: map.profile 'profile/:id', :controller => "user", :action => "show" # Generate a full complement of RESTful routes and associated # URL generation methods for the accounts resource: map.resources :accounts

This magic pen has a lot of ink in it.

Last but not least, let’s look at the extremely useful filehandle magic pen in Ruby.

Ruby’s filehandle magic pen

You can, if you wish, deal with file-writing procedurally, like this:

fh = File.open("myfile", "w") fh.puts "Content of file!" fh.close

And in this scenario, you do indeed get a magic pen. But it’s not very dignified for the magician to have to sweep the stage after the show—as in fh.close. Doing it the magic pen way has the effect of making Ruby do the housekeeping:

File.open("myfile", "w") do |fh| fh.puts "Content of file!" end

The open method yields a filehandle. Then, after the code block finishes, control returns to the method, where the filehandle gets closed for you. You don’t have to worry about it.

The magic pen idiom distills the magic into the pen, by offloading the housekeeping onto the method that yields the pen in the first place (create_table, draw, open). Conversely, the fact that Ruby makes this kind of offloading so easy is what makes magic pen scenarios so easy.

So when you see an iterator, don’t assume it’s handling a collection. It may just be setting up a magic pen experience for you.

Back to top

Sudoku solutions: who cares?

Sun Feb 25 23:47:00 2007

I’m a sort of mediocre good sudoku solver—flashes of brilliance, too lazy to bother writing in all the possible values of each field so not in the running to solve a lot of the harder puzzles. But I enjoy them, and I go through phases of doing them quite a bit.

I also do crosswords—specifically, British-style cryptic crosswords. I’m quite good at those. I rarely finish one completely, but I still consider myself good at them because I often come within, say, two or three clues of finishing. And if the answer is something I’ve never heard of, I give myself partial credit, so to speak.

It’s actually the answers that I’ve been thinking about: the answers to crossword clues, and the answers to Sudoku.

When you work on a crossword clue, there’s a very specific goal for that clue. Clues can be fun, even in isolation. You can work on a crossword puzzle with someone else, even someone who can’t see the puzzle; you just give them a clue, and tell them how many letters you’ve already got, and they can work on it.

Sudoku are different. You can’t really say to your friend, “I’ve got a square that’s missing 2,8, and 9. The blank boxes are the center, the top right, and the middle left” and expect your friend to come up with a solution.

And after you’ve worked on a crossword puzzle – more to the point, after you’ve given up – you want to see the solution. When you see the answers to the clues you didn’t get, you may feel stupid or you may feel vindicated (if you decide the clue was bad, or the answer was something you truly never would have been able to come up with).

That’s where I wonder about Sudoku. You always get the solutions in the back of Sudoku books, or published the next day in the newspaper. But why, exactly? I can’t imagine working on a Sudoku, failing to complete it, and then looking at the third box from the left in the middle row of squares and saying, “Oh, of course! Seven!” The individual squares just don’t have the same relation to their answers that crossword clues have to theirs.

Another kind of weird thing about the solutions to Sudoku is that, at least if you put yourself in the right frame of mind, seeing them doesn’t matter. If I set out to solve a Sudoku rigorously – with no guessing, never filling in a box until I’m sure about it – having access to the solution doesn’t really make my job any easier.

What all of this amounts to is, I think, that the culture of puzzle publication dictates that solutions accompany puzzles, but not too closely (at the back of the book, or a day later), even though this way of doing it is a rather odd fit, in some respects, for Sudoku. No harm done, of course. I just find it kind of funny.

Back to top

DABlog now using Mephisto

Sun Feb 25 23:52:00 2007

I’ve switched DABlog over to Mephisto, a publishing system that’s become a very popular blog engine. Mephisto is by Rick Olson and Justin Palmer.

The switch is smooth so far (thanks for the help on IRC, Rick :-) and I’ve also added a FeedBurner feed. Today is also the day I started using gmail, having been a Pine aficianado for years and years. A big transition day.

Back to top

Rails training by Ruby Power and Light!

Tue Mar 27 14:43:00 2007

Back to top

The L in DSL: langue ou langage?

Tue Apr 17 18:19:00 2007

In 1964, the great film theorist Christian Metz published a seminal essay called, “Le Cinéma: langue ou langage?” The basic idea was this. Movies obviously communicate something. So they’re evidently tapping into the human capacity for understanding symbolic representation—essentially, language. But does that mean that there is a film language, with its own precise rules, the way there is English or French? Or does it mean, rather, that film participates in the process of communicating in a language-like way, but not according to one particular set of rules?

Metz’s view was that it was the latter. Film communicates through language-like means (symbolic representation, piecing shots and scenes together like phrases to create meaning), but there’s no one-and-only language called Film. Different films can do it differently, and different audiences (depending on when and where they learn to become “film literate”) have different ways of interpreting the content and editing patterns of films.

Thus one may say that film is langage (language-like communication), but it is not une langue (a particular language).

It strikes me that this goes to the heart of the L in DSL.

DSLs a-go-go

The concept of the Domain Specific Language (DSL) has been in heavy rotation in recent times in the Ruby and Rails worlds, and for good reason. Ruby provides a very hospitable environment for little idiom sets that, with little effort, can be coaxed into looking like pseudo-code or configuration syntax, and therefore can help greatly in allowing non-programmers to understand what’s going on.

Thus, for example, you might come up with something that allows you to do this:

with Employee "123-45-6789" do dock_salary 1000 warn_about :misconduct end

and you can be fairly optimistic that, with minimal coaching, you can get most people to understand it.

This kind of thing is extremely useful. I wonder, though, whether it always deserves to be called a Domain Specific Language. It seems to me that the term DSL has become a bit over-burdened. It sometimes feels like any snippet of code that uses a block and includes one or more well-named methods ends up getting called a DSL.

In the grand scheme of things it doesn’t really matter if someone happens to call a snippet of code a language, domain specific or otherwise. But I do think that the horizon of DSL expectation in Ruby has shrunk a little bit. If DSL means having a method called warn_about that doesn’t need an explicit receiver (and, by the way, I myself dislike the magic instance_eval trick that allows this; but that’s another story), then we don’t really have a name for full-blown, semantically rich, domain-specific languages written in Ruby.

What the ‘ell?

It’s a bit curmudgeonly, though, to lobby for people to stop using a term they find appropriate for their code. So I haven’t. But this morning I thought of another way to see the whole thing.

This:

with Employee "123-45-6789" do dock_salary 1000 warn_about :misconduct end

is not a domain specific language. It is, rather, domain specific language. Note the lack of the “a”. It’s domain specific, and it uses language-like constructs. But it isn’t a language. It’s Ruby, using expressive method names and cushy semantics and therefore facilitating the use of domain specific idioms.

In other words, I suggest that when people say they have created a DSL, they might more precisely say that they have used DSL. They have not created une langue, but they have made use of a particular aspect of langage.

Anyway, that’s how I’ve come to see it. I hope the late, great Metz would have approved.

Back to top

Tough love from Verizon

Mon May 14 12:57:00 2007

I don’t think you have to be a language snob to wince (and laugh) at the way advertisers misuse English. They’re protected, of course, by the myths that surround their profession. If they get their grammar wrong, or misuse an idiom, they must have some ingenious marketing reason for doing so—or so people are willing to asusme. In fact, I think what’s happening is that the lousiness of the American educational system is trickling up into the ranks of copy writers and copy editors and basically everyone in the chain of custody of commercials.

The one that got me writing this post is a Verizon radio ad, specifically an ad for Verizon’s phone/cable/Internet triple package. It features the usual fake testimonial sound-bites from actors pretending to be customers. That’s par for the course, until one of them says (and the stuff in square brackets is a paraphrase; the rest is verbatim):

“[Verizon gives you a great deal,] providing all three services and not pulling any punches.“

I love the image of a Verizon repair person coming to my door and slugging me in the jaw, as hard as he or she can. (I’d rather it not happen, but I love the image.) It is, of course, completely clear that the person who wrote that line has no idea what the expression “pulling a punch” actually means, and neither do the executives who paid to have the ad written. I surmise that they think it means “pulling a stunt”, so that not pulling any punches means you’re entirely honest. Or something. Who knows?

I suppose that if Coors can actually bring to market a product called “Artic [sic] Ice”, then Verizon can sleepwalk through the process of producing radio commercials. In fact, it doesn’t surprise me any more. I no longer expect the ostensible gatekeepers to know what they’re doing. They probably never did, but I do think it’s gotten worse. And funnier.

Back to top

Boston Early Music Festival wrapup

Sat Jun 16 23:44:00 2007

I’m in Boston, having just spent four days at the Boston Early Music Festival. My brother Gavin, director of the Princeton Early Keyboard Center, rented an exhibitor’s room—basically a hotel room from which the beds have been removed—where he displayed his oldest harpsichords (one made in London in 1785, one made in Italy in the late 17th century). Visitors to the room were encouraged to play on the instruments, and many did.

It wasn’t just a display, though. Gavin also produced something like fifteen half-hour musical recitals, involving himself, me, and various musical colleagues and friends. The result was that Room 921 at the Radisson was a hot-spot of wonderful performances and presentations. Highlights included:

Baroque music performed by its composer, Grant Colburn (unusual at an early music event!)

John Thompson performing on the qin (pronounced ‘chin’), a Chinese instrument, with Gavin playing clavichord selections to complement the pieces

John Burkhalter discussing the Neff manuscript, a one-of-a-kind handwritten collection of pieces, dating from late 18th century Pennsylvania and belonging to John

Two recitals by the baroque group Col Legno, of which I am a member

And there was more. Room 921 was, as Gavin and I said to each other almost simultaneously when we were discussing it afterwards, a festival within a festival. Congratulations to Gavin for producing these four days of music, and thanks to everyone who participated and everyone who came to hear us.

I also spent a lot of time looking at the exhibit halls, where there were lots of instrument makers and sheet music sellers. There were not as many cellos as I would have liked; in fact, I only saw three. Viols seem to rule at this event, and the violin family is mainly represented by the smaller instruments. I guess it’s understandable, since the makers have to lug the instruments to the festival… but I still would have liked to have seem more baroque cellos. There were a lot of bowmakers on hand, though, and that was interesting.

Back to top

The Stupidity Tax

Wed Jul 4 12:47:00 2007

As of this morning, I can't find my London cell phone. Yes I know it sounds pretentious for an American even to have one... but I go to London usually two or three times a year, and you really can't have any kind of social life over there without one. Anyway, I'm at home in the U.S., and I can't find the phone.

That means I will almost certainly have to buy another one, solely because I'm too stupid to have put it away properly last time I got back from London.

I consider the price of the new phone to be a Stupidity Tax payment. I pay several hundred dollars a year in Stupidity Tax. I forget to cancel hotels; I neglect to send in rebate forms; I lose things. I have to say, the losing things thing is very deep-rooted; there's more to that syndrome than stupidity. Still, to the extent that I lose expensive things that should be simple to keep track of, their replacement is Stupidity Tax.

Thinking of all of this as Stupidity Tax actually makes it a little easier to deal with. It's just part of the cost of living. Of course I'd like to reduce it as much as possible. But it's unlikely I'll ever reduce it to zero. Life is too much of a sieve to hope for that. At least I can keep things interesting by rotating the reasons for the tax: a lost item here, a forgotten bill there. I'd like it not to get too interesting... but the Stupidity Tax is here to stay, so I might as well try to adapt to it.

Back to top

Bang methods; or, Danger, Will Rubyist!

Wed Aug 15 11:35:00 2007

In Ruby, you can write methods whose names end in ! (exclamation point or “bang”). There’s a lot of confusion surrounding the matter of when, and why, you would want to do so.

What ! does (and does not) mean

The ! in method names that end with ! means, “This method is dangerous”—or, more precisely, this method is the “dangerous” version of an otherwise equivalent method, with the same name minus the !. “Danger” is relative; the ! doesn’t mean anything at all unless the method name it’s in corresponds to a similar but bang-less method name.

So, for example, gsub! is the dangerous version of gsub . exit! is the dangerous version of exit . flatten! is the dangerous version of flatten . And so forth.

The ! does not mean “This method changes its receiver.” A lot of “dangerous” methods do change their receivers. But some don’t. I repeat: ! does not mean that the method changes its receiver.

Don’t overuse the !

Not every !-method changes its receiver, and not every receiver-changing method ends with !. There’s Array#pop / push / shift / unshift / concat / clear , and lots of others.

Don’t add ! to your destructive (receiver-changing) methods’ names, unless you consider the changing to be “dangerous” and you have a “non-dangerous” equivalent method without the !. If some arbitrary subset of destructive methods end with !, then the whole point of ! gets distorted and diluted, and ! ceases to convey any information whatsoever.

If you want to write a destructive method and you don’t think the name conveys destruction, you might be tempted to add a ! to make it clear. That’s not a good idea. If the name of a destructive method, without a !, does not connote destruction, then the name is wrong and cannot be repaired by slapping a ! on it.

In such a case, you should create the traditional pair of methods: a non-bang method and a bang method. It’s conventional to define the non-bang method in terms of the bang one. Here’s an example involving a simplistic version of an Array#flatten_once method (it doesn’t handle nested objects other than arrays very well, but it makes the bang-point):

class Array def flatten_once! res = [] each do |e| [*e].each {|f| res << f } end replace(res) end def flatten_once dup.flatten_once! end end

The non-bang method is defined in terms of the bang method. You wouldn’t want to write an isolated method called flatten_once! without the matching non-bang version, since there’s no way to measure the “danger” except in relation to the non-dangerous method.

[Aug. 16, comment in response to IRC question from apeiros: you can also define the bang method in terms of the non-bang method, but in the Ruby source code it’s usually done in the direction I’ve done it, and I’ve followed that practice here.]

Danger takes many forms

Sometimes you get more than one kind of “danger” even within one bang method. Take String#gsub! . This method changes its receiver:

str = "David" str.gsub!(/$/, " Black") str # David Black

It also differs from gsub (non-bang) in that if the string does not change, gsub returns a copy of the unchanged string but gsub! returns nil:

str.gsub(/xyz/, "blah") # David Black str.gsub!(/xyz/, "blah") # nil str # David Black

The ! in gsub! gives you a heads-up: it warns you of danger, and that means that before you use the method, you should find out exactly how it behaves. (A simple “ ri String#gsub! ” should do it.)

Forget “intuitive”

It may not be easy or, to use a heavily overworked term, “intuitive” to think of ! as meaning “dangerous”, or to craft your method names so that the !’s make sense in that context. It’s worth it, though. Give Ruby (and Matz) the benefit of the doubt. This use of ! probably does not occur in other languages you’ve used. But it works really well. If you let go of the notion that ! means destructive, and if you think through the naming and pairing of dangerous and non-dangerous methods, you’ll see how valuable a flag the ! can be.

Back to top

Reflections on Wikipedia

Tue Sep 4 12:53:00 2007

I love reading Wikipedia, and I’ve learned a lot from doing so. I’m not, in other words, rabidly anti-Wikipedia. But I do have a few serious concerns about it.

It seems to me that Wikipedia is, in effect whether or not in intent, pushing the Web in exactly the direction it isn’t best suited for: namely, centralization of information. Mailing list posts and IRC channels are full of links to Wikipedia articles, on everything from… well, on lots of things. It seems that the standard way of saying, “If you’re not familiar with the term I just used, here’s how to learn about it” is to provide a Wikipedia link.

I strongly suspect that this is automatic on the part of the people doing it—automatic, that is, rather than based on a thorough search of all the resources available on a given topic and a reasoned decision about which is best-written and/or most informative. That’s the thing: Wikipedia provides something close to one-stop shopping. You’ll find something on almost anything.

Furthermore, Wikipedia itself seems to buy into and cultivate the image of itself as a centralized, objective source of information about everything. One symptom of this is the fact that links within Wikipedia articles are always, or very nearly always, links to other Wikipedia articles. In spite of how open it is, in terms of contributions, it’s ultimately a closed system.

Yes, external sources are indicated at the bottom of articles. But the providing of sou