define_method块中的条件代码

时间:2010-10-01 01:06:38

标签: ruby-on-rails ruby

我正在动态生成一些方法。方法体根据特定标准而变化。 我依靠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 个答案:

答案 0 :(得分:3)

我认为因为关闭你可以做这样的事情:

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

但问题是if将在每次调用方法时进行评估。 如果您想避免这种情况,则需要将不同的块传递给define_method以获得不同的行为。 e.g。

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

或者,您可以传递if语句选择的lambda

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

要考虑的一件事,define_method可能比使用eval慢。