My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement
I like minitest and I like rspec-mocks, so I wanted to use them together. Now you can too!

Thoughts? Let me know!

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!



minitest-stub_any_instance will define a method stub on any instance of a class for the duration of a block.

String.stub_any_instance(:length, 42) do
  assert_equal "hello".length, 42 # this assertion passes!
end


@nashby_ actually extracted the code from SimpleForm to do the job, and suggested it be included in MiniTest itself. But that didn't fly, so I packaged it as a plugin/gem.


Last week at the Houston Ruby User Group I made a presentation called "The Website's Slow" Tips and Tools for Identifying Performance Bottlenecks.

Image of the first slide in the presentation

That link is to the slides and notes on each slide mentioning a little about what I said.

Basically I went through a couple of different classes of performance issues you're likely to see on the server side of things, what tools you might use to make finding the issue easier, how you can interpret some of the data, and even a suggestion here or there about what to do to resolve common issues I've seen.

Let me know what you think! (Or, if you have any questions, feel free to ask!)


A sequence alignment from using BLAST on the NCBI website In the field of bioinformatics, one way to measure similarities between two (or more) sequences of DNA is to perform sequence alignment:
"a way of arranging the primary sequences of DNA, RNA, or protein to identify regions of similarity that may be a consequence of functional, structural, or evolutionary relationships between the sequences."
Think of it this way: you've got two random strands of DNA - how do you know where one starts and one begins? How do you know if they come from the same organism? A closely related pair? You might use sequence alignment to see how the two strands might line up in relation to each other - subsequences may indicate similar functionality, or conservation through evolution.

In "normal" programming terms, you've got a couple of strings and want to find out how you might align them so they they look as much like one another as possible.

There are plenty of ways to achieve that goal. Since we haven't done much programming on here lately, I thought it would be nice to focus on two very similar algorithms that do so: Needleman-Wunsch and Smith-Waterman.

