views:

236

answers:

3

Hey,

As a bit of a fun project I'm implementing a Beatnik interpreter in Ruby. If you've never heard of Beatnik it's an esoteric programming language in which operations are specified by the "scrabble score" of the words in the source code.

Anyway, the implementation requires a different operation to happen for different scrabble scores. This isn't particularly to implement, one obvious ways is an if statement:

if score == 1
...
elsif score == 2
...
else
...
end

Another way would be to use a case statement:

case score
when 1
  ...
when 2
  ...
else
  ...
end

But neither of these two methods strikes me as particularly elegant, can you suggest an alternative way of implementing this?

+1  A: 

I'm sure Ruby supports delegates in some fashion... I don't know Ruby, so I can't provide a sample in correct syntax, but the idea is to create an array of references to a function, then call into the array:

lookupArray[score](param1, param2);
Matthew Scharley
+5  A: 
commands = {
  1 => ->(p1,p2) {...},
  2 => ->(p1,p2) {...},
  3 => ->(p1,p2) {...},
}

commands[score].call(p1,p2)

Insert your code in place of the ...'s, and your parameters in place of p1,p2. This will create a hash called commands, from integer scores to anonymous functions (-> is short for lambda). Then you look up the appropriate function based on the score, and call it!

Nick Lewis
Just FYI: -> instead of "lambda" will only work in Ruby 1.9. In Ruby 1.8.x, you will need to write out the full lambda {|p1, p2| ... }
Yehuda Katz
+2  A: 

You could create an hash, mapping scores to code:

ScoreMapping = { 
  1 => lamda { do_some_stuff },
  2 => eval("do_some_other_stuff"),
  3 => Proc.new { some_thing_even_more_awesome }
}

Eval is not very pretty, but you could do some other stuff like

eval "function_for_score_of_#{score}"

with it. Given score == 1, it would call function_for_score_of_1.

For the difference between proc and lambda take a look at this. It is mostly harmless ;)

Arthur