From: "M.Uemura" <mitsuhideuemura / yahoo.co.jp>
Subject: [ruby-list:45234] Matrix のサブクラスのインスタンス生成
Date: Fri, 18 Jul 2008 00:41:44 +0900

るびきちです。

> 頑張っているところなのですが、Matrix のサブクラスを定義しようとして、
> はまっております。

残念ながら、Matrixはサブクラスを作成できるようには作られていません。

> #"ruby -w" を受け取ってくれる env と "No such file" と弾いちゃう env
> #があるけれど、違いは何なのだろう。。。

envの問題ではなくて、#!の解釈の問題です。
一部の環境では 「#! /bin/env ruby -w」を「/bin/env」と「ruby -w」に解釈してしまい、
/bin/envの引数に「ruby -w」が渡されます。
そのため、「ruby -w」(スペースつきのコマンド)を探そうとして見つからないと言われてしまいます。

他にもいろいろな解釈の方法があるようです。
http://www.jmuk.org/diary/2007/03/01/0
http://x68000.q-e-d.net/~68user/unix/pickup?%A5%B7%A5%A7%A5%D0%A5%F3%A5%B0

> class MyMatrix < Matrix
>   attr_accessor :fixed
>   def initialize
>     super
>     @fixed = false
>   end
> end

Matrix#initializeは引数を取るのでこれではだめです。

require 'matrix'

class MyMatrix < Matrix
  attr_accessor :fixed
  def initialize(*args)
    super
    @fixed = false
  end
end

mtrx = MyMatrix.zero(3)              # => Matrix[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
mtrx.class                           # => Matrix

mtrx = Matrix[[11, 12], [21, 22]]    # => Matrix[[11, 12], [21, 22]]
mtrx.class                           # => Matrix
mtrx = MyMatrix[[11, 12], [21, 22]]  # => Matrix[[11, 12], [21, 22]]
mtrx.class                           # => MyMatrix
rows = [[1, 0], [0, 1]]
mtrx = MyMatrix.rows(rows, true)     # => Matrix[[1, 0], [0, 1]]
mtrx.class                           # => MyMatrix

MyMatrixのインスタンスが生成されてても「Matrix[行列の内容]」と表示されているのは、
あくまでMatrix#inspectがそう定義されているためです。

Matrix.zeroは次のように定義されているため、MyMatrixのインスタンスは生成されません。
たとえサブクラスから呼ばれても無理矢理Matrixのインスタンスを作成します。

  def Matrix.zero(n)
    Matrix.scalar(n, 0)
  end

一方、Matrix.[]は次のように定義されているため(Matrixが出てこない)、MyMatrixの
インスタンスが生成されます。

  def Matrix.[](*rows)
    new(:init_rows, rows, false)
  end

--
rubikitch
Blog: http://d.hatena.ne.jp/rubikitch/
Site: http://www.rubyist.net/~rubikitch/