The idea behind these two algorithms is that we have a scoring scheme we want to maximize as successive "matches" occur. One popular substitution matrix for scoring protein alignment is BLOSUM62 (and here's a good PDF describing how BLOSUM came about).

The particular scoring matrix you use will be determined by the goals you want to acheive. For our purposes, a simple matrix or two will suffice:

@substitution_matrix =
    [[" ", "a","c","g","t"],
     ["a",  1 , 0 , 0 , 0 ],
     ["c",  0 , 1 , 0 , 0 ],
     ["g",  0 , 0 , 1 , 0 ],
     ["t",  0 , 0 , 0 , 1 ]]

@substitution_matrix2 =
    [[" ", "s", "e", "n", "d", "a"],
     ["s",  4 ,  0 ,  1 ,  0 ,  1 ],
     ["e",  0 ,  5 ,  0 ,  2 , -1 ],                     
     ["n",  1 ,  0 ,  6 ,  1 , -2 ],                 
     ["d",  0 ,  2 ,  1 ,  6 , -2 ],           
     ["a",  1 , -1 , -2 , -2 ,  4 ]]

The first @substitution_matrix is fairly simplistic - give one point for each match, and ignore any mismatches or gaps introduced. In @substitution_matrix2 what score should be given if "s" is aligned with "a"? (One.) What if "d" is aligned with another "d"? (Six.) The substitution matrix is simply a table telling you how to score particular characters when they are in the same position in two different strings.

After you've determined a scoring scheme, the algorithm starts scoring each pairwise alignment, adding to or subtracting from the overall score to determine which alignment should be returned. It uses dynamic programming, storing calculations in a table to avoid re-computation, which allows it to reverse course after creating the table to find and return the best alignment.

It feels strange to implement this as a class, but I did it to make it clear how trivially easy it is to derive Smith-Waterman (SW) from Needleman-Wunsch (NW). One design that jumps out at me would be to have a SequenceAligner where you can choose which algorithm as a method to run - then SW could use a NW algorithm where min_score is passed as a parameter to the method. Perhaps you can think of something even better.

Anyway, here's the Ruby class that implements the Needleman-Wunsch algorithm.

class NeedlemanWunsch
    @min_score = nil
   
    def initialize(a, b, substitution_matrix, gap_penalty)
        @a = a
        @b = b
       
        # convert to array if a/b were strings
        @a = a.split("") if a.class == String
        @b = b.split("") if b.class == String
                   
        @sm = substitution_matrix
        @gp = gap_penalty
    end

   
    def get_best_alignment
        construct_score_matrix
        return extract_best_alignment_from_score_matrix
    end
   
    def construct_score_matrix
        return if @score_matrix != nil #return if we've already calculated it
       
        initialize_score_matrix
       
        traverse_score_matrix do |i, j|
            if i==0 && j==0
                @score_matrix[0][0] = 0
            elsif i==0 #if this is a gap penalty square
                @score_matrix[0][j] = j * @gp
            elsif j==0 #if this is a gap penalty square 
                @score_matrix[i][0] = i * @gp
            else
                up = @score_matrix[i-1][j] + @gp
                left = @score_matrix[i][j-1] + @gp
                #@a and @b are off by 1 because we added cells for gaps in the matrix
                diag = @score_matrix[i-1][j-1] + s(@a[i-1], @b[j-1])
               
                max, how = diag, "D"
                max, how = up, "U" if up > max
                max, how = left, "L" if left > max
   
                @score_matrix[i][j] = max
                @score_matrix[i][j] = @min_score if @min_score != nil and max < @min_score
               
                @traceback_matrix[i][j] = how
            end
        end
    end
   
    def extract_best_alignment_from_score_matrix
        i = @score_matrix.length-1
        j = @score_matrix[0].length-1
        left = Array.new
        top = Array.new
        while i > 0 && j > 0
            if @traceback_matrix[i][j] == "D"
                left.push(@a[i-1])
                top.push(@b[j-1])
                i -= 1
                j -= 1
            elsif @traceback_matrix[i][j] == "L"
                left.push "-"
                top.push @b[j-1]
                j -= 1
            elsif @traceback_matrix[i][j] == "U"
                left.push @a[i-1]
                top.push "-"
                i -= 1
            else
                puts "something strange happened" #this shouldn't happen
            end
        end
        return left.join.upcase.reverse, top.join.upcase.reverse   
    end

   
    def print_score_visualization
        construct_score_matrix
        print_as_table(@score_matrix)
    end

   
    def print_traceback_matrix
        construct_score_matrix
        print_as_table(@traceback_matrix)
    end

   
    def print_as_table(the_matrix)
        puts
        puts "a=" + @a.to_s
        puts "b=" + @b.to_s
        puts
        print "   "

        @b.each_index {|elem| print " " + @b[elem].to_s }

        puts ""
        traverse_score_matrix do |i, j|
            if j==0 and i > 0
                print @a[i-1]
            elsif j==0
                print " "
            end
            print " " + the_matrix[i][j].to_s

            puts "" if j==the_matrix[i].length-1
        end
    end
   
    def traverse_score_matrix
        @score_matrix.each_index do |i|
            @score_matrix[i].each_index do |j|
                yield(i, j)
            end
        end
    end
   
    def initialize_score_matrix
        @score_matrix = Array.new(@a.length+1)
        @traceback_matrix = Array.new(@a.length+1)
        @score_matrix.each_index do |i|
            @score_matrix[i] = Array.new(@b.length+1)
            @traceback_matrix[i] = Array.new(@b.length+1)
            @traceback_matrix[0].each_index {|j| @traceback_matrix[0][j] = "L" if j!=0 }
        end
       
        @traceback_matrix.each_index {|k| @traceback_matrix[k][0] = "U" if k!=0 }
        @traceback_matrix[0][0] = "f"
    end
   
    def s(a, b) #check the score for bases a. b being aligned
        for i in 0..(@sm.length-1)
            break if a.downcase == @sm[i][0].downcase
        end

        for j in 0..(@sm.length-1)
            break if b.downcase == @sm[0][j].downcase
        end
        return @sm[i][j]
    end
end


Needleman-Wunsch follows that path, and finds the best global alignment possible. Smith-Waterman truncates all negative scores to 0, with the idea being that as the alignment score gets smaller, the local alignment has come to an end. Thus, it's best to view it as a matrix, perhaps with some coloring to help you visualize the local alignments.

All we really need to get Smith-Waterman from our implementation of Needleman-Wunsch above is this:

class SmithWaterman < NeedlemanWunsch
    def initialize(a, b, substitution_matrix, gap_penalty)
        @min_score = 0
        super(a, b, substitution_matrix, gap_penalty)
    end
end

However, it would be nice to be able to get a visualization matrix. This matrix should be able to use windows of pairs instead of each and every pair, since there can be thousands or millions or billions of base pairs we're aligning. Let's add a couple of methods to that effect:

#modify array class to include extract_submatrix method
class Array
  def extract_submatrix(row_range, col_range)
    self[row_range].transpose[col_range].transpose
  end
end

require 'needleman-wunsch'
class SmithWaterman < NeedlemanWunsch
    def initialize(a, b, substitution_matrix, gap_penalty)
        @min_score = 0
        super(a, b, substitution_matrix, gap_penalty)
    end
   
    def print_score_visualization(window_size=nil)
        return super() if window_size == nil
       
        construct_score_matrix
       
        #score_matrix base indexes
        si = 1
       
        #windowed_matrix indexes
        wi = 0
       
        windowed_matrix = initialize_windowed_matrix(window_size)
       
        #compute the windows
        while (si < @score_matrix.length)
            sj = 1
            wj = 0
            imax = si + window_size-1
            imax = @score_matrix.length-1 if imax >= @score_matrix.length
           
            while (sj < @score_matrix[0].length)
                jmax = sj + window_size-1
                jmax = @score_matrix[0].length-1 if jmax >= @score_matrix[0].length
                           
                current_window = @score_matrix.extract_submatrix(si..imax, sj..jmax)
                current_window_score = 0
                current_window.flatten.each {|elem| current_window_score += elem}
             
                 begin
                    windowed_matrix[wi][wj] = current_window_score   
                rescue
                end
               
                wj += 1
                sj += window_size
            end
           
            wi += 1
            si += window_size
        end
       
        #find max score of windowed_matrix
        max_score = 0
        windowed_matrix.flatten.each{|elem| max_score = elem if elem > max_score}

        max_score += 1 #so the max normalized score will be 9 and line up properly 
       
        #normalize the windowed matrix to have scores 0-9 relative to percent of max_score
        windowed_matrix.each_index do |i|
            windowed_matrix[i].each_index do |j|
                begin
                normalized_score = windowed_matrix[i][j].to_f / max_score * 10

                windowed_matrix[i][j] = normalized_score.to_i
                rescue

                end
            end
        end
       
        #print the windowed matrix
        windowed_matrix.each_index do |i|
            windowed_matrix[i].each_index do |j|
                print windowed_matrix[i][j].to_s
            end
            puts
        end
    end
   
    def initialize_windowed_matrix(window_size)
        windowed_matrix = Array.new(((@a.length+1).to_f)/window_size)
        windowed_matrix.each_index do |i|
            windowed_matrix[i] = Array.new(((@b.length+1).to_f)/window_size)
        end
        return windowed_matrix
    end
end

And now we'll try it out. First, we take two sequences and perform a DNA dotplot analysis on them:

Local sequence alignment performed by DotPlot application

Then, we can take our own visualization, do a search and replace to colorize the results by score, and have a look:

Local sequence alignment performed by the version of Smith-Waterman presented here

Lo and behold, they look quite similar!

I understand the algorithms are a bit complex and particularly well explained, so I invite questions about them in particular. As always, comments and (constructive) criticisms are encouraged as well.


I just read an excerpt from @avdi's new alpha Confident Ruby ebook and it prompted some thoughts:

In the article, he talks about dealing with an account_balance where you iterate over the transactions of the account and sum up their amounts to arrive at a final balance.

A special case arrives when he points out you're dealing with a transaction.type whose value is "pending". You clearly don't want to include this in the account_balance because when the transaction processor introduces a new transaction of "authorized" for the same purchase, your overall balance will be incorrect.

A lot of the code I see (and used to write) looks like Avdi's example:

def account_balance
  cached_transactions.reduce(starting_balance) do |balance, transaction|
    if transaction.type == "pending"
      balance
    else
      balance + transaction.amount
    end
  end
end

It cannot be stressed enough how important the advice is to go from code like that to introducing a new object. In my experience, many cases are solved by simply introducing an OpenStruct.new(attributes: "you need", to: "support"), but Avdi advocates going further than that, and introducing a new object entirely.

I'm a fan of that, but typically I'll wait until YAGNI is satisfied, like when I need a method call with parameters.

Doing that is a huge win. As Avdi points out, it
solves the immediate problem of a special type of transaction, without duplicating logic for that special case all throughout the codebase
But for me, the second benefit he mentions is the biggest, and I hope he'll revisit its importance over and over again:
But not only that, it is exemplary: it sets a good example for code that follows. When, inevitably, another special case transaction type turns up, whoever is tasked with dealing with it will see this class and be guided towards representing the new case as a distinct type of object.
It's something I mentioned in my How to avoid becoming a formerly-employed Rails developer standing in line at the OOP Kitchen presentation, and I'll continue to stress its importance: "it's always easier to go with the flow, even when the flow is taking you through the sewers." So if you can introduce a little example of how to avoid the sewers, do it.

Anyway, I bought the book (which is literally just an introduction right now) based on the strength of that article and Avdi's commitment in his blog post. The article I linked to on Practicing Ruby is not yet in the book, but I hope it makes its way in.

I really enjoy the style of what I've read so far as a narrative, and if the article is any indication, this will be better than Objects on Rails (which I loved). One bit of feedback though: I'd like to see a "Key Takeaway" at the end of every section, so it can double as a quick reference book when I need to remind myself of its lessons.


Here's a 35 minute recording of the presentation which I gave to houstonrb on February 21, 2012. It is a practice run I did before the live presentation, so you won't get the discussion, but hopefully you'll find it useful anyway.

How to avoid becoming a formerly-employed Rails developer standing in line at the OOP Kitchen from Sammy Larbi on Vimeo.



You can find the slides here: Slides for the Rails OOP presentation

There is also reference to a project whose purpose is to eventually be a full-scale demonstration of the techniques: Project for the Rails OOP presentation

Let me know what you think in the comments below.

Updated to use HTML5 player at Vimeo.


My vocabulary is failing me right now. What do you call it when a piece of code checks the type of an object before doing something to it?

Type Casing is the act of using case statements in a program to determine what to do with an object based on what type of object it is. It's an OO fail, often hoping to implement Multiple Dispatch. (See also Case Statements Considered Harmful)

Here are three passive-aggressive ways to feel like you're getting back at typecasers.

More...


With a name like each_cons, I thought you were going to iterate through all the permutations of how I could construct a list you operated upon. For example, I thought

[1,2,3,4].each_cons do |x| # I did not notice the required argument
  puts x.inspect
end
 

would output: More...


Gem, Y U No install from git?

Yesterday I wondered if there was a good reason we couldn't gem install <url to git repository> and thought I'd have a look at adding it to rubygems for fun's sake.

Is there a good reason we can't just do `gem install <url to git repository>` ?

Then I saw how many files there were and decided gem install from git with a shell script would be easily achieved in just a few minutes.

#!/bin/bash
gemifgTMPDIR=$TMPDIR"_gemifg"
git clone $1 $gemifgTMPDIR
gemifgOWD=$PWD
cd $gemifgTMPDIR
gem build *.gemspec
gem install *.gem
if [ ! -z "$gemifgTMPDIR" ]
  then
    rm -rf $gemifgTMPDIR
fi
cd $gemifgOWD

Let me know what you think, or if there are some repositories where it doesn't work for you. I only tested it on utility-belt.


Yesterday I got sick of typing rake test and rake db:migrate and being told
You have already activated rake 0.9.2, but your Gemfile requires rake 0.8.7. Consider using bundle exec.
I know you should always run bundle exec, but my unconscious memory has not caught up with my conscious one on that aspect, so I always forget to run rake under bundle exec.

So I wondered aloud on twitter if I could just alias rake to bundle exec rake, but confine that setting to specific directories (with bash being my shell).

Turns out, it is possible with the help of another tool that Calvin Spealman pointed me towards: capn.

More...


Rails Rumble has nothing on this.

Of course, you could just click the edit button in your database management studio of choice and achieve the same functionality.

SELECT DISTINCT 'script/generate scaffold ' + t.name + ' ' + column_names
FROM sys.tables t
CROSS APPLY (
    SELECT c.name + 
           case when max_length > 255 then ':text' else ':string' end + ' '
    FROM sys.columns c
    WHERE c.object_id = t.object_id
    ORDER BY c.column_id
    FOR XML PATH('') ) dummy_identifier ( column_names )


A similar discovery was made in the 1930's. One important difference to note is that, since my program does not simulate the input on it's output program, I am able to achieve speeds that are logarithmically faster than what Turing could accomplish.



I like to use descriptive variable names, and I try to err on the side of more-descriptive if I think there's any chance of confusion. contract_participants isn't terribly long, but if you're building up all of its members from different sources (i.e., you can't really loop over it), it can get cumbersome to type and worse, to read. Moreover, it's different from just "participants" and they certainly aren't "contracts," so shortening it in this case wasn't going to happen. More...


