Ruby 类初始化

Fal*_*man 3 ruby constructor

我想创建一个可以用两种不同方式初始化的对象。我找到了 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
Run Code Online (Sandbox Code Playgroud)

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

  attr_accessor :id, :status, :dateTime
  def initialize hash = nil
    if hash != nil
    @id = hash['id']
      @status = hash['status']
      @dateTime = hash['dateTime']
    end
  end
Run Code Online (Sandbox Code Playgroud)

方法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
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Tom*_*Tom 5

我会尝试为您的构造函数使用散列,如下面的代码改编自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
Run Code Online (Sandbox Code Playgroud)

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

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

创建新对象 - 使用示例

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

my_new_example = Example.new :id => 1, :status => 'live'
#=> #<Example: @id=1, @status='live'>
Run Code Online (Sandbox Code Playgroud)

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

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>
Run Code Online (Sandbox Code Playgroud)

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

my_new_example.id = 24
Run Code Online (Sandbox Code Playgroud)