Два расширенных класса - один работает, а другой нет - PullRequest
1 голос
/ 04 февраля 2012

У меня были некоторые трудности в использовании расширенных классов в рельсах, в частности, при расширении класса Matrix - и я также задал несколько вопросов, связанных с этим:

Правильно ли я расширяю этот встроенный класс ruby?

Использование пользовательских функций в приложении rails

Где поместить этот класс матрицы в мое приложение rails

В общем, ответы были на автозагрузку в rails 3. Однако, когда я расширяю 'Math', новые функции работают, когда я расширяю 'Matrix', новые функции не работают - даже если я отношусь к ним одинаково

Я перепробовал много итераций и изменил имена модулей, требует, автозагрузки, но вот мои последние ключевые файлы:

application.rb:

require File.expand_path('../boot', __FILE__)

require 'rails/all'
require 'matrix'

# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)

module SimpleFixed
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Custom directories with classes and modules you want to be autoloadable.
    # **I have tried all these autoload variants**
    #  config.autoload_paths += %W(#{config.root}/extras)
    #  config.autoload_paths += %W(#{config.root}/lib)
    #  config.autoload_paths += Dir["#{config.root}/lib/**/"]
    #  config.autoload_paths << "#{Rails.root}/lib"
      config.autoload_paths << "#{::Rails.root.to_s}/lib" # <-- set path
      require "extend_matrix" # <-- forcibly load your matrix extension

*other standard code here*

lib/extend_math.rb

module Math
  class << self

    def cube_it(num)
      num**3
    end

    def add_five(num)
      num+5
    end

  end
end

lib / exte_matrix.rb

module Extend_matrix **An error is raised if I call this 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

страница моего просмотра:

<%= Math.add_five(6) %> **works*

<%= Matrix[[25,15,-5],[15,18,0],[-5,0,11]].cholesky_factor %> **doesn't work**

Может быть, потому что Math - это модуль в rubyа матрица это класс?Если да, то как мне исправить это?

1 Ответ

1 голос
/ 04 февраля 2012

Если вы посмотрите на реализацию Matrix, вы увидите причину. Для меня это находится в .../ruby192/lib/ruby/1.9.1/matrix.rb. Определение (опущены все методы):

class Matrix
  include Enumerable
  include ExceptionForMatrix
  ...
end

Это означает, что Matrix не содержится в модуле. Ваш источник ваших дополнений должен начинаться:

class Matrix

  def symmetric?
    ...
  end
  def cholesky_factor
    ...
  end
end

Таким образом, ваше добавление к классу или модулю должно соответствовать текущему определению. Matrix известен как Matrix в константах Ruby, а не как Extend_matrix::Matrix, который вы определили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...