A while ago, I was working with a problem in C# where where our code would get deadlocked, and since someone must die or several must starve, I thought it would be nice to just toss a "try again if deadlocked" statement into the exception handler. I muttered this thought on twitter to see if there was any language with such a try-catch-try-again-if construct. More...


SOAP can be a huge PITA in Ruby if you're not dealing with a web service that falls under the defaults. In particular, if your web service falls under HTTPS where you need to change the default certificate acceptance, or if you need to authenticate before seeing the WSDL, you're SOL as far as I can tell as of writing this post. (If you know of a way that doesn't resort to this complexity, please speak up!)

I was using Ruby 1.8.7 and soap4r 1.5.8, but this may apply to other versions. Anyway, here are a couple of monkey patches to help get you there if you're having trouble. More...


Code in Views and Code in the Wrong Place are two of the top 20 Rails development No-No's that came up in Chad Fowler's straw poll on Twitter about poor practices in Ruby on Rails.



Domain code in controllers and views isn't a problem that's limited to Rails, of course. It's a problem everywhere, and one you generally need to remain vigilant about. Rails doesn't make it easy by making it easy - it's much too easy to do the wrong thing.

You've got the view open and think, "I need to get a list of Widgets."

More...


From time to time I like to actually post a bit of code on this programming blog, so here's a stream-of-conscious (as in "not a lot of thought went into design quality") example that shows how to:
  1. Open Excel, making it invisible (or visible) to the user.
  2. Create a workbook and access individual worksheets
  3. Add data to a cell, or retrieve data from a cell
  4. Add a chart to a worksheet, with constants for various chart types
  5. Save as Excel 97-2003 format and close Excel
If you know where I can find the constants for file type numbers, that would be appreciated. Calling SaveAs without the type seems to use whatever version of Excel you are running, but I'd like to find how to save as CSV or other formats.

Needless to say, this requires Excel be on the computer that's running the code.

require 'win32ole'
xl = WIN32OLE.new("Excel.Application")

puts "Excel failed to start" unless xl

xl.Visible = false

workbook = xl.Workbooks.Add
sheet = workbook.Worksheets(1)

#create some fake data
data_a = []
(1..10).each{|i| data_a.push i }

data_b = []
(1..10).each{|i| data_b.push((rand * 100).to_i) }

#fill the worksheet with the fake data
#showing 3 ways to populate cells with values
(1..10).each do |i|
  sheet.Range("A#{i}").Select
  xl.ActiveCell.Formula = data_a[i-1]

  
  sheet.Range("B#{i}").Formula = data_b[i-1]

  
  cell = sheet.Range("C#{i}")
  cell.Formula = "=A#{i} - B#{i}"

end 

#chart type constants (via http://support.microsoft.com/kb/147803)
xlArea = 1
xlBar = 2

xlColumn = 3
xlLine = 4
xlPie = 5
xlRadar = -4151

xlXYScatter = -4169
xlCombination = -4111
xl3DArea = -4098

xl3DBar = -4099
xl3DColumn = -4100
xl3DLine = -4101 

xl3DPie = -4102
xl3DSurface = -4103
xlDoughnut = -4120

#creating a chart 
chart_object = sheet.ChartObjects.Add(10, 80, 500, 250)

chart = chart_object.Chart
chart_range = sheet.Range("A1", "B10")

chart.SetSourceData(chart_range, nil)
chart.ChartType = xlXYScatter

#get the value from a cell

val = sheet.Range("C1").Value
puts val

#saving as pre-2007 format
excel97_2003_format = -4143 

pwd =  Dir.pwd.gsub('/','\\') << '\\'

#otherwise, it sticks it in default save directory- C:\Users\Sam\Documents on my system
workbook.SaveAs("#{pwd}whatever.xls", excel97_2003_format)

xl.Quit

It's also posted in my Miscellany project at GitHub


LDAP in Ruby is better than LDAP in C#/.NET. Looking at it, I can't say it's much different minus the cruft from .NET.

Lightweight? Seriously?

Experiencing it while actually writing code, it's very different. I can't explain it, except to show it to you and tell you try it. More...


Logging Good Ideas Without Interrupting Your Flow Recently I decided I'd start using a wiki to manage knowledge and ideas, adding research and thoughts as I flushed them out over time. I'd like to see how the things I think about are interrelated, and I think using a wiki is going to help me on that front.

One problem I've had with the traditional to-do list, emails, calendars, and wikis was that when you open the whole thing up, you can pretty easily get distracted from what you were doing by all of the information that floods your brain: all the emails in your inbox (especially the bold ones), the rest of the to-do list, tomorrow's events, and -- well everyone knows the time-sink a wiki can be. More...


One step back from greatness lies the very definition of the impossible leadership situation: a president affiliated with a set of established commitments that have in the course of events been called into question as failed or irrelevant responses to the problems of the day... The instinctive political stance of the establishment affiliate -- to affirm and continue the work of the past -- becomes at these moments a threat to the vitality, if not survival, of the nations, and leadership collapses upon a dismal choice. To affirm established commitments is to stigmatize oneself as a symptom of the nation's problems and the premier symbol of systemic political failure; to repudiate them is to become isolated from one's most natural political allies and to be rendered impotent.
Stephen Skowronek, The Politics Presidents Make (pg. 39)


A little while ago Obie asked "What's this crap about a Ruby backlash?" The whole situation has reminded me of Skowronek's work, so I dug a couple of passages up.

We're at a crossroads right now between two regimes - one represented by Java, and the other represented by Ruby (although it is quite a bit more nuanced than that). My belief right now is that Java The Language is in a position where it can't win. People are fed up with the same old crap, and a change is happening (see also: Why Do I Have To Tell The Compiler Twice?, or Adventures in Talking To a Compiler That Doesn't Listen.) More...


This is a story about my journey as a programmer, the major highs and lows I've had along the way, and how this post came to be. It's not about how ecstasy made me a better programmer, so I apologize if that's why you came.

In any case, we'll start at the end, jump to the beginning, and move along back to today. It's long, but I hope the read is as rewarding as the write.

A while back, Reg Braithwaite challenged programing bloggers with three posts he'd love to read (and one that he wouldn't). I loved the idea so much that I've been thinking about all my experiences as a programmer off and on for the last several months, trying to find the links between what I learned from certain languages that made me a better programmer in others, and how they made me better overall. That's how this post came to be. More...


Suppose for the purposes of our example we have string the_string of length n, and we're trying to determine if string the_substring of length m is found within the_string.

The straightforward approach in many languages would be to use a find() or indexOf() function on the string. It might look like this: More...


It's not a hard thing to come up with, but it's incredibly useful. Suppose you need to iterate over each pair of values or indices in an array. Do you really want to duplicate those nested loops in several places in your code? Of course not. Yet another example of why code as data is such a powerful concept: More...


Since the gift buying season is officially upon us, I thought I'd pitch in to the rampant consumerism and list some of the toys I've had a chance to play with this year that would mean fun and learning for the programmer in your life. Plus, the thought of it sounded fun. Here they are, in no particular order other than the one in which I thought of them this morning: More...


I just wanted to give a quick shout out to the IntelliJ IDEA Ruby plugin team for working so fast to get a fix out the door.

I had posted a question on the JRuby Development list about running Ruby unit tests against JRuby from within IntelliJ IDEA using the Ruby plugin. A couple of days went by and one of the developers of the plugin contacted me, worked with me on solving my problem, and released a new version that supported what I needed within another couple of days.

That's awesome service.


The following was generated using a 7th order Markov chain and several of my blog posts as source text:

More...


When looping over collections, you might find yourself needing elements that match only a certain parameter, rather than all of the elements in the collection. How often do you see something like this?

foreach(x in a)
   if(x < 10)
      doSomething;


Of course, it can get worse, turning into arrow code. More...


A couple of weeks ago the UH Code Dojo embarked on the fantastic voyage that is writing a program to solve Sudoku puzzles, in Ruby. This week, we continued that journey.

Though we still haven't completed the problem (we'll be meeting again tenatively on October 15, 2007 to do that), we did construct what we think is a viable plan for getting there, and began to implement some of it.

