From: MonkeeSage Date: 2007-12-06T11:25:00+09:00 Subject: Re: Worth an RCR? static_type_check, polymorphic_type_check, quacks_like On Dec 5, 7:08 pm, Trans wrote: > On Dec 5, 6:48 pm, John Carter wrote: > > > > > Is there another library like this? I would love it if it were just > > standard methods on Object. > > > I find this very useful and 'require' it into all code I write. Just > > helps me mop up those problems that static type checking would have > > found for me... > > > Heres a typical usage, create an object and initialize it with > > stuff. Only much later when you invoke the methods on the object do > > you find you initialized it with the wrong stuff. > > > Got the parameter order wrong or something. But then the bug isn't on > > the backtrace. So put when you initialize your instance variables you > > can type check'em like so... > > > eg. > > class MyObject > > def initialize( _name, _drawable, _theme) > > @name = _name.static_type_check String > > @drawable = _drawable.polymorphic_type_check Drawable > > @theme = _theme.quacks_like :border_color, :fill_colour > > end > > Special methods? Just do: > > def initialize( _name, _drawable, _theme) > raise ArgumentError unless _name.instance_of?(String) > raise ArgumentError unless _drawable.kind_of?(Drawable) > raise ArgumentError unless [:border_color, :fill_color].all?{|m| > _theme.respond_to?(m)} > @name, @drawable, @theme = _name, _drawable, _theme > end > > Besides, with exception to the 2nd (done for the right reason) this is > all generally considered a bad practice. If you want to do it for > debugging purposes that's cool --wrap the the check in an 'if $DEBUG'. > But the idea behind duck-typing is to NOT do these types of checks. > Just let it ride, so we can drop whatever we want into your method -- > if our object is "adapted" right then it can work regardless. > > Note: I used to think the last made sense. But I've learned over time > that it actually is worse --you're assuming those methods dictate some > type of behavior, but those methods might not do what you think they > do. Use of respond_to? should be generally avoided. > > T. Heh. I used to think the opposite about respond_to?, but for a while I've been thinking about it as not asking for a promise of behavior, but for a promise that it's safe to act like we have a promise of behavior. Just like when we use "begin...rescue NoMethodError", we're not saying "now I've ensured X object will behave well", we're saying "now I can safely pretend like object X implements some interface" The only difference *at all* that I see between asking respond_to? and using a "begin...rescue NoMethodError" clause, is that one asks for permission and the other asks for forgiveness (i.e., the only difference is the point in time at which they occur). That said, there are problems with method signature validation by respond_to?, as many people have pointed out before, e.g., method_missing dispatching with variable arity. So, while I would agree that it may not often be a good idea, pragmatically, I disagree with the idea that it *necessarily* promotes a wrong way of thinking about programming (or at least programming in ruby). Regards, Jordan