Условный код в блоке define_method - PullRequest
2 голосов
/ 01 октября 2010

Я генерирую некоторые методы на лету. Тело метода варьируется в зависимости от определенных критериев. Я полагался на class_eval для генерации условного кода.

%Q{
  def #{name}
   #{
   (name != "password") ? "attributes[:#{name}]" : 
                         "encrypt(attributes[:#{name}])"
   }
  end
}

Недавно я начал использовать define_method. Как создать блоки условного кода при использовании define_method?

Редактировать 1

Вот возможные подходы, которые я рассмотрел:

1) Проверка имени во время выполнения:

define_method(name) do       
 if name == password
   decrypt(attributes[name])     
 else
   attributes[name]
 end
end

Это не предпочтительный метод, поскольку проверка выполняется во время выполнения.

2) Условное определение всего метода.

if (name == "password")
 define_method(name) do       
   decrypt(attributes[name])     
 end
else
 define_method(name) do       
   attributes[name]
 end
end

Недостатком этого подхода является необходимость повторять блок кода, просто меняя небольшую часть (так как мой метод содержит несколько строк кода).

1 Ответ

3 голосов
/ 01 октября 2010

Я думаю, что из-за замыканий вы можете сделать что-то вроде этого:

  define_method name do
    if name=='password'
      decrypt(attributes[name])
    else
      attributes[name]
    end
  end

Но проблема в том, что if будет оцениваться при каждом вызове метода. Если вы хотите избежать этого, вам нужно передать разные блоки в define_method для различного поведения. например,

if name=='password'
  define_method(name) { decrypt(attributes[name]) }
else
  define_method(name) { attributes[name] }
end

альтернативно вы можете передать lambda, выбранный оператором if.

define_method(name, name=='password' ? lambda { decrypt(attributes[name]) } : lambda { attributes[name] }

Одна вещь, о которой следует подумать, define_method может быть медленнее, чем использование eval.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...