Friday, July 3, 2009

Jane Eyre and feminism

I read Jane Eyre recently. This was necessary because I'm reading Simon Callow's excellent biography of Orson Welles, and I'd got to the part where Welles appears in that movie. I had to see the movie before reading that section of the biography, and I had to read the book before seeing the movie. So it fit in well with my desire to enjoy some of these famous works as I get on in years. Call it a literary bucket list.

For most of the book, I found myself laughing at Jane and the rest of the characters. It's hard for me to imagine real people speaking and thinking in this way. I'd love to hear how they talk after the collective stick had been removed from their asses.

But at some point, I simply accepted the style, and I enjoyed the book far more. The plot was just as ridiculous, however. Mr Rochester goes from talking about marrying Blanche and sending Jane away to clasping her in his arms in the space of a paragraph or two. I never did understand the reason for or in fact any evidence of a transition in his intent. One sentence Blanche - next sentence Jane. We were all expecting it, of course, but it certainly made no sense.

Then there's the amazing coincidence of the house Jane stumbles upon, which just so happens to contain her nearest relatives. She's apparently half-dead by this time from exposure and hunger, but as near as I can tell, she was only away from a soft bed and a hot meal for about three days. Not very stern stuff, one feels.

But the reason I wanted to make this blog post was to react to the statement in the (modern) introduction that Jane Eyre is "one of the most intensely erotic books in the English language." First, it's good of the writer to concede that there are eroticer books in other languages (too bad she doesn't mention what they are, or I would by all means start a course of study in those languages). Second, what the fuck? It is impossible to imagine Jane even possessing a clitoris, much less any kind of erotic feeling.

The writer of the introduction is from feminist school of the 1980's. I am all for feminist schools. I consider myself a feminist and have done since the age of 12. I am so feminist, in fact, that I know that I'm sexist. But besides being erotic, this novel is, according to the writer of the introduction, a triumph of feminism and female power. How can it be, when all Jane does is serve and obey? True, she twice obeys her God over her male masters, but this is hardly empowerment. Throughout the book, Jane is either a slave or trying to become a slave.

I still enjoyed the book. The character was foreign enough to make her interesting. And I did read on, wondering what would happen next. As for the movie, it was fun to see Orson Welles play Mr Rochester. He certainly played the part in my imagination as I was reading the book.

And now I've moved on past that part in Callow's biography of Welles. Tonight I watch The Lady from Shanghai.

Saturday, June 27, 2009

It's hard to make a game easy

I'm just getting to the end of Prince of Persia. It's considered by gamers to be an easy game - too easy, some say. For me, it's just hard enough to make it rewarding but not so hard as to be frustrating.

The first computer game I ever played was Zork. Now there was a frustrating game. I spent literally hours getting nowhere, simply because I didn't use the right combination of words to get something to happen. That, of course, was the challenge of the game. It was a difficult puzzle to solve. It wasn't particularly fair, either. Logic took a back seat to obscurity sometimes. On the other hand, finding one of those obscure combinations of words was tremendously satisfying.

Another way games like this can be hard is to not permit escape from prior bad choices. You didn't pick up that item in the room you were in three weeks ago (in real time)? Too bad - now you're stuck. You have to go back to that point (if you even have a saved game from then) and do it all over. This is not fun by anyone's definition.

But both kinds of game design are easy for the designer. It's actually quite easy to make a game hard. What's hard is to make it easy.

Which is where Prince of Persia comes in. I don't have a lot of time for gaming. I spend perhaps an hour a day, and a few more on weekends. If I choose to stick out a game to the end, it's because it consistently gives me more fun than doing something else. Prince of Persia does that by having puzzles that are just hard enough to make me think (a little bit, at least), but allowing me the freedom to swing across vines without worrying about painting myself in a corner.

Of course, the game is famous for "not being able to die." If you fall off a ledge or get beaten in combat, your companion Elika saves you and you start again from a checkpoint that's usually not too far before the point when you died. Some would say that this isn't challenging enough - that there's not enough "penalty" for doing something wrong. Good! I don't play games to inflict pain on myself, and I don't like having to repeat a sequence of events over and over until I get it right. (This does happen in Prince of Persia, but it's nothing like one situation I was in in Halo 3, where I would spend at least a minute gathering weapons, spend another couple of minutes killing Brutes, die, lather, rinse, and repeat.)

But easy resurrection is just a part of it. Much harder, it seems to me, is the ability Prince of Persia gives you to follow paths wherever and whenever you want, without fear of being unable to get back to where you are. Although the game is essential a platformer, with narrowly-defined places you can go, there are usually at least two ways to get to every important place.

And doing this without making it obvious takes design skill. I suppose one could win the game merely by trying every path in every combination. But it doesn't seem that way. I really feel like I'm exploring, not just following a script.

