【问题标题】:Ruby class initializationRuby 类初始化
【发布时间】:2016-07-10 16:02:37
【问题描述】:

我想创建一个可以用两种不同方式初始化的对象。我找到了 3 种不同的方法来完成同一件事,我想知道我的哪种方法是最好的,以及是否有另一种更好的方法。

方法

attr_accessor :id, :status, :dateTime
  def initialize *args
    if args.length == 1
      puts args[0]
    @id = args[0]['id']
    @status = args[0]['status']
    @dateTime = args[0]['dateTime']
    else
      @id = args[0]
      @status = args[1]
      @dateTime = args[2]
    end
  end

方法二:(注意我需要在这一种上手动设置参数作为第二种方式)

  attr_accessor :id, :status, :dateTime
  def initialize hash = nil
    if hash != nil
    @id = hash['id']
      @status = hash['status']
      @dateTime = hash['dateTime']
    end
  end

方法3:(注意我需要在这个上手动设置参数作为第二种方式并且和我的第二种方式几乎相同,只是不在构造函数中)

attr_accessor :id, :status, :dateTime
  def initialize
  end

  def self.create hash
    if hash != nil
      obj = Obj3.new
      obj.id = hash['id']
      obj.status = hash['status']
      obj.dateTime = hash['dateTime']
      return obj
    end
  end

提前致谢!

【问题讨论】:

  • 他们有什么论据?
  • Method 2: (note that I need to set the parameters by hand on this one as second way) 第二种方法/方式遵循第二种方式不是很明显吗?
  • @sawa 也许我需要更清楚一些。它需要一个带有 id、status 和 dateTime 的哈希,或者我可以初始化一个不带参数的对象并说 object.id = "an id" 等。

标签: ruby constructor


【解决方案1】:

我会尝试为您的构造函数使用哈希,如下面的代码改编自DRY Ruby Initialization with Hash Argument

class Example
  attr_accessor :id, :status, :dateTime

  def initialize args
    args.each do |k,v|
      instance_variable_set("@#{k}", v) unless v.nil?
    end
  end
end

这样在构造函数中设置每个属性就变成了可选的。因为 instance_variable_set 方法将设置每个属性,如果 has 包含它的值。

这意味着您可以支持任意数量的方式来构造您的对象。唯一的缺点是您可能需要在代码中进行更多的 nil 检查,但如果没有更多信息就很难知道。

创建新对象 - 使用示例

要使用这种技术创建一个新对象,您只需将哈希传递给您的初始化程序:

my_new_example = Example.new :id => 1, :status => 'live'
#=> #<Example: @id=1, @status='live'>

而且它足够灵活,可以使用一个构造函数创建多个没有特定属性的对象:

my_second_new_example = Example.new :id => 1
#=> #<Example: @id=1>

my_third_new_example = Example.new :status => 'nonlive', :dateTime => DateTime.new(2001,2,3)
#=> #<Example: @id=1, @dateTime=2001-02-03T00:00:00+00:00>

创建对象后,您仍然可以更新您的属性:

my_new_example.id = 24

【讨论】:

  • 但是现在我需要能够通过哈希或通过与对象的交互来设置值,例如将对象初始化为 obj = Example.new; obj.id = "一个 id"
  • 不完全-我将通过一些用法示例更新答案。
  • 所以如果我理解正确的话,我可以用任意数量的参数来初始化对象,没有给出的将被置为nil,我可以在以后设置它们吗?另外,如果我理解正确,我可以说 my_new_example = Example.new my_new_example.id = 23
  • 对于您的第一点。是的,只要您定义您的属性(到目前为止在示例中使用 attr_accessor),那么您就可以使用哈希初始化您的对象。关键是你的参数的名称和设置它的值。如果您的哈希不包含属性的键/值,则该属性将为 nil。你的第二点。是的,只要 my_new_example.id = 23 在新行上,您就可以这样做!
  • @FalingDutchman 您也可以只使用OpenStruct 类,它允许您使用值进行初始化,但也可以在事后设置任意值。话虽如此,如果您想使用它,我建议将attr_accessor 添加到初始化块中,例如self.class_eval { attr_accessor k} 在 args 循环中,这将为每个属性创建 getter/setter 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 1970-01-01
  • 2017-11-30
  • 2012-06-15
  • 2011-03-26
  • 2011-06-21
  • 1970-01-01
相关资源
最近更新 更多