Howdy. I am a class. There are certain rules for what you are supposed to do when you subclass me, so as a sanity check I wish to introspect your subclass to make sure it's obeying the contract. However, my problem is that self.inherited is called too early. class C # this is me def self.inherited(p) #whatever super end end class B < C # this is you # C's self.inherited is called right here def yourFirstMethod # etc. end end So I can't, in my self.inherited, ask about what methods you have defined, because you haven't defined them yet. This must have come up before; is there an easy solution? Thx - m.
on 20.03.2009 17:26
on 20.03.2009 17:40
On 20.03.2009 17:22, matt neuburg wrote: > end > defined, because you haven't defined them yet. This must have come up > before; is there an easy solution? Thx - m. Even after the class definition methods can be added. You could catch that with method_added but if you require a minimum set of methods to be defined before class is used (e.g. instantiated) this will be difficult to track. One option would be to define method initialize in your class and do the check there. But this is still fragile because it might not be guaranteed that sub classes invoke it from their initialize... Another option would be to override the sub class's method "new" so you can do the check there. This might be a bit more robust but even "new" can be overridden by subclasses (although it isn't generally). I'd probably just omit the check. If any of your superclass methods invokes a method that is not defined you'll see this at runtime anyway. Kind regards robert
on 20.03.2009 19:38
On Mar 20, 2009, at 09:37 , Robert Klemme wrote: >> end > > even "new" can be overridden by subclasses (although it isn't > generally). > > I'd probably just omit the check. If any of your superclass methods > invokes a method that is not defined you'll see this at runtime > anyway. I agree with this in general for Matt's particular problem. The smalltalk pattern of defining all contracted methods and having them raise SubclassResponsibility is a good one to use in this situation. BUT... There have been many times where I've wanted a "class closed" hook to go along with inherited (essentially a "class opened" hook). Having both makes it very easy for me to do lots of things with my language tools. I can instrument added methods quite easily with that mechanism. It'd be nice to have this extra hook.
on 20.03.2009 19:55
2009/3/20 Ryan Davis <ryand-ruby@zenspider.com> >>> def self.inherited(p) >>> So I can't, in my self.inherited, ask about what methods you have >> > SubclassResponsibility is a good one to use in this situation. So, maybe a little helper: class Module def abstract_methods(*names) names.each do |name| define_method(name) { raise SubclassResponsibility } end end end For example class MyClass abstract_methods :foo, :bar end class Whizz < MyClass def foo; "foo!"; end end w = Whizz.new w.foo #=> "foo!" w.bar #=> error: SubclassResponsibility
on 20.03.2009 20:23
Robert Klemme <shortcutter@googlemail.com> wrote: > Another option would be to override the sub class's method "new" so you > can do the check there. This might be a bit more robust but even "new" > can be overridden by subclasses (although it isn't generally). That's a good idea, I'll look into it - thanks! m.
on 26.08.2009 09:27
matt neuburg wrote: > Howdy. I am a class. There are certain rules for what you are supposed > to do when you subclass me, so as a sanity check I wish to introspect > your subclass to make sure it's obeying the contract. Is this even a good idea? What if I wanted to create an abstract subclass that doesn't obey the contract -- which is OK because it won't be instantiated -- but whose own subclasses do?
on 26.08.2009 18:14
On Fri, Mar 20, 2009 at 8:35 PM, Ryan Davis<ryand-ruby@zenspider.com> wrote: > > BUT... There have been many times where I've wanted a "class closed" hook to > go along with inherited (essentially a "class opened" hook). Having both > makes it very easy for me to do lots of things with my language tools. I can > instrument added methods quite easily with that mechanism. It'd be nice to > have this extra hook. I am not sure I understand. Do you mean "class frozen hook"? I do not really know when a "class closed" hook should be triggered. Robert