Archive for the ‘Ruby’ Category

So far this first week of vacation has been used, as Lauren astutely noted, as, effectively, study hall. This weekend was largely spent preparing for my Latin probatio on Tuesday. The good news is that I managed to catch up on all the optional exercises in the back of my Wheelock’s and I had an interesting opportunity to learn more about extending Textmate.

I have discussed elsewhere the power curve of the editor emacs versus vim, but think that Textmate may have hit the sweet spot in terms of writing extensions.

Extension 1: Writing Macrons

While I had earlier posted about my joy of finding a keyboard map which would allow me to enter macron-ized vowels with Option + Vowel, I found this to me a very straining key combination on my keyboard. It’s not that easy to hook a thumb under to hit option plus a vowel.

Thanks to my crazy remapped keyboard, where Control is where Caps Lock is, I was able to remap Control + Vowel -> Macronized Vowel. This is a much better typing arrangement ( try it: Push caps lock plus a/e/i/o/u ). Even nicer is that on a Dvorak keyboard, all of these combinations can be hit with the left hand solely.

While this may be nifty, you say, I can say that it’s even niftier because I was able to scope the effectiveness of these bindings to be within certain types of documents. While emacs and vim certainly both support this feature it was incredibly easy to implement in Textmate. I simply scoped this command set to be within the text.html scope and it was carried into text.html.markdown ( an HTML shorthand ) text.html.textile and good old text.html itself. This is huge, huge, huge. This means that when editing PHP or Perl code Control + “e” or macronized-e reverts to its default setting of “end of line”. Very handy.

{ Aside: Astute readers may note that by assigning Ctrl+e to be macron I lost a handy mnemonic key-binding for go-to-end-of-line. I did, in fact. I have remedied this by adding, in that same scope Control + “]” as a replacement and that’s worked out pretty well so far. }

Extension 2: Speaking of Markdown

So key bindings and scoping may not be that big of a deal to you, but it was a huge step forward to me. Further, modal text editing is not something particularly foreign to vim or emacs. However, I had a few needs come up that would have been hairy to add in Vim’s scripting language, but that were incredibly easy to add with Textmate.

Ascii Table

Often when answering the questions in the back of Wheelock the question takes the form of:

  1. Identify the personal endings of the future and imperfect tenses of the first two conjugations. 1) -o 2)-s 3)….

Obviously, constructing the answer in a table would be preferable with column headings being the given number, the given ending, the identification / the translation / etc. But the code for entering an HTML table is, while simple, a bit of a pain to enter. It’s very tag-heavy. Textmate has not done the best job of making this process easier.

In the php-markdown-plus wordpress extension, suppotr was added for Ascii tables. Why this hasn’t been added for the Markdown master code base I have no idea.

Step 1: Create columns

There were six rows of data. Add plus one for the headers.

ruby -e ‘7.times{puts “|”}’

I type into textmate and push Ctrl+R. I get this:

 |
 |
 |
 |
 |
 |
 |

Textmate just let me type a Ruby one-liner into the text, hit Control R and insert the text. Not too shabby.

Step 2: Fill in the table headers:

|person|imperfect|future|
|
|
|
|
|
|

Step 3: Let’s fill in the given persons…

|person|imperfect|future|
|1st sg
|2nd sg
|3rd sg
|1st pl
|2nd pl
|3rd pl

Now it would be a pain to closs off all the row definitions with “|” by hand. I could use a search and replace expression like “s#$#|#g” on the highlighted range, but I wrote a simple key-binding to do that search and replace for me. I saved this add on into a bundle I created ( HTML Editing for Latin Students ) and voilá. Thus i hi-lit the section, control + | and…

Step 4: Close off newly-added column

|person|imperfect|future|
|1st sg|
|2nd sg|
|3rd sg|
|1st pl|
|2nd pl|
|3rd pl|

