Posts Tagged: ruby


26
Jan 10

when in rome

collisium

Trust me, you want to do what the Romans do, I mean... have you ever built a Collisium?

Ah the cliché of it all, “When in Rome.” Although it would be nice to have a post about being in or traveling to Rome, sadly this is not the case. Instead, this post is about following convention and how that can help you learn.

I’ve been getting into ruby as of late, after learning Smalltalk, Objective-C, and LISP (to varying degrees), ruby hits a nice sweet spot of stealing some of the best bits from each. I was recently approached by a friend who does primarily .Net programming about the best way to go about learning ruby. He had decided that, at least in the beginning, he should use the NetBeans IDE. This seems harmless enough, even logical for someone who spends their entire day in Visual Studio to want the comforting guidance of the IDE. It is also the exact wrong approach.

As he progressed past simple “Hello World” examples and onto his first rails project he found himself battling with the IDE. Odd error messages, the IDE struggling to provide auto-completion on the dynamic models, but most importantly a complete lack of resources. The ruby and rails world to a large degree lives and breathes on the command line, right now if you go to my home computer you will find 4 terminal windows arranged with a mysql shell, script/console, script/server, and one for git. If something goes wrong and I get a weird error, I do what all great programmers do, copy and paste that sucker into Google. I normally find somewhere around a bajillion hits with solutions, huzzah!

My friend on the other hand had trouble doing the simple things through the IDE, like installing gems. I’m certain the IDE was capable of it, and that someone better versed in it would be able to help him out, but the Google-scape was barren to his questioning. All I could say to answer his questions were, “well I’m not sure how NetBeans does it, but on the command line just type gem install [gem]” (Also I can speak in teletype, I just do a robot voice.)

Despite the difficulties, my friend clung to the belief that the IDE was the way to go for beginners. I finally realized the perfect analogy to drive home the point, I asked, “Would you ever advise someone new to .Net to learn it by using the command line tools?” It’s a perfectly valid question, I’m sure plenty of people who hang out in vim all day and don’t mind doing things like ./configure && make && sudo make install (thanks Jeremiah for pointing out my n00bishness) would feel much more at home on the command line.

I am not free of fault on this either, when I attempted to learn git for the first time, I used TortoiseGit. I was very comfortable with TortoiseSVN and thought it would ease the transition. It sure did, I was able to treat git exactly like svn, and completely miss the point! Once I moved to the command line (and watched some screencasts and read some articles) I felt much more at home with git, and even began to understand why I would want to use it over svn. I had stopped trying to make it something it isn’t and embraced the thing that it is.

The point here is that when you learn something new, it’s new, don’t bring along your technological baggage. If the community all rallies around some IDE (.Net, I’m looking at you) then for flying spaghetti monster’s sake, use that IDE. If they rally around the command line (ruby, I’m looking at you) then by the hammer of Thor, use the command line. If they rally around some weird virtual environment machine (smalltalk, I’m looking at you) then have fun and realize you are never going to be able to use that at work (just poking fun, I <3 smalltalk).

The point here is that learning something new is often times uncomfortable, you have to feel like a tourist for a while. When in Rome though, do as the Romans do. Embrace the methodologies, naming conventions, and tools that are the community standard. Give it a few weeks, if you still find yourself hating it, then maybe that particular technology isn’t for you, it’s ok, we can’t all love everything. Life is about trying new things and figuring out what makes you want to get out of bed in the morning, for some people it will be .Net, for some ruby, for some COBOL (just kidding, no one likes COBOL).

You never do yourself any favors by half-way learning something, because you will either hate it because it was poorly shoehorned into an inappropriate paradigm, or you will learn to love it. “That second thing doesn’t sound too bad” (I can sense your thoughts), and at first blush its not, until you want to start participating with the community by using others’ code and sharing your code. Then you will have to unlearn all the bad practices you’ve adopted and have a difficult transition into the community, attempting to erase months of muscle memory. Save yourself the difficult task of trying to unlearn something and simply embrace the technology in full to begin with. It’s a steeper curve, but the payout is the depth of understanding.


