Since the thread “Inheritance question” has become so deep (physically and
my point is sort of orthoganal to it, new thread.
I personally don’t believe it makes sense to create a class that inherits from
Matrix. Doing so would suggest to me that you are creating a new kind of
Matrix. If you are, then perhaps you should visit a local mathematician to see
whether there really is more than one kind of Matrix. Same goes for Array and
probably some others.
In Jim’s case, he wanted to add some methods to Matrix. Well, he didn’t want
to change Matrix directly, but the methods he was going to add would in no way
be out of place in the real Matrix class, so to me, inheritance is the wrong
approach. Delegation is the key here. Create a new class based on Matrix, add
your methods, and forget that Matrix ever existed.
Of course, I think there are some implementation problems he had with the type
that was returned from some methods - I lost track. But maybe he can come up
with a new kind of delegation that solves that.
The Stack class in Java was an extension of Vector, which everybody’s favourite
Ruby advocate Bruce Eckel (!) pointed out in his “Thinking in Java” is a
stoopid idea. Whoever heard of a Stack having a method “elementAt(i)” ???
Anyway, I hope we see a satisfactory solution to Jim’s implementation problem.
This kind of thing has been generating a lot of interest.
Since the thread “Inheritance question” has become so deep (physically and
my point is sort of orthoganal to it, new thread.
I personally don’t believe it makes sense to create a class that inherits from
Matrix. Doing so would suggest to me that you are creating a new kind of
Matrix. If you are, then perhaps you should visit a local mathematician to see
whether there really is more than one kind of Matrix. Same goes for Array and
probably some others.
I’ve always had a fondness for inheriting from Array and
Hash… though, you point out in your example, it can be overkill,
leaving an object with methods that really have nothing to do with it.
But sometimes the fit is rather good – those core classes are core
for good reasons. I’ve never thought of it in terms of claiming that
there’s a new kind of Array or Hash; I see it more as just
incrementally building on the available components of the language.
In Jim’s case, he wanted to add some methods to Matrix. Well, he didn’t want
to change Matrix directly, but the methods he was going to add would in no way
be out of place in the real Matrix class, so to me, inheritance is the wrong
approach. Delegation is the key here. Create a new class based on Matrix, add
your methods, and forget that Matrix ever existed.
I spot an opportunity to learn more about delegation, something which
I’ve never really absorbed. Can you elaborate a bit on the conditions
under which delegating would be a better choice than inheriting in
this example?
Of course, I think there are some implementation problems he had with
the type >that was returned from some methods - I lost track. But maybe
he can come up >with a new kind of delegation that solves that.
Isn’t there a Delegate mixin that can take the pain away?
Russ
···
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.422 / Virus Database: 237 - Release Date: 20/11/2002
Yes, that is what I want. The Matrix class has a sticky issue since it
uses a class method constructor. But, if I overlook that temporarily, I
think the delegator class would need the ability to wrap functions that
were chainable and return self. I believe it is as simple as that. But
I have not come up with a good syntax for that and I don’t think I have
had the ‘ah-ha’ moment about delegators yet.
···
On Saturday, 14 December 2002 at 22:36:11 +0900, Gavin Sinclair wrote:
Since the thread “Inheritance question” has become so deep (physically and
my point is sort of orthoganal to it, new thread.
In Jim’s case, he wanted to add some methods to Matrix. Well, he didn’t want
to change Matrix directly, but the methods he was going to add would in no way
be out of place in the real Matrix class, so to me, inheritance is the wrong
approach. Delegation is the key here. Create a new class based on Matrix, add
your methods, and forget that Matrix ever existed.
Of course, I think there are some implementation problems he had with the type
that was returned from some methods - I lost track. But maybe he can come up
with a new kind of delegation that solves that.
Saturday, December 14, 2002, 4:36:11 PM, you wrote:
Of course, I think there are some implementation problems he had with the type
that was returned from some methods - I lost track. But maybe he can come up
with a new kind of delegation that solves that.
i think just the same. current delegation classes never mind about this issue
I’ve always had a fondness for inheriting from Array and
Hash… though, you point out in your example, it can be overkill,
leaving an object with methods that really have nothing to do with it.
But sometimes the fit is rather good – those core classes are core
for good reasons. I’ve never thought of it in terms of claiming that
there’s a new kind of Array or Hash; I see it more as just
incrementally building on the available components of the language.
I used to inherit from HashMap in Java occasionally, but it always felt dirty.
It’s great to built on the language’s components, but inheritance isn’t the
only way to build. That’s one of my great realisations from Ruby. Inheritance
used to be the path of least resistance. Now I treat inheritance as a
significant design decision that has to be justified. I use it less than
before, thus when it is used, its purpose is more clear.
In Jim’s case, he wanted to add some methods to Matrix. Well, he didn’t
want
to change Matrix directly, but the methods he was going to add would in no
way
be out of place in the real Matrix class, so to me, inheritance is the
wrong
approach. Delegation is the key here. Create a new class based on Matrix,
add
your methods, and forget that Matrix ever existed.
I spot an opportunity to learn more about delegation, something which
I’ve never really absorbed. Can you elaborate a bit on the conditions
under which delegating would be a better choice than inheriting in
this example?
Well, I think of inheritance as specialising a class (as in Car < Vehicle).
You encapsulate objects when you want to make use of them (so a Stack
encapsulates an Array, as does a Matrix). I think of delegation as wholesale
encapsulation - you want to use all of an object. Thus, delegation provides
all the methods you want, and gives you the opportunity to build on them. I
was hoping to provide an example, but it’s getting very late and I’m fighting
with the syntax.
Wholesale delegation and inheritance are only subtly different. I’d like to
hear if you have reason to prefer inheritence in these situations. The Pickaxe
reference section has some interesting examples on delegation.
Of course, I think there are some implementation problems he had with
the type >that was returned from some methods - I lost track. But maybe
he can come up >with a new kind of delegation that solves that.
Isn’t there a Delegate mixin that can take the pain away?
Russ
Yes, he would begin with
require ‘delegate’
class MyMatrix < DelegateClass(Matrix)
# …
end
and by examining the Pickaxe section on it, because when I tried delegating
Array I had trouble instantiating my new class.
When I mentioned a “new kind of delegation” I meant that the return values of
the delegated methods might be doctored (class-wise). I don’t know whether
that would be an issue (as in the “Inheritance Question” thread) and I
certainly don’t know if my off-the-cuff new-delegation thought would be
feasible.
Yes, that is what I want. The Matrix class has a sticky issue since it
uses a class method constructor. But, if I overlook that temporarily, I
think the delegator class would need the ability to wrap functions that
were chainable and return self. I believe it is as simple as that.
Yes, it is simple as that *but* the wrapped functions *must not* return
self, but must return an object which is a delegator and this only in some
special cases.
Sorry, but being new to delegators, can you show an example of “but must
return an object which is a delegator…”
Thanks
···
On Sunday, 15 December 2002 at 0:45:45 +0900, ts wrote:
Yes, that is what I want. The Matrix class has a sticky issue since it
uses a class method constructor. But, if I overlook that temporarily, I
think the delegator class would need the ability to wrap functions that
were chainable and return self. I believe it is as simple as that.
Yes, it is simple as that but the wrapped functions must not return
self, but must return an object which is a delegator and this only in some
special cases.
–
Jim Freeze
The computing field is always in need of new cliches.
– Alan Perlis
Sorry, but being new to delegators, can you show an example of "but must
return an object which is a delegator..."
Here what do DelegateClass in delegate.rb
def DelegateClass(superclass)
klass = Class.new
methods = superclass.instance_methods(true)
methods -= ::Kernel.instance_methods
methods |= ["to_s","to_a","inspect","==","=~","==="]
klass.module_eval <<-EOS
def initialize(obj) @obj = obj
end
EOS
for method in methods
klass.module_eval <<-EOS
def #{method}(*args, &block)
begin @obj.__send__(:#{method}, *args, &block)
rescue
$@[0,2] = nil
raise
end
end
EOS
end
return klass;
end
All wrapped function return the result of
@obj.__send__(:#{method}, *args, &block)
where @obj in your case is a Matrix Object
When you write
m = MyMatrix[[1,2],[3,4]]
n = MyMatrix[[1,2],[3,4]]
o = m + n
ruby will call the method #+ for @obj which is a Matrix and fatally the
result is a Matrix when you want an instance of MyMatrix
i’ve been out of this thread for a while, but i wanted to back up a bit and
ask again what people find so fundementally wrong with the paradigm of
creating classes as in :
class PotentiallyExtended
def PotentiallyExtended.class_method
PotentiallyExtended.new
end
def instance_method
type.class_method
end
end
classes which do this are certainly better candidates for subclassing. in
the Marix case, it may or may not be the best idea due to the associative
properties of some of operators but that is not the point. if class designers
hardwire classname.methodname into instance methods they forbid all sorts of
interesting behaviour. coding Matrix in this way would not of changed the way
it functions and would have allowed subclassing for the irreverant. i know
people get religious about subclassing but the fact remains that, regardless
of the design principles, it can sometimes be the case that
class MyClass < Array
end
or even
class MyClass < Matrix
end
can get the job at hand done quickly in the fewest lines of code; bearing in
mind that the number of code lines is also a measure of design that many
scientific studies have shown to be one of the more important ones.
getting back to the Matrix example, i’d like to see an example of Delegation
in the case of the ‘+’ method which provides this behaviour :
p (MyMatrix[] + MyMatrix[]).type # >> MyMatrix
i’m not saying it can’t be done… i’d just like to see an example on par in
complexity with the subclassing method.
-a
···
–
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================
i've been out of this thread for a while, but i wanted to back up a bit and
ask _again_ what people find so fundementally wrong with the paradigm of
creating classes as in :
Nothing wrong.
classes which do this are certainly better *candidates* for subclassing. in
the Marix case, it may or may not be the best idea due to the associative
properties of some of operators but that is not the point.
There is where you are wrong, it exist some case where it's inappropriate
to always make this choice.
interesting behaviour. coding Matrix in this way would not of changed the way
it functions *and* would have allowed subclassing for the irreverant.
No it will just give the possibility to have strange result :-)), like
A + Array ==> A
Array + A ==> Array
can get the job at hand done quickly in the fewest lines of code;
Yes, but nobody can predict the class of the result :-))
There are very good reasons for the actual behavior of Array.