Рубиновый переключатель как идиома - PullRequest
0 голосов
/ 02 апреля 2010

Я недавно начал проект в Ruby on Rails. Раньше я делал все свои проекты в Python, но решил попробовать Ruby.

В проектах, которые я написал на Python, я использовал небольшую методику, объясняемую правильным ответом в этом посте:

словарь или оператор If, Jython

Я использую эту технику из-за отсутствия в Python встроенной функции переключения, а также избавления от больших блоков if else

Я пытался воссоздать описанный выше метод в Ruby, но, похоже, не совсем понял.

Может ли кто-нибудь мне помочь?

Ответы [ 3 ]

2 голосов
/ 02 апреля 2010

Если вам нужно только вызвать метод по его имени, хранящемуся в строке, стандартным способом Ruby для этого является использование метода Object#send:

def extractTitle dom
  puts "title from #{dom}"
end

def extractMetaTags dom
  puts "metatags from #{dom}"
end

dom = 'foo'

type = 'extractTitle'
send type, dom
#=> title from foo
type = 'extractMetaTags'
send type, dom
#=> metatags from foo

В противном случае вы можете использовать оператор Ruby case, как уже предлагалось.

2 голосов
/ 02 апреля 2010

Хотя ничто не мешает вам использовать подход, основанный на классах, почему бы не использовать оператор Rubys case?

case thing
when 'something'
   do_something
when 'nothing'
   do_nothing
else
   do_fail
end
0 голосов
/ 02 апреля 2010

Как уже говорили другие, есть альтернативные способы сделать это в Ruby, но если вам просто любопытно, то эквивалентен этому подходу Python в Ruby (использование Object # send , как только вы определились имя метода) будет:

class MyHandler
  def handle_test(arg)
    puts "handle_test called with #{arg}"
  end

  def handle_other(arg)
    puts "handle_other called with #{arg}"
  end

  def handle(type, *args)
    method_name = "handle_#{type}"
    if respond_to? method_name
      send(method_name, args)
    else
      raise "No handler method for #{type}"
    end
  end
end

Затем вы можете сделать:

h = MyHandler.new
h.handle 'test', 'example'
h.handle 'other', 'example'
h.handle 'missing', 'example'

и результат будет:

handle_test called with example
handle_other called with example
handle.rb:15:in `handle': No handler method for missing (RuntimeError)
        from handle.rb:23
...