Ruby умный способ выполнить функцию по условию - PullRequest
3 голосов
/ 30 июня 2009

В качестве забавного проекта я использую интерпретатор Beatnik в Ruby. Если вы никогда не слышали о Beatnik, это эзотерический язык программирования, в котором операции задаются «скраббл-счетом» слов в исходном коде.

В любом случае, реализация требует другой операции для разных оценок скрэббл. Это не особенно для реализации, одним из очевидных способов является утверждение if:

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

Другой способ - использовать оператор case:

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

Но ни один из этих двух методов не кажется мне особенно элегантным, можете ли вы предложить альтернативный способ реализации этого?

Ответы [ 3 ]

9 голосов
/ 30 июня 2009
commands = {
  1 => ->(p1,p2) {...},
  2 => ->(p1,p2) {...},
  3 => ->(p1,p2) {...},
}

commands[score].call(p1,p2)

Вставьте ваш код вместо ... и ваши параметры вместо p1, p2. Это создаст хеш, называемый командами, от целочисленных значений до анонимных функций (-> сокращение от лямбда). Затем вы ищите соответствующую функцию на основе оценки и вызываете ее!

2 голосов
/ 30 июня 2009

Вы можете создать хэш, сопоставляя баллы с кодом:

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

Eval не очень хорош, но вы могли бы заняться чем-то другим, например

eval "function_for_score_of_#{score}"

с этим. Учитывая счет == 1, он вызвал бы function_for_score_of_1.

Для разницы между proc и lambda взгляните на this . В основном безвреден;)

1 голос
/ 30 июня 2009

Я уверен, что Ruby каким-то образом поддерживает делегатов ... Я не знаю Ruby, поэтому я не могу предоставить пример с правильным синтаксисом, но идея состоит в том, чтобы создать массив ссылок на функцию, затем вызов в массив:

lookupArray[score](param1, param2);
...