あおきです。
引用、前後します。

  In mail "[ruby-list:36576] Re: インスタンス変数が nil になってしまう"
    rubikitch <rubikitch / ruby-lang.org> wrote:

> るびきちです。

> > class Hoge
> > 
> >   class Fuga < TMail::Mail
> > 
> >     def self.load(str, int)
> >       @num = int
> >       super(str)
> >     end
> これではクラスHoge::Fugaのインスタンス変数@numが設定されます。
> Hoge::Fugaのインスタンスではありません。
> なぜならHoge::Fugaの特異メソッド(クラスメソッド)なので。

これは最初のうちはハマりますよね。


> > TMail::Mail クラスにインスタンス変数を一つ追加したい
> > のですが、値を代入しても nil になってしまいます。
> こういう場合、TMail::Mailクラスをインスタンスに持つクラスをつくってみるのはどうでしょうか?

厳密に言うと、TMail::Mail のインスタンスを持つようなオブジェ
クトのクラスを定義する、ですよね? こんな感じに。

  class MailWrapper
    def initialize(mail, n)
      @mail = mail
      @number = n
    end
  end

  n = 125
  MailWrapper.new(TMail::Mail.load("/home/aamine/Mail/inbox/#{n}"), n)

用語使うとコンポジション (composition)。

これでもいいと思いますが、この場合に限っては、元のメール番号を
知りたいというのが目的だと思うので、次のようにしたほうがいい
でしょう。まず

  mail.port.filename

でメールのロード元のファイル名が取れるので、

  File.basename(mail.port.filename).to_i

で番号に戻せます。つまり、わざわざ継承してまで元データを
とっておく必要はありません。これを毎回書くのが面倒なら

  module TMail
    class Mail
      def seqence_number
        File.basename(port().filename).to_i
      end
    end
  end

と定義しておけば

  mail.sequence_number

だけで取れます。


しかし、安易に継承しないほうがいい、という点は同感です。
もうちょっと他のデータも必要だということなら、その場合は
コンポジションのほうがいいと思います。
-------------------------------------------------------------------
青木峰郎