【问题标题】:Ruby: metaprogramming methods based in model attributeRuby:基于模型属性的元编程方法
【发布时间】:2016-07-07 23:30:40
【问题描述】:

我正在尝试根据其 order 属性中的值向类公开一些方法,这可能类似于 ['top', 'bottom', 'right', 'lower-right']

首先,我的班级从该数组中删除任何响应空白的内容,如下所示:

def order
  order.split(' ').delete_if do |o|
    send(o).blank? if respond_to? o
  end
end

在那之后,我想“公开”top(例如)作为该类的方法。我在initialize 方法中尝试过这样的东西:

order.each do |o|
  V1_ATTRIBUTES << o.to_sym
  define_method(o) do |a|
    send(a).blank? ? '' : send(a)
  end
end

但是 o 在类未实例化时未定义,唉:

<NameError: undefined local variable or method `o' for #<Class:#<APIDocument:0x007fb8123609f8>>>

谁有更好的方法来获得这个结果?

注意:我知道允许用户编写实例方法名称不是很好的做法,但在这种情况下,安全性和损坏不是问题。

【问题讨论】:

  • 方法order的实现是否存在无限递归?
  • 不,这篇文章已经简化了。 :)

标签: ruby-on-rails ruby ruby-on-rails-4 metaprogramming


【解决方案1】:

您可以定义单例方法(每个对象的方法)。

def order
  orders.split(' ').map{|o| send(o)}.compact.each do |o| 
    singleton_class.send(:define_method, o) do
      send(o).to_s
    end
  end
end

但正如您所见,这只会弄乱您的代码。所以不要滥用元编程,明智地使用它。

【讨论】:

  • 啊!单例方法。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
  • 2014-01-07
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
相关资源
最近更新 更多