What's "new" in Ruby

While updating Delayed Job’s YAML parser compatibility last week, Steve and I came across a Ruby method that neither of us had seen before, Class.allocate. Given that we were in the trenches of serializing and deserializing objects, this method caught our attention.

So, what’s it do? It allocates space for a new object of the class, but doesn’t call the initialize method on that new instance. Whoa… wait, what? You can create an object that skips the initialization of that object? Yes… but don’t think you’re going to go off and start using allocate willy nilly. In my eyes, it’s main use is in serialization, where you may want to split the allocation and initialization of the object in two steps.

Nonetheless, here’s a quick example showing the difference between new and allocate.

class Person
  def initialize(*args)
    @name         = "Brian"
    @loves_coffee = true
  end

  def loves_coffee?
    @loves_coffee || false
  end

  def name
    @name
  end
end

> brian = Person.new
# => #
> brian.name
# => "Brian"
> brian.loves_coffee?
# => true

> b = Person.allocate
# => #
> b.name
# => nil
> b.loves_coffee?
# => false

As you can see in the second group of results, when calling Person.allocate we’re given back a new instance of Person but without the initialized attributes. What’s interesting, though, is under the hood Ruby’s Class.new first calls allocate, then initialize.

What are some other lesser known ways of creating or initializing objects?

bryckbost@gmail.com

Comments

  1. October 05, 2011 at 17:44 PM

    #inspect might call allocate on some objects (ActiveRecord, amongst others).
    See this (closed) rails bug : https://github.com/rails/rails/pull/1297

  2. October 05, 2011 at 20:32 PM

    *Damien*: Fascinating. Looks like ActiveRecord also makes use of allocate@ for STI.

  3. October 05, 2011 at 22:24 PM

    Interesting, thank you Brian.

  4. nuwanchaturanga@gmail.com
    Nuwan Chaturanga
    October 06, 2011 at 0:47 AM

    another bit of ruby knowledge to my little brain. Thank you.

  5. sam_dolin@web.de
    sam
    October 06, 2011 at 3:08 AM

    it could be very interesting to use for factories and programming using factory patterns or delegation patterns. having an object in a state where usually no default values are stored in could also be used as fake lazy loading.

  6. dave@wegoto12.com
    dave
    October 06, 2011 at 4:39 AM

    This is very similar to how it is done in Objective-C, where the allocation and initialization of objects are separated, but some classes offer a “new” method which combines the alloc and init into a single call. I’ve never fully understood why they do this, but I think it has something to do with garbage collection.

  7. October 06, 2011 at 5:02 AM

    Here is a cool stuff you can do with allocate in order to have a nice factory: https://gist.github.com/270744

  8. October 06, 2011 at 8:30 AM

    *Nuwan Chaturanga*: Your welcome! I don't know how long allocate@ has been around, but in the nearly 5 years of programming Ruby, it was the first I’ve seen it. Love coming across stuff like this.