Now I needed to fill in the subsequent columns…I use control +n to go to the next line so that I don’t have to use the mouse or the arrow keys. It makes the vertical editing task much easier. This is an emacs convention. I close the process off with Control + | again.

Step 5: Finish off the table

|person|imperfect|future|
|1st sg|bam|
|2nd sg|bas|
|3rd sg|bat|
|1st pl|bamus|
|2nd pl|batis|
|3rd pl|bant|

and the future…

|person|imperfect|future|
|1st sg|bam|b?|
|2nd sg|bas|bis|
|3rd sg|bat|bit|
|1st pl|bamus|bimus|
|2nd pl|batis|bitis|
|3rd pl|bant|bunt|

Now, to my eye, this is an intelligible table. Nevertheless, I will need to convert this to an HTML table as Markdown doesn’t natively support this conversion. Now, if I were in emacs here, I’d need to break out some eLisp code. In vim I’d have to go through the hell of using the scripting metalanguage. With Textmate, I just write a ruby script and then paste that in ( it’s pasted after the jump ) and then bound that to a key-binding. Thus I have “Turn Ascii table into HTML” bound to Command-Option-T

<table border="0" cellspacing="5" cellpadding="5" style="">
  <tr>
    <th>person</th>
    <th>imperfect</th>
    <th>future</th>
  </tr>
  <tr>
    <td>1st sg</td>
    <td>bam</td>
    <td>b?</td>
  </tr>
  <tr>
  ...
</tr></table>

And that was incredibly handy.

Make styling with CSS easy

One of the things that made me choose HTML for my language of typing was the ease of styling. Per standard didactic purposes, there will be translation sections in exercises. I wanted to style the “given” one way and the answers another. Again, Textmate to the rescue.

Add a tab-trigger.

Typing: “pgiv(tab)”

<p class="sent_given">. </p>

I type a number (say, 11) then hit tab again and I’m inside the tag, typing the given.

Typing “pans(tab)”

<p class="sent_answer"></p>

Similar, but for answers. As both of these <p>-tag elements have classes associated with them, I can format them with CSS to get the look I want. Simple.

But wait, there’s more.

Doing ‘pans’ and ‘pgiv’ is inefficient. How about I type all the sentences at once, in paragraph form, start the paragraph with the question number to start at, and then have each of those set up as <p> tags with the “given” class associated with them?

11.  This is sentence one.  This is sentence two.  This is sentences three.

Highlight run through Ruby script I added called “Line-ify as Given sentences..”

<p class="sent_given">11.  This is sentence one.</p>
<p class="sent_given">12.  This is sentence two.</p>
<p class="sent_given">13.  This is sentence three.</p>

I’ve added other features like a corrections binding (corr-tab) to produce a span elemnent that’s colored red so that I can annotate errors, but I’ll stop here. You get the idea.

Textmate: Pretty, easy to extend with scripting languages you already know to key bindings you want in such a way that you don’t obliterate key bindings you don’t want to lose.

Conclusion

I’ve been so impressed by the power of Textmate in the regard of making HTML so much easier to generate, that I’m thinking about extending these features to LaTeX to get the beautiful formatting power latent there. I hopes this has helped you see that Textmate isn’t just a wonderful editor for code-hackers, it’s great for classicists as well!

(more…)

In March of this year I started the meetup.com group for the Ruby programming language. I wanted to meet some other people who were interested in exploring this elegant and rich system for the expression of thought.

Well, here’s the group!

Wisely, one of our members suggested that we work together on a learning project. Our project of choice was resolved last meeting and it is a ‘text-based adventure game engine’. The generic requirement is that by creating a scenario file ( i.e. the rooms, the contents of the room, etc. ) you can feed that file to the engine and it will give you a text-based adventure story along the lines of Zork or Leather Goddesses of Phobos.

I was so inspired by the discussion we had around this last week, that I wrote a basic set of classes for the construction and population of the universe. Our working model is that everyone will attempt the assignment and then at the next meeting we will compare approaches, decide on which model works, and then collapse those “winning” implementations into our main code branch.

