Skip to Content Collective Idea Home

What’s “new” in Ruby

by Brian Ryckbost

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
# => #<Person:0x007fb3720b7020 @name="Brian", @loves_coffee=true>
> brian.name
# => "Brian"
> brian.loves_coffee?
# => true

> b = Person.allocate
# => #<Person:0x007fb37208ea08>
> 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?

Comments

Damien
::

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


Brian Ryckbost
::

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


Ismael Marin
::

Interesting, thank you Brian.


Nuwan Chaturanga
::

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


sam
::

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.


dave
::

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.


Alexis
::

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


Brian Ryckbost
::

*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.