問題描述
Ruby 一種在條件下執行函數的巧妙方法 (Ruby a clever way to execute a function on a condition)
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:
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!
方法 2:
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 ;)
方法 3:
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);
(by user130076、Nick Lewis、Arthur、Matthew Scharley)