Bit by bit we’ll all learn new aspects of Ruby and grow our own skills. Ultimately we may unleash our inner screenwriters and create a fun game or two.

This post is a ‘jumping off’ point for reading about my adventures at BNR’s RoR camp in February of 2007.

Day-by-day Recap

Summation / Preparation

Thanks Staff

Thanks to Charles, my teacher, and Emily and Jaye who handled the logistics. Big thanks to Aaron for coming out to check on us! Thanks as well to the Callaway Gardens staff who were so friendly and accommodating of a nerd invasion.

I had a good experience in the class. I was able to learn the material without falling behind, feeling like i was drinking from a firehose, or feeling like each additional word was just a drop of water on a saturated sponge. There were definitely people who feel more comfortable with the material right now than I do, but I thought I would like to tell you things in my background that I believe helped me be successful in the class.

Unlike a college institution, the BNR does not enforce pre-requisites. As such it is your responsibility to assess whether you have the tools and knowledge necessary to get what you need out of the class.

Rails stores its data in a Database: Know a relational database

Do I mean be a DBA? Be able to deploy Oracle with both eyes closed? No, I don’t mean that. I think you should be able to do a MySQL or PostgreSQL database set up ( you could probably just use a tutorial for either product ).

  • Basic DB concepts
    • What’s a relational database?
    • What’s a typical SQL query string?
    • What’s a primary key?
  • Basic DB skills
    • Run the command line to open a session
    • Create a database
    • Add / Delete / Describe a table
    • ( I didn’t have ) Knowledge about joins. This did not inhibit me, but having understanding of this too would have had me completely in the know.
  • Basic familiarity of DB use
    • Be able to run a SQL query on basic select parameters, be able to order by a criteria

Rails uses a web front end, know CGI / WebUI programming / HTTP issues about state

  • HTTP is a stateless protocol
    • Know what that means
    • Know techniques for preserving parameters between script reloads
    • Know how to write a basic form in HTML or Perl or PHP
    • Know how to pass a parameter in a ‘hidden’ form field
    • Know how passing form data in this format behaves when using a GET operation versus a POST operation
    • Experience writing CGI in either Perl or PHP will be hugley advantageous

If you’re on a Mac, Textmate is the editor to use

Some time playing with Textmate, how it tries to help you, how to use the bundle editor, maybe watching the screencasts is advised. Again, coming in with no experience is no loss, but if you have it you can r0x0r some s0x0rz.

If you’re on a PC, uhm. Sorry. I don’t have any knowledege about that.

Rails tries to use New Web Technology

  • Know CSS
  • Know a basic, modern, non Front Page, HTML file.

Rails is written using Ruby: know something about Ruby

Ruby …

  • Is object-oriented, you should understand object orientation
    • How would you define it?
    • What’s the difference between procedural programming and OO, why did OO evolve
    • Be able to describe the theory of a Class, Subclassing, an Ancestor class
  • Has a very interesting syntax, know a little bit about Ruby syntax
    • You needn’t be a guru, you’ll be writing Rails, which uses a fairly limited subset of the Ruby lexicon
    • Conversely, if you know a lot about Ruby you may be able to squeeze out new arrangements, you may be able to build more terse algorithms.
  • Data types
    • Know the basic data types: Hash, Array, and String
    • Be able to define you own data type ( == class )

If you know this, you should be able to breeze through the first day. You’ll be introduced to some Rails concepts, but they are mostly slight nuances of the above.

End Day 1 and beginning Day 2 will be your first solid Rails lessons and Day 3 will challenge you to incorporate advanced-core capabilities onto the core-capabilities you learned on Day 2.

