Zakoff
Zakoff

Reputation: 12995

Am I extending this inbuilt ruby class correctly?

In my rails app in lib/matrix.rb I have entered the following code to extend the inbuilt Matrix class:

module Matrix

  require 'matrix'

  class Matrix
    def symmetric?
      return false if not square?
      (0 ... row_size).each do |i|
        (0 .. i).each do |j|
          return false if self[i,j] != self[j,i]
        end
      end
      true
    end

    def cholesky_factor
      raise ArgumentError, "must provide symmetric matrix" unless symmetric?
      l = Array.new(row_size) {Array.new(row_size, 0)}
      (0 ... row_size).each do |k|
        (0 ... row_size).each do |i|
          if i == k
            sum = (0 .. k-1).inject(0.0) {|sum, j| sum + l[k][j] ** 2}
            val = Math.sqrt(self[k,k] - sum)
            l[k][k] = val
          elsif i > k
            sum = (0 .. k-1).inject(0.0) {|sum, j| sum + l[i][j] * l[k][j]}
            val = (self[k,i] - sum) / l[k][k]
            l[i][k] = val
          end
        end
      end
      Matrix[*l]
    end
  end
end

Is this the correct way to add methods to an existing class within the rails app? Should I have the require matrix line there?

EDIT 1: Additional info provided

I have now removed the require 'matrix' line.

If I type the following test code in a view page, it only works if I delete my lib/matrix.rb file:

<% require 'matrix' %>

<%

m = Matrix[
   [0,0],
   [1,1]
   ]

%>

<%= m.column(0) %>

Otherwise it gives the error:

undefined method `[]' for Matrix:Module

It appears that I am eliminating the default methods of the built in Matrix class when I try to extend the class. Is there a way around this error?

Upvotes: 1

Views: 123

Answers (2)

Graham Swan
Graham Swan

Reputation: 4828

To extend a core class in Rails, you simply open it, add your methods, and close it. For example, to extend the Matrix class:

class Matrix
  def my_method
    "New method"
  end
end

You should not need to require 'matrix' in your code either. As long as the file holding your extension is in one of the autoload paths, you should have direct access to the new methods.

If you need to add a directory to your Rails autoload path, simply update /config/application.rb with the following line:

  • config.autoload_paths += %W(#{config.root}/app/extras) # Autoload /app/extras/*.rb

Upvotes: 0

ez.
ez.

Reputation: 7654

no you should not have to require 'matrix' here. Whoever uses your code(rails app in your case), should use require 'matrix'

Upvotes: 1

Related Questions