29
Dec 09

book review: design patterns in ruby

design patterns in ruby

Go buy this now

I am back from the holiday break and a perfect storm has come together, I’m currently working on a rails project, and I have a wonderful girlfriend who embraces my geekiness and buys me Design Patterns in Ruby. I have been reading this thing for the past few days and can’t put it down, I wanted to read a chapter last night before bed, I sleepily set it down 5 chapters later.

Just so you understand something, although I love to read, I am a slow reader, books are hard for me to get through, I also have a ton of things to read and play around with, so you better keep my attention. I have also read the classic GoF book, so I’m coming into this book well versed in design patterns. I’ve played with ruby a few times before, but nothing too serious (if you look back in the archives you will see that my first post was on ruby koans).

Let’s talk about this great book by Russ Olsen. The book does not require you to know anything about ruby, the first chapter is, in fact, a great primer to the language. Olsen comes from a background of 25 years of software development experience, as he puts it

I have been building software for more than 25 years. I’ve done assembly language, FORTRAN, Pascal, C, C++, Python, Java and now Ruby.
  -Russ Olsen

The introduction to ruby feels like it was written for someone with programming experience in a Java-like language. Throughout the book Olsen makes reference to the Java way to do things (which will be easy to grasp for the .Net crowd too). The primer to the language is interesting in that it skips some of the core things that makes ruby what it is (the whole meta-programming, monkey patching, message passing thing). This would seem like an oversight at first, but was helpful for me as a new ruby user. I wasn’t bogged down in the different of ruby, so I could focus on the same. This let me feel comfortable with the language and focus on the patterns, as we will see, these parts missing in the primer will be fully explored later in the book.

The book is structured very much like the GoF book, with each chapter focusing on a particular pattern. Olsen opens up the chapter with some example situation, then he moves into how you could solve it with inheritance or ugly code. Then the problem is re-examined, a pattern starts to emerge, and then is described. The pattern is explained in the classic GoF style with example code (in ruby) and UML diagrams, the best part though is the clear, concise, approachable explanation provided by Olsen. The pattern now being firmly understood, the book digs into the pattern and looks at ways that we can ruby-ize it. At this point we are normally treated to some new interesting ruby language paradigm that let’s us quickly and easily rewrite the pattern, making it more concise and elegant. There is then a discussion of the uses, and probably more importantly, the abuses of the pattern. Every chapter ends with a nice summary of what was learned and (as I found out last night) an enticement to keep reading as the next pattern is introduced.

rocket sauce

Pure unadulterated rocket sauce!

The writing is incredibly approachable, Olsen does not get bogged down in technical jargon, he explains everything that’s going on in a concise and understandable way. There are copious code examples that are excellent at providing a concrete example to the abstract pattern Olsen is discussing. The author mixes in some humor here and there and will show how other programming languages implement the patterns and historical reasoning for why things are the way they are in ruby.

The overall impression I got from this book is that it is win, condensed down into ink on paper. I have learned a ton about ruby, relearned some great patterns, and gotten a great insight on the ruby way to solve problems. If you find yourself thinking, “Well I don’t need to learn design patterns, I’m so smart!” Well you are not, I’m going to use one of my favorite quotes here with a bit of a twist.

Those who don’t understand design pattern are condemned to reinvent them, poorly.
  -Matt Nowack (original attribution to Henry Spencer)

Design Patterns are all around you, learning these will help you solve future problems, understand how rails works (in fact there are several occasions in the book where Olsen shows how rails uses this pattern or that one). This book is a pleasure to read, and I suspect will serve as a nice reference for implementing patterns correctly in ruby. I’m glad to have it in my toolbox, and I would suggest you get it for yourself.


5
Nov 09

duck typing works

Design Patterns in Ruby

Design Patterns in Ruby

