使用Object.const_get和.send初始化类

时间:2014-11-25 21:47:37

标签: ruby-on-rails ruby ruby-on-rails-3

我正在尝试编写一个方法,该方法将初始化(.new(...)并在从字符串中找到的类上调用.run方法,该字符串将替换大量重复代码。这是旧的,有效的方法(有很多类似的):

def facebook
  @share = params[:share_document]
  ::Documents::SendToFacebook.new(@document, @share).run
end

新的“meta-”方法如下所示:

def send_to_provider
  provider = params[:provider]
  @share = params[:share_document] || nil
  klass = "send_to_#{provider}".classify
  p = class_send(klass, :new, @document, @share)
  return true if p.run
end

class_send(受this启发)看起来像这样:

def class_send(class_name, method, *args)
  return nil unless Object.const_defined?(class_name)
  c = Object.const_get(class_name)
  c.send(method, *args)
  c
end

我似乎无法从c方法访问send_to_provider对象,即无法找到p.run的类未正确返回与c。我必须在:new方法中调用:run而不是send_to_provider来初始化对象。

如何从:run方法初始化并调用send_to_provider对象?

修改

当前代码给出了这个错误:

Completed 500 Internal Server Error in 574.9ms

NoMethodError (undefined method `run' for nil:NilClass):
  app/controllers/documents_controller.rb:98:in `send_to_provider'

2 个答案:

答案 0 :(得分:3)

您正在向班级发送:new,然后忽略结果,这似乎是错误的。然后你就回到课堂上并试着打电话给:run,这似乎也错了。

你的意思是写:

def class_send(class_name, method, *args)
  return nil unless Object.const_defined?(class_name)
  c = Object.const_get(class_name)
  c.send(method, *args)
end

这并没有解释您报告的错误消息,虽然我不确定是什么:如果原始方法返回的值是nil(如错误消息所暗示的那样),那么我们应该看到send失败(因为nil没有回复:new)。

答案 1 :(得分:0)

@Todd Agulnick的回答很有帮助,但这是一个引起我特殊问题的命名空间问题。

这解决了我的问题:

c = ::Documents.const_get(klass).new(@document, @share)

非常简单。