From: Masao M. <mu...@hi...> - 2003-10-26 16:33:22
|
むとうです。 On Sun, 26 Oct 2003 01:00:45 +0900 (JST) Masahiro Sakai (酒井政裕) <sa...@to...> wrote: > さかいです。 > ではとりあえずサンプルを。 > > require 'gtk2' > Gtk.init > > class MyButton < Gtk::Button > register_type("MyButton") > > def initialize(label = nil) > # XXX: register_typeするとsuperがGLib#initialize相当になる なるほど。これは良いアイデアだと思います。 register_typeは活かして上記は採用と言うことで。 > super("label" => label) > @fuga = 0 > end > # 既存のシグナルのデフォルトハンドラをオーバーライド > def do_clicked(*args) > puts "MyButton#do_clicked enter" > #p caller > super > puts "MyButton#do_clicked leave" > end > # 新しいシグナルを定義 > signal_new("hoge", # 名前 > GLib::Signal::RUN_FIRST, # フラグ > nil, # accumulator (XXX: 仕様が未確定) > GLib::Type["void"], # 返り値の型 > GLib::Type["gint"], GLib::Type["gint"] # 引数の型 > ) > # 新しいシグナルのデフォルトハンドラ > def do_hoge(a, b) > puts "MyButton#do_hoge enter" > #p caller > puts "MyButton#do_hoge leave" > end たぶん、私が"Rubyっぽく"とお願いしたからだとは思うのですが 以下の点が気になります。 ・メソッド定義の形になっている。 他のメソッドと用途がかなり違う。また、 signal_connect()みたいブロックを受け付ける形とも違う ・do_*の名前がちと汎用的すぎるような...。 ・signal_overrideのdo_clickedが突然現れ、do_clickedの意味が ちょっとわかりづらい気がする。 #もちろん、register_typeを知ってれば気にならないと言う人 #もいるとは思いますが。 逆に、以下のような記法はどうでしょうか。 signal_override("clicked") {|args,...| : super : } signal_new("hoge", ..... ){|args,...| : } これでdo_*のようなメソッドを定義する必要もなくブロック内の ロジックの使用用途が見た目上、限定できるような気がします。 実装が難しいようでしたら、逆に以下のようにするとか。 signal_override("clicked") def signal_do_clicked(args,...) : super : } signal_new("hoge", ..... ) def signal_do_hoge(args,...) : } もちろん、さかいさんの実装を見てしまうと、 上記ではsignal_override("clicked")は冗長なものに なるとは思いますが、 要は、signal_newとsignal_overrideの位置づけを同様にして 見た目上の一貫性を持たせることを意図しています。 ------- あとそれとは別に、GLib::Typeの部分ってRubyのクラスを 使うようにはできないですかね。 > signal_new("hoge", # 名前 > GLib::Signal::RUN_FIRST, # フラグ > nil, # accumulator (XXX: 仕様が未確定) > GLib::Type["void"], # 返り値の型 > GLib::Type["gint"], GLib::Type["gint"] # 引数の型 > ) signal_new("hoge", # 名前 GLib::Signal::RUN_FIRST, # フラグ nil, # accumulator (XXX: 仕様が未確定) nil, # 返り値の型 Integer, Integer, # 引数の型 ) 両方使えるようにするとかでも構いませんけど...。 > # 新しいプロパティの作成 > install_property(GLib::Param::Int.new("fuga", # name > "Fuga", # nick > "fuga hoge", # blurb > 0, # min > 10000, # max > 0, # default > GLib::Param::READABLE | > GLib::Param::WRITABLE)) > # プロパティの実装 > def fuga > puts "MyButton#fuga is called" > @fuga > end > def fuga=(arg) > puts "MyButton#fuga= is called" > @fuga = arg > end > end これって、def fugaとfuga=は必要ですか? 上記の形でinstall_propertyを読んだら、 1. @fugaというインスタンス変数が定義される 2. fuga, fuga=, set_fugaが生成される の2つを自動で行うのが良いと思うのですがいかがでしょうか? #実装上難しいのかな。 fuga, fuga=, set_fugaの各メソッドのオーバーライドは可能だと なお良いかも。 あり? そういえばこの場合、@fugaって定義する必要ありましたっけ? 通常、propertiesってsetter/getterはあるけどインスタンス変数 としては存在しないと思ってたのですが、そうではない? ---- それ以外は良いと思います。 あと一歩だと思いますので、次のリリースまでには何とかしたいですね〜。 それでは。 -- .:% Masao Mutoh<mu...@hi...> |