BNR Classes are fun, it’s the hardest computer training course you’ll love busting your ass at:

  • Bring hiking shoes, there’s a daily walk after lunch ( weather permitting )
  • Bring business cards or have your .vcf file ready to go: you’re going to make friends and you’re going to want to give them your cards
  • Bring some wind-down material: Settlers of Catan was popular, the book you’re reading, some DVDs. Sometimes you may want to get away from the hub-bub and / or you may need something to help move you from ‘twitch mode’ to being able to sleep.
  • Check the weather. Who would have guessed that Atlanta would have been as cold as Kansas?
  • Be ready to work. Work as hard as you can to get a real understanding. Do the exercises, work to improve them, try to implement them again on your own, with slight modifications.
  • You may want to take additional time off to practice whet you’ve learned and / or to re-calibrate to “the real world”
  • A small umbrella might be handy, weather in the Gulf / South is unpredictable
  • Send me an email if you have a question or a comment!

Big Nerd Ranch: RoR Day 5, and back home

Saturday, February 17th, 2007

Well yesterday was a brief morning session where we covered profiling, how to get help, and took a look at some of the student generated work that had been created during the week.

After that we were shuttled back to Atlanta where we all dispersed, catching our flights to the various parts of the map.

My plane was delayed by an hour ( mechanical ) so I arrived in houston about 7:30. After getting to the park and ride I proceeded to drive back to Austin, getting home about midnight.

While I was flying I had a chance to post a wrap up and advice page which will be next in the posting list.

I’m glad to have gone, but right now, in my comfy chair, I’m sure glad to be back home!

Big Nerd Ranch: RoR Camp: Day 4: The Reprieve

Thursday, February 15th, 2007

Day Four: It’s a good day.

The reason day 4 is a good day is because you’re out of “how rich is this language and how many other key concepts must I learn to be functionally literate” phase. You see, you’ve covered the dead basics on the first day. Day two is a real challenge because you’re learning the bits of the language that are advanced and that you will need to know to really be able to work “out of the middle section of the book”: the part where it moves from introductiory to non-trivial.

Day three is the hardest, as I’ve detailed in great detail previously.

But day four is where the new and core material starts giving way to specialized topics: how to handle mail, how to build a test, how to provide web services. All of these build on the hard work you did on the first 2.5 days so you no longer get that feeling of “Oh hell, am I slipping too far behind?”.

Everyone in class seems to be a bit more spirited. The hardest part of our personal / night projects have been dealt with and everyone has that sense of “hey, you know, I might be able to do this on my own.” It’ the beginning of a very hopeful swing that continues into day 5.

Day 5 is the final bit of the “topics” specialized areas ( but not, not core language ), you learn to maximize particular aspects and you’re going home in just a few hours. It’s great to be at the Ranch, and you learn a lot, but just like all journeys it’s so good to go back home.

Once home you’ll reflect on the great experience you had and you’ll shake off the experience and re-integrate yourself into reality. But it’s so much fun, you can’t wait to get back to that mindset again.

Today was beautiful, but still cold. During our travels today we visited Callaway Gardens’ butterfly preserve. After walking through 40-degree weather it was quite a change of pace to enter the balmy 80-degree chamber in which the beautiful leipidopterans inhabit.

I’m still amazed by the versatility of the teacher, Charles B. Quinn. I mean, being able to take 30000.times{‘question after’} without snapping (verbally or mentally ) is really an excellent demonstration of guru-dom. I can only aspire to know some thing as well as the C. knows Rails, or as well as Aaron knows Cocoa (my previous BNR class).

Really I need a few days away from Rails, but I know that within the next week I’m going to start scratching in my notebook, imagining how I can turn BNR education into applications that amuse, entertain, and possibly do Something Great.

Hi all,

After the lengthy tour of duty yesterday, I’m back in for another lengthy day. I think that Wednesday is really the grinder day.

First, you’ve been lectured to for the last 3 days. There are very few minds that can take 8hr. / day lectures without feeling a bit tapioca-ish on the 24th hour.

