From: Masao M. <mu...@hi...> - 2004-10-17 11:46:29
|
むとうです。 On Sun, 17 Oct 2004 20:01:31 +0900 (JST) Kouhei Sutou <ko...@co...> wrote: > 須藤です. > 確かに,PrintConfig.newはPrintConfigオブジェクトを返すのです > が,返したいオブジェクトはClass#new(Class.new???)でアロケー > トしたPrintConfigオブジェクトではないのです(B.new #=> Aはそ > こらへんをいいたかったらしい).具体的には > gnome_print_config_from_string()でアロケートされた > GnomePrintConifgです. > > でも、私が指摘した点はもっと単純で、Rubyとlibgnomeprintの > > ライブラリの対応関係を考えて > > gnome_print_config_default/_from_stringの実装を見ると、 > > どちらも、GNOME_TYPE_PRINT_CONFIGのインスタンスを作っているので > > B.new #=> AではなくB.new #=> Bでは無いでしょうか(つまり、Ruby側 > > から見るとそれはやはりGnomePrintConfigのインスタンスなのではないかなと) > > と言う前提の元、それならば#initializeを実装すべきでは?ということでした。 > > #何か勘違いしてるのかな...。 > > > #initializeでごにょごにょやろうとしても,#initializeではもう > すでにClass#newとかでGnomePrintConfigがアロケートされてしまっ > ています.この時点ではもう遅いのです. > > 私の考えは以下のような感じです. > > > PrintConfig#initializeでやる場合 > > PrintConfig.newすると... > > (1) どこかでGnomePrintConfigをアロケートする. > (2) アロケートしたオブジェクトを#initializeで初期化する. > > #initializeでgnome_print_from_string()でアロケートした > GnomePrintCofnigを返しても,PrintConfig.newが返すのは > Class#newとかがアロケートしたGnomePrintConfig. > > →だから今回は使えなそう. > > > PrintConfig.newでやる場合 > > PrintConfig.newすると... > > (1) gnome_print_from_string()でGnomePrintConfigをアロケー > トし,それを返す. > > →だから今回はこっちの方がよさそう. > > > rubyのレベルでいうと, > > class A > attr_accessor :a > > @@obj = A.new > > def self.a_is_one > @@obj.a = 1 > @@obj > end > end > > class B < A > def self.new > a_is_one > end > end > > class C < A > def initialize > self.class.a_is_one > end > end > > p B.new.a # => 1 > p C.new.a # => nil > > というようになるのですが,私の意図は汲み取って頂けるでしょう > か. すみません。もうちょっと教えてください。 もしかしたら、他にも該当する可能性があるのできちんと理解したい んです。 どこでRubyのオブジェクトをアロケートするか、どこでCの構造体 をアロケートするか、というところが問題の焦点ということですよね。 であれば、そもそもPrintConfig.newの中から別のRubyメソッドを 呼び出すような実装に*しなければ*良いのではないでしょうか。 うまく説明できないのでコードを示します。 static VALUE gp_config_initialize(int argc, VALUE* argv, VALUE self) { VALUE flags; /* currently not used in libgnomeprint. */ VALUE string; GnomePrintConfig* config; rb_scan_args(argc, argv, "11", &string, &flags); if (NIL_P(flags)) { flags = INT2NUM(0); } config = gnome_print_config_from_string(RVAL2CSTR(string), NUM2UINT(flags)); G_INITIALIZE(self, config); return Qnil; } これならば、GnomeConfig.newすると、 (1) Class.newでGnome::PrintConfigを作る(けど中身なし) (2) Class.newを#initializeで初期化する. #initializeでgnome_print_from_string()でアロケートした GnomePrintCofnigを返し、それを(1)で作ったGnome::PrintConfig に割り当てる -- という理解でして、それであれば#initializeを使えると思うのですが、 もしかして間違えてますか(^^;)? ちなみに、なぜ、ここにこだわるかというと、 そもそもnewをオーバーライドしちゃうとサブクラスが作れない という問題があるからです。 -- .:% Masao Mutoh<mu...@hi...> |