I recently had the joy of picking up the book Design Patterns in Ruby which is a great book, made my Christmas wish list. If you have been living on the moon or are just one of those weird people that haven’t heard of ruby yet, it is a dynamically typed interpreted language made famous by the web framework, Ruby on Rails.

Do you see what I just did right there? I gave you some background information, information that you more than likely don’t need, you are reading my blog, you know what ruby is. Russ Olsen (author of Design Patterns in Ruby) does the same thing with duck typing. What is duck typing you ask? (again you probably didn’t, you know what it is, or you are familiar with this thing called Google). Well it comes from the term, “If it walks like a duck, quacks like a duck, then its a duck” and according to the authority on all human knowledge it can be defined as the following

In computer programming with object-oriented programming languages, duck typing is a style of dynamic typing in which an object’s current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.

One of the properties this gets you is the ability to pass any kind of variable anywhere and as long as it acts like the object the function is expecting it will work, no matter what class it is. In practice this allows for some great code reuse and as described in the book the evaporation of some class GoF design patterns. Olsen goes into a bit of depth about duck typing and the classic fear of someone coming from a strongly typed language.

So there is no compile time or static checks, what stops you from passing a database connection into a function that accepts an int or calling the give_big_fat_bonus method on a lowly worker instance instead of an executive instance, or of course the ceo instance which is a derived class of executive.
Anonymous Object Oriented Programmer

The answer is a resounding, nothing! (Dovetails nicely with my last post) Nothing stops you from doing this, go ahead see what happens. Depends on the language, in ruby you get a NoMethodError, and you get something like that in most duck typed languages.

The question then is how do people write any code that works, the answer is by not being full-on stupid. Ruby, and other duck typed languages, have taken to heart the sentiment of my post i can’t stop you from being stupid (The shameless self promotion is getting a little rampant at this point). The language can’t stop you from treating an int like a database connection, and really why should it. What in the hell are you doing mixing up an int and a database connection, you deserve to get punched in the face, a NoMethodError is the least of your worries.

But, accidents happen, so your db variable holding the database connection and your dv variable holding the direct value modifier amount are dangerously close on the keyboard. Are you going to just pray that you are 100% correct in your typing all the time, who do you think you are, me?! (I’ll wait patiently as grammar-nazis and typoistas tear apart this post). This is why unit testing is so huge in duck typed languages, if you are using sweet delicious lisp then repl is your friend, ruby also has repl (irb) but its not nearly as integral to the development process as repl is to lisp. Your tests let you know that you aren’t doing something stupid, and performs all the static and dynamic checking one could want.

So go out and give a duck typed language a shot, pretty soon you will enjoy the added speed, and you will realize that the static syntax checking is not necessary if you know what the hell you are doing.


6
Oct 09

ruby koans (2)

I still have the good fortune of not having any huge problems with our production application. During this time I’m brushing up on some ruby, sharpening the blade. I’ve been doing this by working through EdgeCase’s Ruby Koans. In my first blog post ruby koans I suggested that anyone interested in ruby utilize this resource and pointed out some problems I had encountered. I still suggest that anyone wanting to learn ruby and who has a basic understanding of programming use this great resource.

Working through the koans I have found some more issues, this time in the about_message_passing.rb file. One is just an oddity, the other a potential show stopper for someone new to programming.

Starting at line 50 there is a class called MessageCatcher (technically they are reopening the class defined on line 5)

class MessageCatcher
  def add_a_payload(*args)
    return :empty unless args
    args
  end
end

This is a very oddly named function, it doesn’t seem to add a payload to the the arguments, and it is coded in such a way that it will never return :empty. For it to return :empty, args would have to evaluate to false. The only falsey values in Ruby are nil and false, the only values args can be is an array. Arrays, even empty arrays, are true in ruby. If you don’t believe me, go ahead and run this in irb

:empty_arrays_are_true if []

That will evaluate to :empty_arrays_are_true, which proves my point. This is really a minor issue, but when filling out the corresponding test, the results aren’t really obvious.