The idea was based around this algorithm (or something close to it): More...


The last bit of advice from Chad Fowler's 52 ways to save your job was to be a generalist, so this week's version is the obvious opposite: to be a specialist.

The intersection point between the two seemingly disparate pieces of advice is that you shouldn't use your lack of experience in multiple technologies to call yourself a specialist in another. Just because you develop in Java to the exclusion of .NET (or anything else) doesn't make you a Java specialist. To call yourself that, you need to be "the authority" on all things Java. More...


A couple of days ago the UH Code Dojo met once again (we took the summer off). I had come in wanting to figure out five different ways to implement binary search. The first two - iteratively and recursively - are easy to come up with. But what about three other implementations? I felt it would be a good exercise in creative thinking, and pehaps it would teach us new ways to look at problems. I still want to do that at some point, but the group decided it might be more fun to tackle to problem of solving any Sudoku board, and that was fine with me.

Remembering the trouble Ron Jeffries had in trying to TDD a solution to Sudoku, I was a bit weary of following that path, thinking instead we might try Peter Norvig's approach. (Note: I haven't looked at Norvig's solution yet, so don't spoil it for me!) More...


Blaine Buxton has a nice post on Promises And String Concatenation.

In that post, Blaine notes that string concatenation "make[s] your code slow and consumes memory," and that you are often told to use something like StringBuilder (in Java) when doing a lot of string concatenations.

His position is that the language should abstract that for us and "do the right thing" when you use + (or the concatenation operator). Using + as a message to an object, it would be possible for us mere programmers to implement a string builder on top of + to really speed it up. Of course that's not the case in Java, but he shows an implementation of it in Ruby that, over 1 million iterations of concatenating 'a' to a string, takes only 23.8 seconds versus 4500+ the "normal way."

I'd like to see benchmarks in normal usage to see if that speed increase is typical in a system that uses tons of concatenation, but those numbers are still staggering.

And I agree the language should do it for us, assuming it is possible. I add the clause about possibility there because I can't comprehend why it hasn't been done to begin with (nor have I thought a lot about it). Good catch Blaine.

Update: Chad Perrin notices that String#<< and String#concat do the same thing.


A couple of evenings ago, after I wrote about how I got involved in programming and helped a friend with some C++ (he's a historian), I got inspired to start writing a scripting engine for a text-based adventure game. Maybe it will evolve into something, but I wanted to share it in its infancy right now.

My goal was to easily create different types of objects in the game without needing to know much about programming. In other words, I needed a declarative way to create objects in the game. I could just go the easy route and create new types of weapons like this: More...


Like many programmers, I started doing this because of my interest in video games. I was 6 years old when I first touched a computer. It was an Apple IIe and I would play a game involving Donald Duck, his nephews, and a playground (I forget the name of the game). I was hooked, and took every available chance to play that I could.

Subsequently, I got a Nintendo and played all sorts of games. Super Mario Bros. was my favorite, of course, and it greatly inspired me. After a while, I was spending more time planning and drawing levels in my notebook for two-dimensional side-scrolling video games than I was playing them. It wasn't long before I envisioned my own game console. More...


Yesterday, Ola Bini (from the JRuby team) described a new feature in JRuby that lets you steal methods from one class and add them to an object of another class. Ordinarily, you could only reuse methods through modules (as mixins), or of course the usual inheritance or aggregation. Police Line: Do Not Cross

It turns out someone wrote evil.rb, which does that and more in Ruby. Somehow, they are messing with Ruby's internals, or so I've read. I browsed the source quickly, and to be honest I don't have the experience to understand the trickery well enough to do a sam_larbi("evil.rb").inspect. My guess is that it will not work outside of MRI.

When Ola said the magic words - "there is no way to get hold of a method and add that to an unrelated other class or module" - I had to give it my own shot, however. More...


Bruce Eckel posted an article on how to use Flex with a Python back end over at Artima.

He said its possible to do the same thing "with any language that has support for creating an XML-RPC server."

In any case, I'm going to look into this in the future (I still haven't hopped onto the bandwagon). Anyone else played with it? What has been your experience?


This one refers to the 40+ minute presentation by Obie Fernandez on Agile DSL Development in Ruby. (Is InfoQ not one of the greatest resources ever?)

You should really view the video for better details, but I'll give a little rundown of the talk here. Obie starts out talking about how you should design the language first with the domain expert, constantly refining it until it is good - and only then should you worry about implementing it (this is about the same procedure you'd follow if you were building an expert system as well). That's where most of the Agility comes into play. More...


Sean Corfield responded in some depth to "Is Rails easy?", and explained what I wish I could have when I said (awkwardly, rereading it now) "I think my cat probably couldn't [code a Rails app]."

Sean makes it quite clear (as did Venkat's original post) that it isn't that using a framework, technology, or tool in general is easy or hard (although, you can certainly do things to make it easier or harder to use). In many cases, what it does for you is easy to begin with - in the case of Rails, it is stuff you do all the time that amounts to time-wasting, repetitive, boring busy-work. Rather, the right way to look at them is that they are tools that make you more productive, and it takes a while to learn to use them.

If you go into them thinking they are easy, you're likely to be disappointed and drop a tool that can really save you time before you learn to use it. And that could be tragic, if you value your time.


Want to get a report of a certain session? I'll be attending No Fluff Just Stuff in Austin, Texas at the end of June. So, look at all that's available, and let me know what you'd like to see.

I haven't yet decided my schedule, and it's going to be tough to do so. I'm sure to attend some Groovy and JRuby sessions, but I don't know which ones. In any case, I want to try to leave at least a couple of sessions open for requests, so feel free to let me know in the comments what you'd like to see. (No guarantees though!). Here's what I'm toying with so far (apologies in advance for not linking to the talks or the speakers' blogs, there are far too many of them =)): More...


I take my second weekend in a row (mostly) off of a computer, and look at all the cool things happening!

Adobe releases AIR (previously known as Apollo) and Flex 3 public beta, both products have been on my list of things to do for quite some time, still with no action taken.

Ruby (MRI) released bug fixes in version 1.8.6. JRuby officially went 1.0 (though it has yet to be posted to the website as I write this). And Ruby.NET released version 0.8 (IronRuby uses its scanner and parser, according to the article -- and this happened a couple of days before the weekend). More...


As I was trying to find a reference today for golfing (in code), I came across CodeGolf.com, a site for Perl, Python, PHP, and Ruby golfers. Looks like fun if you're into "good code ruined," as the site's tagline calls it (the point is to solve the problem using the least number of (key) strokes).

Enjoy!


Last night Thomas Enebo announced on Ruby Talk that JRuby 1.0 RC 3 has been released, and that it "will likely be our final release candidate before our 1.0 release."

I'm interested to deploy a web app trying Ruby on Rails with JRuby (or JRuby on Rails, perhaps), and also in experimenting with Sean Corfield's Scripting for CF 8 to run Ruby within ColdFusion.

Anyone else planning to do good things with JRuby?


I've been wanting to do a Ruby Quiz now for quite some time, but I've always had some excuse about being too busy. But this week's Ruby Quiz is FizzBuzz, so I had to take the two minutes and write up a solution.

