jgaskins/perpetuity

Creating objects in memory uses `Object.allocate`

Closed this issue · 1 comments

Currently, objects are not instantiated with .new because constructors may require parameters, which would raise an exception. Using allocate isn't necessarily a bad thing, but it could cause a lot of trouble (and confusion) if a class' constructor initializes variables that aren't initialized anywhere else.

class Widget
  def initialize
    @subwidgets = []
  end
end

@subwidgets will not be initialized. If it's one of the attributes that gets persisted, this isn't a problem, but if it isn't it will be nil after being retrieved from the DB when the object expects it to be an Array.

Been thinking about this and I think we could either enforce a rule that mapped classes respond to a naked .new call or we could provide some interface to specify arguments when loading from the DB so that we can instantiate with .new(*args). Something like this:

class Article
  attr_accessor :title, :body
  def initialize(title, body)
    @title, @body = title, body
  end
end

Perpetuity::Mapper.generate_for Article do
  attribute :title, String
  attribute :body, String

  default_args('', '') # When loading from the DB, this calls Article.new('', '')
end

However, I don't see how that is at all better than having default args inside the mapped class' initialize method: def initialize(title='', args='').