The much bigger problem starts with the TypicalObject example

class TypicalObject
end

def test_sending_undefined_messages_to_a_typical_object_results_in_errors
  typical = TypicalObject.new

  assert_raise(NoMethodError) do
    typical.foobar
  end
  assert_match(/foobar/, exception.message)
end

This results in a nasty error when you rake, that looks something like this

You have not yet reached enlightenment ...
undefined local variable or method `exception' for #&lt;aboutMessagePassing:0xmemory&gt;

Please meditate on the following code:
./about_message_passing.rb:78:in `test_sending_undefined_messages_to_a_typical_object_results_in_erros'
./edgecase.rb:143:in `send'
./edgecase.rb:143:in `run_test'
./edgecase.rb:135:in `run_tests'
./edgecase.rb:134:in `each'
./edgecase.rb:134:in `run_tests'
./edgecase.rb:204
./edgecase.rb:203:in `each'
./edgecase.rb:203
./edgecase.rb:202:in `catch'
./edgecase.rb:202
path_to_enlightment.rb:27

If you are new to programming this could throw you off your game, the interpreter does helpfully tell us the line number to look at, line 78.

Looking at line 78 we see that we are using a local variable named `exception’, but we never define this variable. The way to fix this is to assign the result of the assert_raise to the variable exception, like so

class TypicalObject
end

def test_sending_undefined_messages_to_a_typical_object_results_in_errors
  typical = TypicalObject.new

  exception = assert_raise(NoMethodError) do
    typical.foobar
  end
  assert_match(/foobar/, exception.message)
end

That simple assignment, which does appear correctly in the test right after this one, solves the problem and allows you to continue on your ruby learning way.


2
Oct 09

ruby koans

EdgeCase’s Ruby Koans are a great way to get started with the Ruby programming language. I’ve worked through them once before and have had some free time at work so decided to work through them again.

The quality of the koans are normally excellent, there are a few times where a comment is left in the code to make you think, and you really wish that there was an answer key somewhere. There are also what look like a few errors in the code

In about_sandwich_code.rb, the find_line and find_line2 functions don’t seem to make much sense. You would imagine a function would find a line matching a given regular expression, but the regular expression is hardcoded to /e/ which doesn’t seem very realistic. This is the original.

def find_line(file_name)
  file = open(file_name)
  while line = file.gets
    return line if line.match(/e/)
  end
ensure
  file.close if file
end

A more realistic function would be

def find_line(file_name, regex)
  file = open(file_name)
  while line = file.gets
    return line if line.match(regex)
  end
ensure
  file.close if file
end

I’m sure this was done to simplify the exercise, but it violates the rule of least surprise by adding magic functionality to the function.

In the last function of about_scoring_project.rb, named test_score_of_mixed_is_sum, the first assert reads

 assert_equal 50, score([2, 5, 2, 2, 3]) 

The rules of the game clearly specify that

# * A set of three numbers (other than ones) is worth 100 times thenumber. (e.g. three fives is 500 points).
# ...
# * A five (that is not part of a set of three) is worth 50 points.

This means that the score should be 200 (for the set of three 2′s) + 50 (for the 5) = 250. The first assert should be changed to

 assert_equal 250, score([2, 5, 2, 2, 3]) 

If you are interested in learning ruby, this is an indispensable way to learn not just the syntax, but to get the flavor, and to start thinking in ruby.

Expand this block of source to see my solution

def score(dice)
  result = 0
  counter = {}
  (1..6).each { |x| counter[x] = 0 }
  dice.each { |d| counter[d] += 1 }
  if counter[1] &gt;= 3
    result += 1000
    counter[1] -= 3
  end 

  (2..6).each do |x|
    if counter[x] &gt;= 3
      result += (100 * x)
      counter[x] -= 3
    end
  end

  result += (counter[1] * 100)
  result += (counter[5] * 50)
end