From: Andrea Dallera Date: 2010-03-16T05:46:08+09:00 Subject: Re: Overriding new? I should have been clearer in the example. This is the actual situation: class FreightViewModel def initialize do_some_init_stuff() end end and this is what it will become if i apply that solution: class FreightViewModel def new(*args, &block) obj = allocate obj.do_some_init_stuff obj.send(:initialize, *args, &block) return obj end end > What happens is the programmer *does* call super in initialize. > While sometimes it's ok for code to get run twice, sometimes it's not. > Be sure that if you are ensuring the parent class's initialize method > runs, that it doesn't foobar something if it runs twice because the user > called 'super'. Calling super shouldn't be a problem in this case: the constructor of the base class does nothing...right? > Are you sure there isn't an instance where someone would want to > subclass your class, but not run the parents initializer? One example > where I can think of this occurring is doing mocks for unit testing. I > may still want to use some of the functionality from your class (thus > subclassing it), but cut out some of the backing guts and replace them > with something I have control over. Good point. I'm taking care of this, in a way that provides a full stub (with all the dependencies stubbed and injected) for integration testing with one line of code, which was one of the initial objectives: i come from WPF and it can be a pain to write integration testing for a VM with even just 3 services, i wanted to be able to test without having to write huge and complex setups all the time. Still, one can think of other cases where a VM is is still needed "uninitialized": i guess i'll provide an hard switch if the case actually arises. Thanks a lot for all the suggestions! -- Andrea Dallera http://github.com/bolthar/freightrain http://usingimho.wordpress.com On Tue, 2010-03-16 at 04:14 +0900, Walton Hoops wrote: > On 3/15/2010 12:48 PM, Andrea Dallera wrote: > > Hei, > > > > I am uncertain about what to do: on one side I'm very aware that it > > would be a huge hack and, before all, using this kind of "template > > method" in the base class, and having every element to inherit from it, > > is very unflexible. On the other side i've been using freightrain for > > quite a while now and i really really like the syntactic sugar, so > > things like > > MyFactory.getInstance() do > > # user defines their behavior here > > end > > as Walton (which i thank for the pointer) suggested are a big no no. > > > > I like this way of doing it: > > def new(*a,&b) > > obj = allocate > > #do your stuff > > obj.send(:initialize,*a,&b) > > return obj > > end > > > > What do you think about it? Aside from the performance hit (in my case i really don't case), are there any motivation i'm not seeing for not using it? > > Also forbidding to specify the constructor would be a way to go but i'd like to allow as much freedom as possible. > > > > > I assume that '#do your stuff' is where you do things like call the > parents initializer? > 1) What happens is the programmer *does* call super in initialize. > While sometimes it's ok for code to get run twice, sometimes it's not. > Be sure that if you are ensuring the parent class's initialize method > runs, that it doesn't foobar something if it runs twice because the user > called 'super'. > 2) Are you sure there isn't an instance where someone would want to > subclass your class, but not run the parents initializer? One example > where I can think of this occurring is doing mocks for unit testing. I > may still want to use some of the functionality from your class (thus > subclassing it), but cut out some of the backing guts and replace them > with something I have control over. > > Provided you have thought about those two things, and still think this > is the right choice, then I see no problem with this code. > >