Secondly, you’re listening and then working very hard on something that you just were introduced to. You have these head bashing against a wall sessions and then, suddenly, you’re set free ( because you’re doing something that’s old hat, something you learned, say, that morning ) and then you hit the wall with all that built-up acceleration. It takes a certain mental flexibility.

Third, the sugar, the munchies, the food, etc. By this time it’s all having some funky effects on your body.

Homesickness becomes a bit of a factor. You remember how good your bed is, how nice it is to be among your things and your life.

Now, about the work. You see, you can slide on day 1. You learn the material, you review it, you’re probably OK. DON’T BE FOOLED this is your one and only chance to get ahead of the abbatoir days 2 and 3.

Then comes day 2. If you want to keep ahead you’ll be working late on day 2, maybe even thinking that you’re going to catch a break on day 3. But no, my friends, day 3 is the grinder. Day 3 says “OK, you’re determined, but how determined are you?” You’re bleary from day 2, the cokes, the mountain of water bottles, can you do another 18-hour run at things?

At day 4 you’re going to be exhausted. You’re going to reach your limit. You start to feel like your treading water capability is turning into negative progress. Unless you’ve stayed up on the exercises and mentally integrated the concept and become with the ‘way things are done in this language’, you’re going to feel a bit behind.

Fortunately day 5 is the wind-up day. There’s a sense of graduation and possibility. If you can integrate the first 3 days quickly you’re going to be in a good position to re-discover the last two days quickly. I think that may be the optimal take-away from a class like this.

I’m not sure, I’ll be a good empirical guinea pig for the next few months.

The example and exercise scripts during the RoR class centter around receiving requirements for a company that produces widgets. Never content to simply accept the assignment, I have pushed my, uh, unusual sense of humour onto the project.

widgetfabrik.png

If you are learning Ruby coming from a C or Perl background, you may find the following discussion somewhat interesting.

One of the most common idioms ( especially in my CGI programming in Perl ) is to use a dispatch table based on a keyword or an option.

It is particularly handy to arrange a hash such that by entering a ‘keyword’ (the key in the hash element) you trigger an anonymous subroutine, or a pre-defined routine.

The code for this, in Perl, looks something like this:

my %h = ( 'alpha' => &theAlphaRoutine, 'beta' => &theBetaRoutine, 'gamma' => &theGammaRoutine, );

Thus by dereferencing %h with the argument ‘alpha’ you can achieve the same net effect as if you had called theAlphaRoutine()

Thus:

$h{'alpha'}()

is equivalent to

theAlphaRoutine()

Now, let’s sexy it up a tiny bit. Let’s put anonymous subroutines inside the hash, that is to say, routines that are defined as you define the structure of the hash. This creates that very cool Perl effect of “I’m running code that I didn’t define in subroutines, this is very subversive.”

my %h = ( 'alpha' => sub { print "first comes first\n"}, 'beta' => sub { print "second comes second\n"}, 'gamma' => sub { print "third comes third\n"}, );

Nice! Thus executing:

$h{'alpha'}() will generate:

first comes first

As an experiment, let’s create an array of the names of the key values in %h and iterate through them. We will then us the current keyword (held in the $_ variable) to dereference the hash. In so doing we will ‘call’ the associated anonymous routine.

The code:

#!/usr/bin/perl

@names = qw |alpha beta gamma|;

my %h = ( 'alpha' => sub { print "first comes first\n"}, 'beta' => sub { print "second comes second\n"}, 'gamma' => sub { print "third comes third\n"}, );

for ( @names ){ $h{$_}()}

Produces the expected result of:

first comes first
second comes second
third comes third

Well, that’s just great. Now, I thought that I would like to try this idiomatic expression in Ruby. Now, let me first say that doing things this way is very un-Ruby like and can be done in many superior implementations. This is simply a thought experiment for you.

Let’s start with this basic Ruby code:

names = %w(alpha beta gamma)

