Dave Thomas <dave / pragprog.com> wrote in message news:<3EA7FF8F.3080500 / pragprog.com>... > I'm trying to get to grips with the 'mathn' library. I can see what it > _does_, but I'm trying to see why it does it. Is it emulating a mathn > library in some other language, or is it simply there to make arithmetic > more accurate? In math, 7 is an integer. It is also a rational number, a real number, and a complex number. The mathn library allows 7 to effectively be all of these by making Float, Fixnum, Bignum, Rational, and Complex all play nice with one another. In a program that requires mathn, we can treat 7 according to its mathematical properties rather than the properties of the class hierarchy. Also, as I've mentioned before, matrix.rb needs mathn.rb in order to work properly. The OO paradigm is rather alien to the mathematical mind. Mathematicians might think of the expression "3 + 7" in various ways, depending on their background and what they had for breakfast. But I'm sure damn few of them think of it as the object 3 receiving the method + with an argument of 7 ! So I've been surprised at how easy it is to write mathematical programs in ruby. In fact, ruby is very good at math, even quite sophisticated math. Doubters should take a look at the algebra package in the RAA. Ruby's reflective powers and dynamic nature allow one to get around OO head-scratchers. For example, I've been working on a polynomial package (pnom.rb, coming soon to an RAA near you). I wanted to allow anything that represented some sort of complex number as a coefficient, so I required mathn. I needed to add a bunch of methods to the classes representing complex numbers according to mathn, so that they would play nice with my new Pnom class. But what if the user created a Numeric class fitting the bill, for example, a class QuadRat of quadratic rationals (numbers of the form a + b*sqrt(c), where a, b, and c are rational), I wanted the user to be able to use that class too. With ruby I was able to rewrite a bunch of methods in all the appropriate classes without knowing about classes the user wanted to add in advance. I also wanted the package to be well behaved when it was reloaded. Here is how I handled them: # make infix operators in Numeric classes play nice with Pnom PlayNiceWithPnom = {'+'=>'Plus', '*'=>'Mul', '<=>'=>'Spaceship', '=='=>'Equal', '<'=>'Less', '>'=>'Greater', '<='=>'LessEqual', '>='=>'GreaterEqual'} PlayNiceWithPnom.each {|key, value| eval(%Q% PlayNiceWithPnom#{value} = <<-EOS alias prePnom_#{value} #{key} def #{key}(other) if defined?(Pnom) and other.kind_of?(Pnom) Pnom.new(self) #{key} other else prePnom_#{value}(other) end end EOS %) } ObjectSpace.each_object(Class) {|klass| if klass.ancestors.include?(Numeric) PlayNiceWithPnom.each{|key, value| if klass.public_instance_methods.include?(key) unless klass.public_instance_methods.include?("prePnom_#{value}") eval(%Q% klass.module_eval(PlayNiceWithPnom#{value})%) end end } end } I shudder to think of trying to accomplish this in Python! Regards, Bret