so collect always returns a Matrix. i had a disscussion a while back about
this sort of thing and would be very curious if you, or others, come up with a
generic solution.
-a
···
On Fri, 13 Dec 2002, Jim Freeze wrote:
–
====================================
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 am subclassing the Matrix class, and am having
difficulty getting ‘self’ for the derived class.
Consider the example below:
[code snipped]
include MyMatrix
m = MyMatrix::Matrix[[1,2],[3,4]]
puts m.type
puts m.to_f.inv.type
=== output
MyMatrix::Matrix
Matrix
How do I get self to be ‘MyMatrix’ so I can
chain methods, such as:
m.inv.add_col(c) ?
Does “m.inv.add_col(c)” work? The example you give that doesn’t work
involves #to_f. Now I presume this is ::Matrix#to_f (“Ruby in a Nutshell”
doesn’t mention Matrix#to_f, though), which would be inclined to return a
::Matrix.
There’s not much you can do about this, except redefine Matrix#to_f to return
“self.class.new”, if it can be done. Then, you can agitate for this change to
be included in the distribution.
i got given much crap for taking this approach not too long ago (note that i
agree with you). i really think self.class.new follows POLS… even if
dangerous…
i think i was advocating this (self.class.new) as a general library
practice…
-a
···
On Fri, 13 Dec 2002, Gavin Sinclair wrote:
There’s not much you can do about this, except redefine Matrix#to_f to return
“self.class.new”, if it can be done. Then, you can agitate for this change to
be included in the distribution.
(I could be barking up the wrong tree, though…)
–
====================================
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 think the following would work, but I need a clean way to wrap all the
public methods for Matrix. For some reason I was having trouble getting
the right result, so I made a test case with the classes A and B. Both
are show below.
require ‘matrix’
class A
private_class_method :new
def self.; new end
def inv; end
end
class B < A
def inv
super
self
end
end
class M < Matrix
def inv
super
self
end
def to_f
super
self
end
end
m = M[[1,2],[3,4]]
puts m.inv.class
puts m.to_f.class
b = B
puts b.inv.class
=== output
M
M
B
···
On Friday, 13 December 2002 at 9:48:15 +0900, ahoward wrote:
On Fri, 13 Dec 2002, Gavin Sinclair wrote:
i think i was advocating this (self.class.new) as a general library
practice…
–
Jim Freeze
“Life is like a buffet; it’s not good but there’s plenty of it.”
Well duh, as soon as I hit send I realized that I had not looked far
enough and that what I had posted would not work. The way Matrix is
currently written, it is nearly impossible to extend through
inheritance. So, instead of using a ‘is-a’ type class, below is a
’has-a’ type class. This method should work but has the drawback as
before, every public method of Matrix that you want exposed must be
wrapped.
require ‘matrix’
class M
def initialize(a) @m = Matrix[*a]
end
private :initialize
def self.
M.new(a)
end
def inv
M[*@m.inv.to_a]
end
def inv! # this is new. ie, not in Matrix @m = @m.inv
self
end
def to_f
M[*(@m.to_f.to_a)]
end
def to_f! # this is new and handy! @m = @m.to_f
self
end
def inspect; @m.inspect end
end
Matrix[[1, 2], [3, 4]]
m.class: M
m.to_f.class: M
m.to_f.inv.class: M
m.inv.class: M
m.to_f.inv.inspect: Matrix[[-2.0, 1.0], [1.5, -0.5]]
m.inv!.class: M
Matrix[[-2.0, 1.0], [1.5, -0.5]]
Well duh, as soon as I hit send I realized that I had not looked far
enough and that what I had posted would not work. The way Matrix is
currently written, it is nearly impossible to extend through
inheritance. So, instead of using a ‘is-a’ type class, below is a
‘has-a’ type class. This method should work but has the drawback as
before, every public method of Matrix that you want exposed must be
wrapped.
[…]
In effect, you are adding methods to the Matrix class, so why don’t you … ?
class Matrix
def all_my_wonderful_methods
…
end
end
Can’t you use method_missing hand off any calls you don’t explicitly
intercept to the matrix class contained in your class?
···
On Fri, Dec 13, 2002 at 02:08:54PM +0900, Jim Freeze wrote:
Well duh, as soon as I hit send I realized that I had not looked far
enough and that what I had posted would not work. The way Matrix is
currently written, it is nearly impossible to extend through
inheritance. So, instead of using a ‘is-a’ type class, below is a
‘has-a’ type class. This method should work but has the drawback as
before, every public method of Matrix that you want exposed must be
wrapped.
Well duh, as soon as I hit send I realized that I had not looked far
enough and that what I had posted would not work. The way Matrix is
currently written, it is nearly impossible to extend through
inheritance. So, instead of using a ‘is-a’ type class, below is a
‘has-a’ type class. This method should work but has the drawback as
before, every public method of Matrix that you want exposed must be
wrapped.
Couldn’t you use ‘method_missing’ and redirect calls to your class’ matrix
member (@m)?
Phil
“Or perhaps the truth is less interesting than the facts?”
Amy Weiss (accusing theregister.co.uk of engaging in ‘tabloid journalism’)
Senior VP, Communications
Recording Industry Association of America
I like open classes, and use this feature for my own classes on occasions,
but I am opposed in principle to modifying standard classes. Even
though, one would still have problems since some of the methods you
would expect to return self don’t. Thus you cannot chain methods when
you need to.
···
On Friday, 13 December 2002 at 14:14:14 +0900, Gavin Sinclair wrote:
Well duh, as soon as I hit send I realized that I had not looked far
enough and that what I had posted would not work. The way Matrix is
currently written, it is nearly impossible to extend through
inheritance. So, instead of using a ‘is-a’ type class, below is a
‘has-a’ type class. This method should work but has the drawback as
before, every public method of Matrix that you want exposed must be
wrapped.
Can’t you use method_missing hand off any calls you don’t explicitly
intercept to the matrix class contained in your class?
Or better still - a Delegator or Fowardable class.
In effect, you are adding methods to the Matrix class, so why don’t you …
?
class Matrix
def all_my_wonderful_methods
…
end
end
I like open classes, and use this feature for my own classes on occasions,
but I am opposed in principle to modifying standard classes. Even
though, one would still have problems since some of the methods you
would expect to return self don’t. Thus you cannot chain methods when
you need to.
I don’t blame you for not wanting to modify “standard” classes, but in this
case I would consider Matrix to be a third-party class that happens to be
packaged with Ruby. It’s hardly essential for Ruby’s operation (like String,
Array, etc.).
And if some of the methods can be plainly improved, I’d probably (for a simple
class like Matrix) modify them directly, prove the superiority over the
original with demonstrations in your code, and offer the improvements for
inclusion in the standard library. That way you’d be using the standard class
ahead of time!
I like open classes, and use this feature for my own classes on occasions,
but I am opposed in principle to modifying standard classes. Even
though, one would still have problems since some of the methods you
would expect to return self don’t. Thus you cannot chain methods when
you need to.
I don’t blame you for not wanting to modify “standard” classes, but in this
case I would consider Matrix to be a third-party class that happens to be
packaged with Ruby. It’s hardly essential for Ruby’s operation (like String,
Array, etc.).
Yes, but modifying it can cause alergic reactions in other third party
libs that I or others using my code may include. It’s a risk I don’t
want to take.
And if some of the methods can be plainly improved, I’d probably (for a simple
class like Matrix) modify them directly, prove the superiority over the
original with demonstrations in your code, and offer the improvements for
inclusion in the standard library. That way you’d be using the standard class
ahead of time!
I have considered modifying the class directly. I’m not sure how
successful I would be in getting my changes to ship with ruby.
···
On Friday, 13 December 2002 at 15:24:08 +0900, Gavin Sinclair wrote:
–
Jim Freeze
Just because your doctor has a name for your condition doesn’t mean he
knows what it is.