h[:alpha] =lambda { puts "first comes first"} h[:beta]= lambda { puts "second comes second"} h[:gamma] = lambda { puts "third comes third"}

So the goal would be, “run through the listing of items in ‘names’ and then proceed to dereference these anonymous subroutines lambda expressions[1] using the Proc.call method”

First Attempt

A naïve stab ( that is, my first stab ) looks like this. We add a simple command to spit out the names that we’re going to use for the dereferencing.

names.each {|name| puts name}

This produces:

    NameError: undefined local variable or method
       `h' for main:Object

What?! An important thing for Perl coders to remember is that Ruby doesn’t auto-vivify[2] a hash by declaring one of its key value pairs. You have to create a pointer to a Hash object before you can start adding keys and values. So let’s add this line before the h[parameter] declarations:

h = Hash.new

Produces:

alpha
beta
gamma

OK, so now we have the keys, let’s get those keys to dereference within the Hash and we’ll see our lambda expressions performed.

Second Attempt The naïve next step would be this:

names.each {|name| h[name].call}

Which produces:

    NoMethodError: undefined method `call' for nil:NilClass
    at top level    in goofing.rb at line 9
    method each in goofing.rb at line 9
    at top level    in goofing.rb at line 9

What the heck?

My first instinct was that it was a scoping issue. “Ah-hah!”, thought I, “I need to declare h to be $h” ( keep in mind Perl-ers, $x merely means “make it global”). This made no difference.

What happened is something that I hadn’t caught on to:

:symbolname is not equal to ‘symbolname’

This should be obvious, but it’s so obvious, it’s easily missed.

One simple set of commands should demonstrate this:

puts :symbolname.class puts 'symbolname'.class exit

Produces:

    Symbol
    String

In our example, thus, names contains strings - not symbols. Our hash structure is set up using symbols as keys.

I thought that perhaps the fix was to simply put a : in front of each of the strings within names. But again, this merely nets you a collection of strings with a “:” as the first character.

A quick bit of code makes the point clear:

names = %w(alpha beta gamma) names2 = %w(:alpha :beta :gamma) names.each {|name| puts name.class} names2.each {|name| puts name.class}

It’s just a bunch of strings!

OK, so we need a method whereby to convert strings to symbols. Fortunately String#to_sym does just this.

Thus, to get whan we expect, let’s add:

names.each {|x| $h[ x.to_sym].call}

In sum:

names = %w(alpha beta gamma)

h = Hash.new h[:alpha] =lambda { puts "first comes first"} h[:beta]= lambda { puts "second comes second"} h[:gamma] = lambda { puts "third comes third"}

names.each {|x| $h[ x.to_sym].call}

And this gets the desired:

<pre> first comes first second comes second third comes third </pre>

Of course the really Ruby way of running this would be...

<code>h.keys.each {|x| h[x].call}

Or better yet…

h.values.each { |y| y.call}


  1. ‘Lambda Expression’ is a particularly interesting area in the hop from pure mathematics to computer science and the reader is highly encouraged to look into the basic outlines of the design of Alonzo Church and colleagues. Defmacro.org has a really great summation. I’ve only read some of the basics in my on-and-off flirtation with Lisp. Check it out.

  2. Auto-vivify means “auto make alive”. By creating a hash key value pair $aHash{'foo'} = 'foomonkey', %aHash is auto-vivified, automatically created. Not so in Ruby.

Steven is a whimsical programmer

Tuesday, June 20th, 2006

Nowhere is this more readily seen than when learning a language, in this case Ruby.

def something puts "Say Something" yield("\t[", "]\n") end

something { |startchar, endchar| puts startchar + "Reggae, Reggae" + endchar} something { |startchar, endchar| puts startchar + "Rasta, Rasta" + endchar}

Produces…

Say Something [Reggae, Reggae] Say Something [Rasta, Rasta]

Stay irie, my bretheren.

Bob Marley, Poet and a Prophet