2015-09-14 4 views
3

У меня есть код, который запускается в одном из нескольких разных мест: в качестве инструмента командной строки с отладочным выходом, как часть более крупной программы, которая не принимает никакого вывода, и в рельсах Окружающая среда.Условные определяющие функции в Ruby

Есть случаи, когда мне нужно внести небольшие изменения в код основан на его месте, и я понял, что следующий стиль, кажется, работает:

print "Testing nested functions defined\n" 
CLI = true 

if CLI 
def test_print 
    print "Command Line Version\n" 
end 
else 
def test_print 
    print "Release Version\n" 
end 
end 

test_print() 

Это приводит к:

Testing nested functions defined 
Command Line Version 

Я никогда не сталкивался с функциями, которые условно определены в Ruby. Это безопасно?

Это не то, как я структурирую большую часть моего кода, но есть несколько функций, которые требуют полной перезаписи для каждой системы.

+2

Посмотрите на 'define_method': http://apidock.com/ruby/Module/define_method;) – MrYoshiji

ответ

6

Я не думаю, что это чистый способ.

Мое предложение состоит в том, чтобы определить одни и те же наборы методов (с разными органами определения) в разных модулях и условно включить соответствующий модуль в класс/модуль, из которого вы собираетесь вызывать методы.

module CLI 
    def test_print 
    ... # definition for CLI 
    end 
end 

module SomeOtherMode 
    def test_print 
    ... # definition for some other mode 
    end 
end 

class Foo 
    include some_condition ? CLI : SomeOtherMode 
end 

Foo.new.test_print 

Если вы только собираетесь использовать только один режим за бега, и думают, что это пустая трата для определения модулей, которые в конечном итоге не используются, то вы можете сделать еще один шаг; определите соответствующие модули (CLI, SomeOtherMode, ...) в отдельных файлах и используйте autoload.

autoload :CLI, "path/to/CLI" 
autoload :SomeOtherMode, "path/to/SomeOtherMode" 
1

Это мета-программирование и, как правило, безопасно. Реальный риск заключается не в том, что он будет работать так, как ожидалось, но и при тестировании всех вариантов, которые вы создаете.

Пример, приведенный здесь, делает невозможным выполнение альтернативной версии. Чтобы правильно использовать оба метода, вам нужен способ принудительного впрыска того или другого.