Skip to content

Instantly share code, notes, and snippets.

@cookrn
Created April 3, 2012 07:03
Show Gist options
  • Save cookrn/2289945 to your computer and use it in GitHub Desktop.
Save cookrn/2289945 to your computer and use it in GitHub Desktop.
Ruby Object Constructors

What the what?!

Ruby objects can be built in a way such that they are easier to use/test/debug from the point of view that if you do not automatically run their intended functionality from the constructor, potential side-effects and bugs can be better examined.

In general, I find it helpful to consider a constructors' purpose constrained only to setting instance-level attributes based on the passed arguments or using pre-defined defaults. Anything outside of that, I would consider setting up a class-level factory method.

Consider creating semantically-named factory style class methods that create an object and then call a specific method.

I find this especially helpful for hand-rolled presenters and worker classes (e.g. for Resque).

Also, per feedback from ahoward, using class-level factory methods makes subclassing much easier to grok in terms of calling super.

BuilderA

Since instances of BuilderA will automatically have their build! method called, they cannot be easily used from IRB.

BuilderB

Instances of BuilderB can be instantiated and have their methods tested more atomically. Also, by stubbing the build! method, you can easily test the class-level factory method.

The Rabbit Hole

Dig into Class::allocate re: overriding Class::new. This is also a tip from ahoward.

class BuilderA
def initialize( my_arg )
@my_arg = my_arg
build!
end
def build!
p "build #{ @my_arg }"
end
end
__END__
>> b = BuilderA.new "hi"
build hi
class BuilderB
def self.build!( my_arg )
builder = new my_arg
builder.build!
end
def initialize( my_arg )
@my_arg = my_arg
end
def build!
p "build #{ @my_arg }"
end
end
__END__
>> b = BuilderB.new "wut"
>> b.build!
build wut
>> BuilderB.build! "there we go"
build there we go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment