【问题标题】:Ruby Custom Super InitializationRuby 自定义超级初始化
【发布时间】:2010-11-22 23:11:00
【问题描述】:

这是我的情况:

  • XMLRPC::Client 有一个代理构造函数new3,它接受选项的哈希值。它取出各个值,然后将构造委托给默认初始化程序initialize
  • 我来自XMLRPC::Client。我想要一个 XMLRPC::Client 但具有一些附加功能的类。
  • 我也希望能够使用选项哈希来实例化这个派生类。这意味着在派生类的初始化程序中,我必须以某种方式使用 new3 代理构造函数实例化 super

我的问题是,如果可能的话。如果不是,那么解决这个问题的唯一方法是实际上将XMLRPC::Client.new3 方法中的代码“复制并粘贴”到我的派生类的构造函数中?

原因我问这个只是为了看看是否有解决这个问题的方法,因为在 Ruby 社区中有这个反复出现的主题 DRY(不要重复你自己) .但当然,如果这是唯一的方法,它不会杀了我。

【问题讨论】:

  • 哇,呃,你能把问题整理一下,让它反映你想问的问题吗?您现在要问几个问题:“我的问题是”、“我将重申我的问题”、“我的问题是”。如果需要的话,没关系,只要把它放在同一个主题上,一般都是同一个问题。
  • @Greg:我确实清理了这个问题,只是我在问题的前一个正文上做了一个“删除线”,而不是在人们阅读它的情况下完全删除它。我现在要删除它 :) 我真的希望您没有尝试通读问题中被删除的部分,哈哈,它被删除是有原因的。

标签: ruby xmlrpcclient


【解决方案1】:

我只是发布一个答案,通过向您展示如何编写 XMLRPC 的代码来补充其他答案

def new3(hash={})

      # convert all keys into lowercase strings
      h = {}
      hash.each { |k,v| h[k.to_s.downcase] = v }

      self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'],
               h['use_ssl'], h['timeout'])
    end

http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/xmlrpc/rdoc/classes/XMLRPC/Client.html

【讨论】:

  • 是的杰里米,我在我的问题中提到了这一点......我知道 new3 是如何定义的。我的问题是我是否必须将 new3 中的代码复制并粘贴到派生类的构造函数中。重复代码没有多大意义,特别是因为它在我派生的类中。我的问题如果这是唯一的方法,如果是这样,那很好,我会这样做。
  • 我或其他人在哪里说过您必须复制和粘贴代码?您需要做的就是在您的类方法中调用new3 并返回该实例。就像new3 调用new 的方式一样。
  • 我不是在指责任何人说过这样的话……我是在询问是否是这样。问题是我确实调用了 new3 但它一直说它是一个未定义的方法。
  • 好的,谢谢,所以我认为没有真正的方法可以做我想做的事。没问题,我将在派生类的初始化程序中重用 new3 中的代码。
  • 好的,这让我想问:Arlen 的回答有什么问题?你还需要访问超类的new3吗?
【解决方案2】:

在您的派生类中创建一个新的类方法(就像他们首先创建 new3 所做的那样):

class MyDerived < XMLRPC::Client
    def self.new3(hashoptions)
         client = XMLRPC::Client.new3(hashoptions)
         # Do further initialisation here.
    end
end

myone = MyDerived.new3(:abc => 123, ...)

super 只适用于initialize(并且只将参数更改为超类的initialize),所以这里不适用。

【讨论】:

  • 从这些答案来看,我认为我的问题太误导了,我会重新陈述。我并不是说我想要在派生类中使用 new3 方法。另外,我是从 XMLRPC::Client 派生的,所以将其设为 client = 没有多大意义,还是我弄错了?
  • 您基本上需要创建一个工厂方法,该方法返回您想要的对象的实例,按照您想要的方式构建。你不能像在 java 中那样在 ruby​​ 中重载构造函数,所以你必须这样做。
  • @Jorge:如果它是一个类方法(请注意它是self.new3),你会这样做。在这种情况下,您是否只想让MyDerived.new 使用XMLRPC::Client.new3?在这种情况下,只需重载self.new
【解决方案3】:

你应该可以在你的子类上调用new3

class MyClient < XMLRPC::Client
end
MyClient.new3({})

如果你需要做额外的事情,或者覆盖它:

class MyClient < XMLRPC::Client
  def self.new3(args)
    client = super(args)
    # do some more stuff
    client
  end
end
MyClient.new3({})

【讨论】:

  • 嗯..对不起什么? XMLRPC::Client 已经具有该类方法。这个问题的重点是看看是否有办法/避免/ new3 已经完成的工作。
  • 所以用yourNew替换new3,用new3替换new。没有?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多