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
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
What are some other lesser known ways of creating or initializing objects?
#inspect might call allocate on some objects (ActiveRecord, amongst others).
See this (closed) rails bug : https://github.com/rails/rails/pull/1297
Damien*: Fascinating. Looks like ActiveRecord also makes use of[email protected] for STI.
Interesting, thank you Brian.
another bit of ruby knowledge to my little brain. Thank you.
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.
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.
Here is a cool stuff you can do with allocate in order to have a nice factory: https://gist.github.com/270744
Nuwan Chaturanga*: Your welcome! I don't know how long[email protected] 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.