2016-01-25 4 views
1

Я написал следующую рекурсивную функцию, чтобы разобрать некоторые настройки и правильно заполнить некоторые объекты файла журнала, которые у меня есть.Каковы альтернативы eval в Ruby?

Когда я запускаю этот код против Code Climate, он говорит мне, что (конечно) использование eval не рекомендуется. Есть ли способ, которым я могу переписать этот метод, поэтому мне не нужно eval, а также не нужно заявление case? Ничто не приходит на ум.

def parse(settings, logfile = nil) 
    settings.each do |key, value| 
    if value.is_a?(Hash) 
     logfile = Logmsg::LogFile.new 
     parse(value, logfile) 
    else 
     eval("logfile.#{key} = value") 
    end 
    end 
end 

Любые идеи?

Я пытаюсь использовать метод мета-программирования instance_variable_set, но я все еще сталкиваюсь с некоторыми проблемами. По какой-то причине мои тесты сейчас терпят неудачу из-за

Argument Error: comparison of Fixnum with String failed 

Я все еще пытаюсь понять это.

ответ

5

Поскольку присвоение атрибута объекта является просто синтаксический сахар для вызова метода (т.е. obj.foo = bar такой же, как вызов foo= метод на obj с аргументом bar), используйте Object#public_send:

logfile.public_send(:"#{key}=", value) 

В старшем коде вы часто видите send вместо public_send, но вы должны использовать последнее, так как оно вызывает ошибку, если вы попытаетесь вызвать частный метод.

+0

Hah! Хотел бы я увидеть ваш ответ после того, как вы его отредактировали! Мне потребовалось некоторое время, чтобы найти, что мне нужно было поставить «=» в имени метода или не найдет подходящего аксессора. Так или иначе! Это действительно сработало! Большое вам спасибо, я не знал об этом методе public_send! –

Смежные вопросы