Friday, July 15, 2011

Ruby magic

I learned ruby for my internet programming class a year or two ago. I built a pretty cool rails app, and generally liked the features, but never really came back to it. I definitely developed some holy-envy for some of the dynamic features and magic that it has.

In the Utah Software Craftsmanship Group last week, we decided to make our next book we read Seven languages in seven weeks. The first chapter in that book is Ruby, so I was super excited to dig in and learn more of the nitty-gritty. Somebody pointed out Ruby koans as a great way to learn ruby, and I must absolutely agree. In the first three files alone, I have learned tons of the intricacies of the language, but also been a bit confused on some others.

For example: this here was quite confusing until I did some research on stackoverflow.

array = [:peanut, :butter, :and, :jelly]
array[0,2]  => [:peanut, :butter] #OK!
array[2,0]  => [] #OK!
array[2,20] => [:and, :jelly] #OK!
array[4]    => nil #OK!
array[5,0]  => nil  #Looks good
array[4,0]  => [] #WTF??!?!?. 

as lines 6 and 7 are both out of bounds, it was dang confusing as to why they would be different. Luckily I'm not the first to have this question. Stackoverflow quickly answered my worries and helped make (a little) sense out of it. If you consider the index as the spaces between elements, array[4,0] starts just after the last element, but has nothing after it, while array[5,0] has no elements before or after it. Still not sure if I agree with that decision, but it makes some sense.

My favorite bit so far though is this:

firstName, lastName = ["John","Smith"]
firstName, lastName = lastName, firstName

I've always known about these compound assignments, and I rather like them when they are not abused horribly. I always thought though that it was sugar for:

firstName, lastName = lastName, firstName

#is same as

firstName = lastName
lastName = firstName

But that is not so. It does more magic than that because without caching the results the name would become "Smith, Smith", not "Smith, John". To really get the in place swapping effect something like this is required:

temp1 = lastName
temp2 = firstName
firstName = temp1
lastName = temp2

Obviously the language designers anticipated this use, and put a generous sprinkling of magic in. I could do more experiments in putting stronger side-effects in the right hand expressions, as now I am a bit curious if it is as simple as my last snippet, or if there is even more magic going on. Maybe I'll do that in the future.

Bottom line is: Ruby is fun. I'm learning a lot.

No comments:

Post a Comment