Monday, June 22, 2009

Assertion as argument

I saw a thread today in which someone asked whether they should add NilClass#to_s to return an empty string instead of raising an exception.

A well-respected member of the Rails community answered by talking about concatenating strings with +. He said

First off, don't do that. String#+ is generally the worst thing you can choose. Second [...]

I had to wonder whether that member would accept a statement like that himself. Don't we programmers tend to examine assumptions and reject arguments from authority?

What he could have said is "String#+ creates a new string by concatenating its argument, so if you're doing it thousands of times a second, it can create problems because of memory consumption. In ordinary practice, it makes no difference."

Sunday, June 21, 2009

Discovering OOP

Before I'd ever really heard of OOP, I was simulating polymorphism by using dispatch tables in structs. I'd define a struct for a listbox, e.g. This would have members for the size of the list, the width, the position on the screen, etc. There would also be a linked list of the items to display. I'd pass these structs around to functions that operated on them. I believe this was called module-based programming. The data was encapsulated in that only certain functions in a certain source file (or module) were allowed to operate on it. So far, so basic.

But sometimes, I'd want to have different functionality on a single listbox (or on a group of similar listboxes). For example, when the user selected an item, maybe I'd want to display information about that item somewhere else. So I'd define a function that was called by the main listbox code when an item was selected. But this function didn't belong with in the main listbox module, since it might be particular to only one application or even only to one screen. So I added a function pointer to the struct. The main listbox code would call that function if the pointer was nonnull. Different listbox clients could define their own functions to get the behavior they needed, without cluttering up the main listbox module.

This is essentially polymorphism - using indirection to select a function to execute at runtime, based on the inherent "nature" of the struct, rather than its incidental contents. Of course, there could be many such function pointers in the listbox struct. Today, we'd recognize this as a dispatch table, implemented in C++ to support virtual functions. But this was 1985, and I'd never heard of C++ or polymorphism. I just knew that I wanted to paramaterize this data structure not only with data, but with behavior. And it worked really well. (This is all obvious to anyone's who's programmed in the last 20 years).

However, the solution wasn't perfect. I eventually came to want to be able to further refine the behavior. I wanted one listbox to act just like another listbox, but also do something additional when an item was selected. This is where inheritance comes in. I ended up adding another function pointer for these cases, that pointed to the original function, and that I could call from the new function. The new function could call the old function before, during or after the new code, or could even completely ignore the old function altogether.

However, this solution never seemed as clean as the first solution of using dispatch tables for polymorphism. It was too obviously hacky having to maintain these chains of function pointers, and too easy to screw up and create bugs.

So imagine my delight when, soon after, I got a job with Sierra On-Line, then (1989) the most prominent adventure game company. They had actually created their own language, SCI, that was a very pure implementation of OOP. I'll never forget that first night reading the documentation on my bed and just being consumed with this language that did things I wanted to do and even things I didn't know I wanted it to do.

Ever since then, I've run into lots of people who talked about the difficulties of making the paradigm shift to OOP. But not me. It was love at first sight.

Monday, May 4, 2009

Listing the contents of your git stash

I had a feeling there was something in my git stash that I'd forgotten to apply. But I couldn't figure out a simple way to list the contents of each of the stashes.

git stash list -p should work, I think, but it just lists one line for each stash, not the diff with the parent.

git stash show stash@{0} shows the contents of one stash, but I don't want to have to do that for each one in the list.

My coworker at Rupture, Rick Fletcher, came up with this, which works a treat:
git show $(git stash list | cut -d":" -f 1)

Wednesday, April 22, 2009

Rails MySQL adapter and tinytext

Ruby on Rails's MySQL adapter doesn't grok the tinytext datatype. The following code will use that type when a text field with limit 255 is defined in schema.rb (which is what the adapter generates when it sees a tinytext in the database).
class ActiveRecord::ConnectionAdapters::MysqlAdapter
original_type_to_sql = self.instance_method(:type_to_sql)
define_method(:type_to_sql) do |*args|
return 'tinytext' if args.first == :text && args.second == 255
original_type_to_sql.bind(self).call(*args)
end
end
Put this code in config/initializers/mysql_extensions.rb.

Sunday, December 14, 2008

Going back to OS X

I recently discovered that the ruby on my Mac was outdated. I had installed it from macports and never updated it.

It seems to me that if OS X comes with ruby, it should also take care of updating it when necessary, automatically, the same as it does with other software. So I nuked the macports version.

I also nuked all my ruby gems, which were installed somewhere under /opt/local. I've been gradually reinstalling them to /usr/local, where the gods of Unix intended them. I had trouble installing the mysql gem, however, and the various blog posts I'd seen about this related to macports.

The following command installed the gem:

sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config