Ruby元编程实现动态方法?

想通过元编程实现以下代码。

@resource = {}
@voters = {}
@is_upvoted = {}

def resource(comment)
  @resource[comment.id]
end

def voters(comment)
  @voters[comment.id]
end

def is_upvoted(comment)
  @is_upvoted[comment.id]
end

如何使用ruby元编程创建这些方法并访问哈希?

您能告诉我代码中的错误吗?

['resource','voters','is_upvoted'].each do |attribute|
  define_method("#{attribute}") do |comment|
    instance_variable_set("@#{attribute}",comment.id)
  end
end
xiaoge1073 回答:Ruby元编程实现动态方法?

这似乎是多余的:

@resource = {}
@voters = {}
@is_upvoted = {}

由于您已经在循环数组中进行元编程。

您可以尝试以下方法:

class Foo 

  %w(
    resource
    voters
    is_upvoted
  ).each do |attr_sym|
    define_method attr_sym do |comment|
      instance_variable_set("@#{attr_sym}",{}) unless instance_variable_get("@#{attr_sym}")
      instance_variable_get("@#{attr_sym}")[comment.id]
    end
  end

end

我相信它将为您提供大致类似的方法:

class Foo 

  def resource(comment)
    @resource ||= {}
    @resource[comment.id]
  end

end

就个人而言,在您的方法中使用comment.id对我来说似乎并不好。因为如果有一天您想使用其他属性(或其他属性)作为key,怎么办?

所以,我想我会这样做:

class Foo 

  %w(
    resource
    voters
    is_upvoted
  ).each do |attr_sym|
    define_method attr_sym do |key|
      instance_variable_set("@#{attr_sym}",{}) unless instance_variable_get("@#{attr_sym}")
      instance_variable_get("@#{attr_sym}")[key]
    end
  end

end

现在,您似乎想要一种简单的方法来在实例变量上设置键值对,所以我想我会尝试以下方法:

class Foo 

  %w(
    resource
    voters
    is_upvoted
  ).each do |attr_sym|
    define_method attr_sym do |key=nil|
      instance_variable_set("@#{attr_sym}",{}) unless instance_variable_get("@#{attr_sym}")
      hsh = instance_variable_get("@#{attr_sym}")
      return hsh[key] if key
      hsh
    end
  end

end

在这种情况下,您应该能够做得到(假设您有一个@comment变量来响应id):

@comment.id 
 => 1 
foo = Foo.new
 => #<Foo:0x000056536d7504b0>
foo.resource 
 => {}
foo.resource[@comment.id] = :bar
 => :bar 
foo.resource 
 => {1=>:bar}
foo.resource[@comment.id]
 => :bar
,
  

您能告诉我我的代码有什么问题吗?

它等效于此:

def resource(comment)
  @resource = comment.id
end

instance_variable_get是一个更好的选择。

,

这是我使用它的方法,并且有效

['resource','voters','is_upvoted'].each do |attribute|
  define_method("#{attribute}") do |comment|
    instance_variable_get("@#{attribute}")[comment.id]
  end
end
本文链接:https://www.f2er.com/3159201.html

大家都在问