Peter V. wrote in post #1034787:
Very curious to hear how this design could be improved with duck typing.
Correct me if I’m wrong, but I think Steve was trying to say that using
abstract base classes with purely abstract methods are useless. I
mean, it’s just there to raise
an exception, but the exception would have been raised anyway (a
NotMethodError). In Ruby, interface is everything, so instead of seeing
if something is a kind_of? Team, just check if it responds_to? :play and
code the interface that way.
In your case, the base class is taking care of things that all accounts
do. In my view, this is a fine, and it’s not really a ruby abstract
base class because you’re not raising explicit exceptions on abstract
methods (you have no abstract methods), and you can still instantiate
that class. In your case, this is just a base class, not an ‘abstract’
base
class. If however, you’re providing real implementation
through actual methods that do stuff, I think Steve would agree that we
should move base implementations to a superclass.
Ruby seems to promote polymorphism through duck-typing more than
checking i f something belongs to a certain base class.
As for passing through the module chain, i came up with a quick hacky
way of doing it after reading through this thread.
class A
end
module B
MODULE = :b
def foo(mod=nil)
if respond_to? :passable?
return(super) unless mod == MODULE
end
‘from module B’
end
end
module C
MODULE = :c
def foo(mod=nil)
if respond_to? :passable?
return(super) unless mod == MODULE
end
‘from module C’
end
end
a = A.new
class A
include B
end
p a.foo => ‘from module B’
class A
include C
end
p a.foo => ‘from module C’
module Passable
def passable?
true
end
end
a.extend Passable
p a.foo :b => ‘from module B’
p a.foo :c => ‘from module C’
Pretty straightforward, and could be rewritten fairly easily to pass all
methods on to super if that were required. Tell me what you guys think.
I think undef’ing a method is fairly brutal in this situation.
-Luke