Some of the discussion on Ruby Talk has been around getting the smallest solution possible (even though the quiz directs us to do as we might for a job interview). There are plenty of claims ranging from 56 to 72 bytes. I couldn't even get under 100, so I'm quite interested to see the different solutions when they are published - not because I think code so terse as to be unintelligible is something we should strive for, but because surely I'll learn new tricks (and some of which I'd expect are understandable!). More...


The Lone Star Ruby Conference has recently announced the 2007 dates and call for papers. The paper deadline is rather short - June 10, 2007, and the conference itself will be September 7-8, 2007 in Austin, Texas (for only $200).

I haven't decided yet whether I'll be making the drive up to Austin for it. That's right around my birthday and Austin City Limits Music Festival is the weekend after, so I've got some decisions to make. In any case, I thought I'd let ya'll Texans know about it (who don't already).


Kenji HIRANABE (whose signature reads "Japanese translator of 'XP Installed', 'Lean Software Development' and 'Agile Project Management'") just posted a video (with English subtitles) of himself, Matz (creator of Ruby), and Kakutani-san (who translated Bruce Tate's "From Java To Ruby" into Japanese) to his blog. According to Matz (if I heard correctly in the video), Kenji's a "language otaku," so his blog may be worth checking out for all you other language otakus (though, from my brief look at it, it seems focused between his company's product development and more general programming issues).

In any case it's supposed to be a six part series where the "goal is to show that 'Business-Process-Framework-Language' can be instanciated as 'Web2.0-Agile-Rails-Ruby' in a very synergetic manner, but each of the three may have other goals." The first part discusses the history of Java, Ruby, and Agile. I found it interesting and am looking forward to viewing the upcoming parts, so I thought I'd link it here.


Peter Bell's presentation on LightWire generated some comments I found very interesting and thought provoking. (Perhaps Peter is not simply into application generation, but comment generation as well.)

The one I find most interesting is brought up by several people whose opinions I value - Joe Rinehart, Sean Corfield, Jared Rypka-Hauer, and others during and after the presentation. That is: what is the distinction between code and data, and specifically, is XML code or data (assuming there is a difference)? More...


For background and history on partial order planners, see What is Partial Order Planning?, Selected History of POP Part 1, and POP History Part 2. Or, you can read the entire thing in PDF format.

Our goal is to give commands to the partial order planner, telling it what the goal is, the initial state (if it exists), and actions it can perform. The actions contain the name of the action, any preconditions that must be fulfilled before that action can be performed, and a set of effects the action has on the world state. After giving this information to the planner, it should output a plan if one exists.

For simplicity's sake, I've used a STRIPS-like notation, without the complexity of existentially or universally quantified variables, among other things. Further, only one possible plan is returned, rather than attempting to find all plans. The one returned is not guaranteed to be optimal, though (inadequate) tests have shown that it is correct. Plans are to improve these limitations in the future, moving to a less restrictive ADL-style syntax, and adding support for returning multiple plans. More...


Apparently, at MIX07, Microsoft announced a new open source project to get Ruby running on the CLR. InfoQ and CNET talk about it just a little bit.


This morning has been strange. On the drive to work, I started out thinking about encapsulation, and how much I hate the thought of generating a bunch of getAttribute() methods for components that extend cfrails.Model (in cfrails, of course). To top it off, I don't know how I'd generate these methods other than to write them to a file and then cfinclude it. But as I said, I really hate the idea of (say in the views) having to write code like #person.getSocialSecurityNumber()#. That's just ugly.

But then again, I don't like the alternative of leaving them public in the this scope either, because then there is no method to override if you wanted to get or set based on some calculations (of course, you could provide your own, but you'd have to remember to use them, and the attributes themselves would remain public. Currently, this is the way its done, because I feel like providing default getters and setters is not really encapsulating anything on its own. The encapsulation part only enters the game when you are hiding some implementation of how they are calculated or set. More...


YAGNI, KISS, and the simplest thing that could possibly work reared their heads again (at least for me) at the April meeting of the UH Code Dojo. Luckily for me, a couple of our members bailed us out of what could have been a disaster - greatly complicating a simple problem. (And my apologies for waiting so long to write this up - with finals and final projects all due these couple of weeks, I've just been super busy, as all you other students know all too well).

We decided on using a recent Ruby Quiz as our problem: Microwave Numbers. The basic idea is: given a number in seconds, identify the most efficient way to push the buttons (based on distance) to get that number of seconds (the actual problem left some room for fuzziness, but we didn't bother with that). This boils down to calculating the distance between any two numbers on the pad, and determining if the number of seconds is greater than 60 (in which case, there will be 2 options to check). Well, at least thats what we came up with. More...


Wow, six posts in one day. I'm exhausted. My last link to InfoQ today comes in thanking them for the timely post Ruby Domain Specific Languages Buzz. There, I got that out of the way.

It is timely for me, because a couple of weeks ago I decided I was going to try to implement a Partial-Order Planner DSL in Ruby. I haven't yet started, nor have I decided on a full course of action. But, I do have a vague strategy outlined in my head, and while I have yet to decide if I will be using the code provided by Reginald Braithwaite in his post about "an Approach to Composing Domain-Specific Languages in Ruby," the content will probably prove helpful. Another link they put was to Creating DSLs with Ruby posted by Jim Freeze to Artima's Ruby Code and Style.

I'll let you know how my progress goes. I'll probably start a little survey of what Partial-Order Planning is - similar to my paper on k-means - and cover some research about it first and post piece by piece to build my paper this time, rather than waiting to post it all at once. I'm not married to that approach, so you might see some code first ... but I'm leaning that way.


It had been a while since I visited InfoQ, but the other day I got one of their mailings in my inbox, and tons of it was relevant to my interests (even more so than normal). Rather than having a separate post for all of it, I decided to combine much of it into this post.

First, this post let me know that Thoughtworks has released CruiseControl.rb, which is good news for Ruby users who also want continuous integration. I've yet to use it, but those guys are a great company and it seems like everything they touch turns to gold. More...


Update: Ruby 1.9.3 adds the ability to use ranges as arguments to rand, which produces more obvious code. So if you're using it, instead of using "magic offsets" like I did in the original post (as Joni Orponen mentions in the comments below), it would be better to use rand(1..6) to simulate a die roll.

So to summarize: if you need a percentage between 0 and 1, just call rand. If you need an integer between 0 and x (not including x), you can still call rand(x). Finally, if you need a number in a specific range, just call rand(x..y) where x is the lower bound of the range, and y is the higher end.

(And recall that if you want a non-inclusive range, you can use 3 periods, like rand(1...100) to get numbers from 1 to 99. Although if you're typing the number out, it's certainly better to use 1..99, if you had used a variable in the higher part of the range, the 3rd period is preferable to 1..(x-1), in my opinion.)

The original post follows:

Another quick note today... I surprisingly have yet to need a random number in Ruby up to this point (or forgot if I did), so I went through a little hassle trying to find out how. Turns out, you can simply use rand(int). So, if you needed a random integer to simulate a roll of a six-sided die, you'd use: 1 + rand(6). A roll in craps could be simulated with 2 + rand(6) + rand(6).

Finally, if you just need a random float, just call rand with no arguments. After that, you can modify the range as you normally would in anything else (i.e., using addition and multiplication).

I guess I used some crappy search terms, because I couldn't find this via google, and I didn't see it skimming the usual suspects in the Ruby docs.


Our second meeting of the UH Code Dojo was just as fun as the first. This time, we decided to switch languages from Java to Ruby. And although we started quite slowly (we came unprepared and undecided on a problem and a language), we pretty much finished the anagram problem.

Now, I mentioned it was slow at first - because we were trying to decide on a problem. I'm guessing we spent about 30-45 minutes just looking over Ruby Quiz and then moving on to Pragmatic Dave's Code Kata. We learned from our experience though, and resolved to determine before-hand what we would do in the future. In any case, we finally decided on anagrams as our problem, and one of us mentioned something to the effect of "I don't know about you all, but I use Java too much at work." Of course, there's not much you can say to an argument like that - Ruby it was!

Since we found ourselves violating YAGNI at the first meeting, we decided to do a little more discussion of the problem before we started coding. One of the initial paths we explored was looping over each letter and generating every possible combination of letters, from 1 to n (n being the length of the input). We then realized that would need a variable number of nested loops, so we moved on to recursion. After that, we explored trying to use yield in conjunction with recursion, in an isolated environment. I don't recall the reasoning behind it, but whatever it was, we were starting to discover that when we passed that fork on the road a few minutes back, we took the path that led to the cannibals. (As a side note, if you're unfamiliar: yield sits in a function, which takes a closure as an argument, and runs the code in the closure -- I think that's a simple way of putting it, anyway).

After smelling the human-stew awaiting us, we backtracked a little and started looking for another idea. Enter idea number two: I'm not sure how to describe it in words, so I'll just show the code now and try to explain it afterwards:

char_count = Array.new(26).fill(0)
dictionary = ['blah', 'lab', 'timmy', 'in', 'hal', 'rude', 'open']

word = "BlAhrina".downcase

word.each_byte { |x| char_count[x - ?a] += 1 }

dictionary.each do |entry|
   char_count2 = char_count.clone
   innocent = true
   entry.each_byte do |letter|
     index = letter - ?a
     if char_count2[index] > 0
       char_count2[index] -= 1
     else
       innocent = false
       break
     end
   end
   puts entry if innocent
end

That's it: quite simple. First we initialize an array with a cell corresponding to each letter of the alphabet. Each cell holds a number, which represents the number of times that letter is used in out input, called word. These cells are set by using the line word.each_byte {...}.

Then for each entry in the dictionary, we do something similar: loop through each letter. If the total count for each letter goes to 0, we have a match (and in our case, simply print it to the standard output device). It's really a simple, elegant solution, and I think we're all glad we didn't go down the painful path of recursion. It would be fairly trivial to add a file which contained a real dictionary, and loop over that instead of each word in our array, but we didn't have one handy (nor did we happen to notice that Dave had provided one). And it would have been just an extra step on top of that to find all the anagrams in the dictionary.

I know this is just a silly little problem that you're not likely to encounter in real life, but it shows how even the simplest of problems can be tough without some thought, and I found it to be great practice. In particular, one problem we had was with trying to use TDD. Although we spent some time looking for tests we could write, and ways to test, and we even wrote an empty test thinking about what to put in there - none of us seemed to find anything to test. Now that we see the solution, it's fairly easy to figure out how to test it, but trying to drive the design with the test was proving fruitless for us. Dave alluded to this on the Kata page:
Apart from having some fun with words, this kata should make you think somewhat about algorithms. The simplest algorithms to find all the anagram combinations may take inordinate amounts of time to do the job. Working though alternatives should help bring the time down by orders of magnitude. To give you a possible point of comparison, I hacked a solution together in 25 lines of Ruby. It runs on the word list from my web site in 1.5s on a 1GHz PPC. It’s also an interesting exercise in testing: can you write unit tests to verify that your code is working correctly before setting it to work on the full dictionary.
I didn't read that before we had started (in fact, it wasn't until we had finished that anyone noticed it), but as you can tell, this exercise performed as promised. Our solution was under 25 lines, and while we didn't test it on his word list, I think our results would have been comparable (in fact, I wouldn't be surprised if we had the same basic solution he did).

Thoughts anybody?


One of the things I've been dreading is getting Rails to work with IIS, although it appears to be getting easier (last time I checked, there was no such "seamless integration"). But eWeek has some good news. They note that core developer on the JRuby project, Charles Nutter
said the JRuby project will announce, possibly as soon as this week, that JRuby supports the popular Ruby on Rails Web development framework. Ruby on Rails is sometimes referred to as RoR or simply Rails.

"We're trying to finish off the last few test cases so we can claim that more than 95 percent of core Rails tests passed across the board," Nutter said.

Moreover, the JRuby team is inviting Rails developers to try out real-world usage of JRuby and help them find any Rails issues the unit tests do not cover, or any remaining failures that are crucial for real applications, Nutter said.

Support for Ruby on Rails is important because "once Rails can run on JVM alongside other Java apps, existing Java shops will have a vector to bringing Rails apps into their organizations. They won't have to toss out the existing investment in servers and software to go with the new kid on the block," Nutter said.
The article also mentions "Microsoft is looking at support for Ruby developers and broader uses of Ruby, including having it run on the CLR."

Both bits of good news for fans of Ruby who want it to play well with Windows and IIS. Not to mention that using JRuby (or NRuby, if it will be called that for .NET) should open up all of those libraries available to Java/.NET developers, which has been considered by some to be one of Ruby's weaker spots.


The good folks at InfoQ have released another minibook, Mr. Neighborly's Humble Little Ruby Book. The PDF is free, and you can buy a print version for $9.95.

I haven't read it yet, but the description sounds like it would be a good introduction to the language. I've got the 2nd Pickaxe, which is available from PragProg. The Humble Little Ruby Book is considerably shorter (144 pages versus 864).

Another good, free resource for Ruby is the first edition of Programming Ruby, available at Ruby Docs. You might also check Introduction to Ruby on Rails for more resources.


When I was young and didn't know much about programming, I remember someone saying to me "functions can return only one value." I also remember thinking to myself, "then I'm going to be the guy to write a language that allows you to return multiple values." I was naive back then, to say the least.

Of course, there are plenty of ways to return more than one value from a function. In languages with pointers, like C and C++, you can pass in an "out" parameter to functions, and have the function dereference that pointer, setting values to it. In languages with ADTs, you can return say, a Point which would then encompass two or more variables. In many of these, you might have to do that via an out parameter as well.

Of course, there are arrays and structs and components in Coldfusion. And there are string lists in just about any language (some of which may be implemented via arrays).

But I always wanted to do something like this:
var_one, var_two, var_three = some_method()

Fortunately for me, Ruby allows you to do just that. It is implemented as an array (to my knowledge), but the syntax is so elegant you'd never know it: More...


Do you find yourself writing more classes in other languages than in Coldfusion? I do. For instance, I certainly develop more classes in Java than Coldfusion.

Is it due to the fact that I've developed bad habits in CF and haven't yet broken out of them (i.e., I'm just unable to spot needs for new classes) or is it because CF is so much more high-level than Java? A third option may be that the performance issues with instantiating CFCs contribute to me not wanting to break out? More...


For those that don't know, cfrails is supposed to be a very light framework for obtaining MVC architecture with little to no effort (aside from putting custom methods where they belong). It works such that any changes to your database tables are reflected immediately throughout the application.

For instance, if you change the order of the columns, the order of those fields in the form is changed. If you change the name of a column or it's data type, the labels for those form fields are changed, and the validations for that column are also changed, along with the format in which it is displayed (for example, a money field displays with the local currency, datetime in the local format, and so forth). I've also been developing a sort-of DSL for it, so configuration can be performed quite easily programmatically (not just through the database), and you can follow DRY to the extreme. Further, some of this includes (and will include) custom data types (right now, there are only a couple of custom data types based on default data types). More...


InfoQ has an interview with Ryan "zenspider" Davis, a "hardcore Ruby hacker." The interview covers several topics, but those of interest to me and the stuff I've been working on lately with cfrails include DSLs and metaprogramming. It doesn't give too much of an in-depth treatment of these topics, as it's only an interview, but I found it interesting so I thought I'd link it.


There are plenty of uses for closures, but two of the most useful ones I've found (in general) are when you really want/need to encapsulate something, and when you want to implement the Template Method pattern. Actually, implementing the Template Method pattern using closures may be misusing it, or I may be mischaracterizing it. It's more of like a "generalized" template method (particularly since we're not following the pattern, but implementing the intent). I still don't understand all of the Gang of Four patterns, so have mercy on me if I've gotten it wrong. =) More on all this below.

So as I get ideas from other languages, I always wonder "how can I use that idea in language X." For instance, I like the way Coldfusion handles queries as a data structure - so I tried to implement something similar in Java (which, I will eventually get around to posting). I encountered closures for the first time in Lisp a few years ago in an Artificial Intelligence course, I'm sure. But it wasn't until more recently in my experience with Ruby that I started to understand them. Naturally, I thought "could this be done in Coldfusion?" More...


OK, maybe its not the stupidist ever, but its almost on par with that error I get from time to time that tells me I need a primary key passed to cfupdate when I've got a primary key passed in, and to top it off it works sometimes (the cfupdate one). This one has to do with lists.

I love lists and list processing in Coldfusion. I use them for everything. But one thing I can't stand (which is something I feel I ought to be able to do), is when I get an exception because the list is too short (or sometimes too long). In this case, I was trying to delete an element from the list, but the element didn't exist. So, I got an "Invalid list index 0" error.

Maybe I'm too used to Ruby and its ability to index arrays with say, -1 to get the last element. But I don't feel its asking too much to have

<cfset listdeleteat(local.hotellist,listcontainsnocase(local.hotellist,"other"))>

not bomb if listcontainsnocase returns 0.

How do you feel? How often do you use lists? All the time like me?


So, I was playing around a little in Ruby and noticed that DateTime is a subclass of Date, yet the method today is not defined for it. I asked Venkat about it (in an email), he inspected the source code (why didn't I think of that?), and he replied that
the culprit! is line 1261 in date.rb, within DateTime class
class << self; undef_method :today end rescue nil
I thought it was interesting: Certainly this violates LSP, yet certainly a DateTime shouldn't have the method today. So, are there instances where it makes sense to violate LSP, in favor of keeping up with the metaphor?

I wonder why Date isn't a subclass of DateTime, rather than the other way around? At least for this case, it would not have violated LSP. So, I posted about this on the Ruby-Talk mailing list - I'll update you when I hear back from that group.

Update: I just realized if we made Date a child of DateTime, we'd get a similar problem in that we'd be removing the time part from the class. How would you resolve it?

Update 2: After some thought and some help from the Ruby community, I'm not so sure this is a violation of LSP. You see, the method today can only be called on Date, not an object of Date. So therefore, there is no violation when an object of Date is replaced by one of DateTime. Robert Klemme chimed in with this, which of course I addressed above, but he said it much better than I did:
Once can certainly argue whether DateTime *is a* Date or rather *has a* Date. But it is definitively clear that Date *is not* a DateTime simply because it does not provide the same set of information that DateTime provides (date *and* time)
So in the end, it appears as if there is no problem at all. Sorry for being alarmist - I guess I should have tested it first, right? =).


Given a class LeapYear with method isleap? and a data file consisting of year, isleap(true/false) pairs, we want to generate individual tests for each line of data. Using Ruby, this is quite simple to do. One way is to read the file, and build a string of the code, then write that to a file and then load it. That would certainly work, but using define_method is a bit more interesting. Here is the code my partner Clay Smith and I came up with:

require 'test/unit'
require 'leapyear'
class LeapYearTest < Test::Unit::TestCase
   def setup
     @ly = LeapYear.new
   end
   def LeapYearTest.generate_tests
     filename = "testdata.dat"
     file = File.new(filename, "r") #reading the file
     file.each_line do |line| #iterate over each line of the file
      year, is_leap = line.split; #since a space separates the year from if it is a leap year or not, we split the line along a space
      code = lambda { assert_equal(is_leap.downcase=="true", @ly.isleap?(year.to_i)) } #create some code
      define_method("test_isleap_" + year, code) #define the method, and pass in the code
     end
     file.close
   end
end

LeapYearTest.generate_tests

One thing to note, that I initially had trouble with, was the to_i. At first, it never occurred to me that I should be using it, since with Coldfusion a string which is a number can have operations performed on it as if it were a number. In Ruby, I needed the to_i, as isleap? was always returning false with the String version of year.

A more interesting item to note is that in the line where we define the method, if you were to attach a block like this:

define_method("test_isleap_"+year) { assert_equal(is_leap.downcase=="true", @ly.isleap?(year.to_i)) }

Then the solution will not work. It creates the correct methods, but when it evaluates them, it appears as though it will use the last value of year, rather than the value at the time of creation.


I could have sworn I had RadRails and Instant Rails working and was able to develop Ruby on Rails applications several months ago. But, I think I had a funktified setup, as yesterday I couldn't get it to work at all.

So, I went looking for what was wrong, and came across Matt Griffith's screencast about how to get started with Rails (in less than 5 minutes!).

The first thing to do was get InstantRails. I already had it, but I downloaded again just in case I had old versions of everything. Then, I followed his easy directions. I've restated them here, since I'm new to this and easily forget.

  1. Unzip Instant Rails where you want it to reside. I chose C:\InstantRails
  2. Start Instant Rails. Click the "OK" button to let it update the configuration file
  3. If IIS is running (you get port 80 is in use by inetinfo.exe, stop IIS by typing iisreset /stop at the command prompt
  4. Open a Ruby console window through Instant Rails by clicking The "I" button -> Rails Applications -> Open Ruby Console Window
  5. You should be in C:\InstantRails\rails_apps. If you are working on a new application, generate it by using the command: rails <project_name>. Matt called his demo, so the command was "rails demo."
  6. Move to the project directory, C:\InstantRails\rails_apps\demo
  7. Generate a controller: ruby script/generate controller <ControllerName>
  8. Generate a model: ruby script/generate model <ModelName>
  9. Create a migration by editing the file: C:\InstantRails\rails_apps\demo\db\migrate\001_create_posts.rb (assuming your model was called Post
  10. In the self.up method in that file, add the columns (one per line). For instance, t.column :title, :string on the first line, then t.column :body, :text (he is using a blog as an example).
  11. Open the configuration file for the database. This is found in C:\InstantRails\rails_apps\demo\config\database.yml. Basically, you can find the names of the databases you are going to need to create. We'll be doing demo_development.
  12. Start Apache to create the database using php administrator interface to MySQL. You can start Apache by clicking on Apache->Start in Instant Rails. Be sure to unblock it if Windows Security asks.
  13. Click I->Configure->Database (via PhpMyAdmin)
  14. That will open a browser to the admin page. Just type in the name of the database and submit the form. Ours is called demo_development.
  15. Stop Apache (in Instant Rails click Apache->Stop)
  16. Start WEBrick: In C:\InstantRails\rails_apps\demo, type the command: ruby script/server. If Windows asks, unblock it. Take note of the port it will be using.
  17. Set up the controller to have something. Open C:\InstantRails\rails_apps\demo\app\controllers\blog_controller.rb. In the class, type scaffold :post
  18. To create the database, run the migration. In C:\InstantRails\rails_apps\demo type the command: rake db:migrate
  19. Now you can go to http://localhost:3000 (or whatever port it is using). Here you'll see the "Welcome Aboard" page from Rails.
  20. To see your application, go to http://localhost:3000/blog. Play around, have fun.
If you are working on an existing application, obviously you can skip several of those steps (like, every one that involves creating a new application).

Now, I'll see about getting RadRails working in the next few days.


Since school has been back in, I've been much busier than (seemingly) ever. I haven't had the opportunity to do some of the things I've wanted (such as writing more in TDDing xorBlog), but I wanted to share my Wizard, which you can teach to learn spells. I should also note that this is the product of work with my partner, Clayton Smith.

We were given the assignment as a few unit tests:

require 'wizard'
require 'test/unit'

class WizardTest < Test::Unit::TestCase
   def setup
     @wiz = Wizard.new
   end

   def test_teach_one_spell
     got_here = false
     @wiz.learn('telepathy') { puts "I see what you're thinking"; got_here = true}
     @wiz.telepathy
     assert(got_here)
   end

   def test_teach_another_spell
     got_here = false
     spell_code = lambda { puts "no more clouds"; got_here = true}
     @wiz.learn('stop_rain', &spell_code)

     @wiz.stop_rain
     assert(got_here)
   end

   def test_teach_a_couple_of_spells
     got_here1 = false
     got_here2 = false
     @wiz.learn('get_what_you_want') { |want| puts want; got_here1 = true }
     @wiz.learn('sleep') { puts 'zzzzzzzzzzzz'; got_here2 = true}

     @wiz.get_what_you_want("I'll get an 'A'")
     @wiz.sleep

     assert(got_here1 && got_here2)
   end

   def test_unknown_spell
     @wiz.learn('rain') { puts '...thundering...' }

     assert_raise(RuntimeError, "Unknown Spell") {@wiz.raln }
   end
end

We simply had to make the tests pass:

class Wizard
   def initialize()
     @spells=Hash.new
   end
   def learn(spell, &code)
     @spells[spell]=code
   end
   def method_missing(method_id, *args)
     begin
       @spells["#{method_id}"].call(args)
     rescue
       raise("Unknown Spell")
     end
   end
end

Basically, all that happens is that when you create a Wizard, the initialize() method is called, and it creates a Hash to store spells in. Then you have a method, learn(), which takes as a parameter a block of code and stores that code in the Hash. Then when someone calls a method that doesn't exist for an object, Ruby automatically calls the method_missing() method. In this method, all I do is try to call the code stored in the hash under the name of the method they tried to call. If that doesn't work, I raise an exception with the message "Unknown Spell." Quite simple to do something so complex. I can't even imagine how I'd do something like that in a more "traditional" language (though, I can't say that I've tried either).

Can you imagine how cool it would be to say, have one programmer who wrote this Wizard into a game, and other programmers who just litter places in the game (in SpellBooks, consisting of Spells of course) with code that names the spell and specifies what it does? Without even needing to know anything about each other! Instantly extending what a Wizard can do, without even having to so much as think about changing Wizard - it's a beautiful world, indeed.


Oh my! I almost forgot the most important part in 'Beginning Ruby' - how to test your code!

require 'test/unit'
class MyTest < Test::Unit::TestCase
    def test_hookup
       assert(2==2)
    end
end

Running that in SciTE gives the following output:

Loaded suite rubyunittest
Started
.
Finished in 0.0 seconds.

1 tests, 1 assertions, 0 failures, 0 errors

On the other hand, if you change one of those twos in the assert() to a three, it shows this:

Loaded suite rubyunittest
Started
F
Finished in 0.079 seconds.

1) Failure:
test_hookup(MyTest) [rubyunittest.rb:4]:
<false> is not true.

1 tests, 1 assertions, 1 failures, 0 errors

The Ruby plugin for Eclipse gives a nice little GUI, however, where you can see the green bar (assuming your code passes all the tests). I also have a classmate who is writing a Ruby unit testing framework based on NUnit for his thesis, so it is supposed to be the bollocks. I'll let you all know more when I know more.


In case you haven't bought the 2nd Edition Pickaxe or found the 1st Edition of Programming Ruby: The Pragmatic Programmer's Guide, I'll be covering some of the basics of Ruby here. I've got both, but I haven't looked at the first edition in a couple of months, and haven't yet found the time to open the second edition and give it the attention it deserves.

But, I have been in class, so I thought I might go over some of the simple things in Ruby, with no real method to my madness. I'll just be going through different things as I remember them. Enjoy the lack of structure. You could actually copy and paste that into an IDE or .rb file and run it as-is if you wanted.

# the hash/pound/number symbol gives us a comment

# set a variable
val = 10;

#semicolons are optional per line. if you want more than one statement
#per line, you'll have to use it
something = 1; something_else = 2
puts something, something_else
puts '--------------------------'

# while loop putting 9 down to 0
while val > 0
    #'puts' puts a string to the console
    puts val = val-1
end
puts '--------------------------'
# or you can do
val = 10
puts val = val -1 while val > 0
puts '--------------------------'
val = 10
puts val = val -1 until val < 1
puts '--------------------------'
for i in 1..10 # .. shows us the range object
    puts i
end
puts '--------------------------'
9.upto(10) { |v| puts v }
puts '--------------------------'

9.downto(1) { |v| puts v }
puts '--------------------------'

condition = true
if condition
    puts "yes"
    puts "yoho"
else
    puts "no"
end
puts '--------------------------'

puts "yes" if condition
puts "no" unless condition

puts '--------------------------'

class Car #define a class called Car. Must begin with an uppercase letter
    attr_reader :miles, :fuel_level #like getMiles but auto-done for you
    attr_writer :fuel_level #like setFuelLevel, but can use on LHS of equation
    # you could also use:
    # def fuel_level=(lvl)
    # @fuel_level = lvl
    # end
    def initialize (year)# is called when an object is created
       @year = year # @varname lets us know that it is a member variable
       @miles = 0
       @fuel_level = 100
    end

    def drive #define a method called drive
       puts "we are driving the car for one mile"
       @miles += 1
       @fuel_level -= 1
    end
end

c1=Car.new(2006)
c1.drive
puts c1.fuel_level
# attr_writer example
puts c1.fuel_level=29

# the last statement is the one returned from a method
puts c1.drive

#attr_reader example
puts c1.miles.to_s + " miles driven" #to_s = toString
# one of my only beefs so far is that you cant simply do
# puts 1 + "sam"
puts '--------------------------'

# inheritance is done via the less than symbol <
class SoupedUpCar < Car
    def drive # will drive 3 times as fast with only 2 times the gas consumption
       @miles+=2
       @fuel_level -= 1
       super
    end
end

c2 = SoupedUpCar.new(2007)
puts c2.inspect #gives us info on the object (puts is there for output only)
puts c2.class #tells us the class of the object

#add a method to SoupedUpCar
class SoupedUpCar
    def burnout
       puts "smell the rubber?"
    end
end

#notice c2 has not been reinstantiated or anything
c2.burnout

Thats all for now. I'm starting to think I should have organized the code a little better. Maybe next time. I certainly need a colorizer for it.


In class on Wednesday Venkat explained so well, yet so succinctly, what I'm loving so much about Ruby: the signal to noise ratio is higher in Ruby than in most languages.

One of his examples was to take a program that does absolutely nothing in Java:

public class DoNothing
{
    public static void main(String[] args)
    {

    }
}

And compare it to this one in Ruby:




Notice the difference?

Incidentally, the high signal to noise ratio is also what I like so much about Coldfusion. To run a query, you just do it. You don't have to go through the hassle of creating connections, statements, and the like. Just type in your query and go. Of course the drawback in Coldfusion is that in many cases, there is a lot of noise. For example, to create an object I have to write <cfset someObj = createObject("component", "long.Path.To.CFC")>, and let's not mention the tag syntax (at least I can use <cfscript>, though I rarely do).

In any case, I find Java's database access so hard to work with, the last time I used it in any significant context I created a façade to do all the work for me. I'd just create an object of it, and pass in a query to run.

But, there's also a problem with building the queries in languages like Java and C#:

String theQueryString="select columnName from table" +
     " where someColumn = "
+ someValue +
     " and anotherColumn = " + anotherValue + " ... " +
     " order by " + orderBy;

Horrible! For long queries, that can get extremely unreadable. In Coldfusion if you need to create a multi-line string to keep it readable, you can simply do the following:

<cfsavecontent variable="theQueryString">
   put any text you want in here
   and as many lines as you
   want
</cfsavecontent>

And I was happy to find out you can do something similar in Ruby:

someVariable = <<DELIMITER_FOR_WHEN_YOUR_STRING_IS_DONE
   put any text you want in here
   and as many lines as you
   want
DELIMITER_FOR_WHEN_YOUR_STRING_IS_DONE

The next great surprise from Ruby? You can add methods to a class at run-time (there is no compilation) quite easily. Suppose I wanted the absolute value method to work on a string. I could just do:

class String
   def abs
      "absolute value of string"
   end
end

And no, it didn't overwrite the String class. So far, I am amazed. I know you can do the same thing in Coldfusion, but that doesn't make it any less awesome.



Google
Web CodeOdor.com

Me
Picture of me

Topics
.NET (19)
AI/Machine Learning (14)
Answers To 100 Interview Questions (10)
Bioinformatics (2)
Business (1)
C and Cplusplus (6)
cfrails (22)
ColdFusion (78)
Customer Relations (15)
Databases (3)
DRY (18)
DSLs (11)
Future Tech (5)
Games (5)
Groovy/Grails (8)
Hardware (1)
IDEs (9)
Java (38)
JavaScript (4)
Linux (2)
Lisp (1)
Mac OS (4)
Management (15)
MediaServerX (1)
Miscellany (76)
OOAD (37)
Productivity (11)
Programming (168)
Programming Quotables (9)
Rails (31)
Ruby (67)
Save Your Job (58)
scriptaGulous (4)
Software Development Process (23)
TDD (41)
TDDing xorblog (6)
Tools (5)
Web Development (8)
Windows (1)
With (1)
YAGNI (10)

Resources
Agile Manifesto & Principles
Principles Of OOD
ColdFusion
CFUnit
Ruby
Ruby on Rails
JUnit



RSS 2.0: Full Post | Short Blurb
Subscribe by email:

Delivered by FeedBurner