こんにちは。大城です。

だいぶ間が空いてしまいましたが、TkCanvasへアイテム生成のメソッドを追加するgemをbundlerで作成してみています。参考までに添付致します。

内容としてはこれまでに教えて頂いた内容だけの、以下のように非常に簡単なものです(実際のgemにはバージョンファイル等の読み込みも入ってきますが)。

require "tk"
class TkCanvas
   TkcItem::CItemTypeToClass.each {|k, v| class_eval("def
create_#{k}(*args); #{v}.create(self, *args); end")}
end

今回、パッケージ名について教えて頂きたいのですが、皆さんけっこう自由につけていますよね?命名ルールはあるのでしょうか?

今のところ、対象そのままの名前を表したtkcanvというものと、キャンバスを拡張するということでcanvexというものを考えていますが、「canvex」というとそれのみで何かの単語になっていそうですし、「拡張」というほど大したことはしておらず、また「あ、require
"tk" じゃなくて、"canvex" だった」と書き換えが生じる際にいちいちtkを消して書きなおす精神的ダメージがでかそうです。

かといって、tkcanvというとTkパッケージに標準で付いていそうな名前になってしまって、ここまでの名前を勝手に使っていいのかが躊躇されます。あと、名前は少しでも短くするためにtkcanvとしましたが、うっかり忘れてしまいそうなので、可能であれば下手に略さずtkcanvasとそのものズバリがよさそうな気もしますが、さらにここまでズバリと使っていいのかどうかと…。

何かご意見頂ければ嬉しいです。

よろしくお願い致します。


2015年3月10日 3:56 Hidetoshi NAGAI <nagai / ai.kyutech.ac.jp>:
> 永井@知能.九工大です.
>
> From: Naoki Oshiro <oshiro / mibai.tec.u-ryukyu.ac.jp>
> Subject: [ruby-list:50100] Re: Ruby/Tkでのキャンバス上のアイテム作成
> Date: Sun, 8 Mar 2015 17:11:40 +0900
> Message-ID: <CANd9fdDZrebYMU+5M3yXKYNn+2BTq0X+gUAaxcbSTY+Cf8YZwg / mail.gmail.com>
>
>> TkcTagAccessモジュール (canvastag.rb)
>> でTkcItemクラスに各アイテムへのコマンド割り当てがなされているのを今回知りました。また、tkclass.rbを使うと接頭のTkを外した形でのクラス名指定(TkCanvas⇒CanvasやTkcLine⇒Lineなど)もできるようになっていたのですね。こちらを使うと種々の基本的なクラス名(Frame,
>> Label, Entry, Lineなど)がTk寄りになり過ぎる感もありますが。
>
> Tk::Label とか Tk::Entry とかでも定義されてますから,例えば
> -------------------------------
> module My_GUI
>   include Tk
>   r = Root.new
>   r.wm_title 'HOGE'
>   Label.new(r, :text=>'sample').pack
>   Button.new(r, :text=>'quit', :command=>proc{exit}).pack
> end
> -------------------------------
> なんてこともできます.
>
>> canvasは元がTclで使い慣れているので、私の場合は「.c create line XX
>> YY」の語順に近いほうが馴染みがあるようです。gem化等々してみますかね(といっても、実質は先のメールで書いたclass_eval一行ですが…)。
>    (snip)
>> method_missingでの対応のご紹介ありがとうございました。こちらの場合は、create_XXXXのメソッドの使用時に毎回method_missingへの呼び出しが起こるのですよね?アイテム生成時のみですから、そこまでのコストではないのでしょうけど。
>
> 確かに method_missing の方がコストはかかるでしょうね.
> メソッド定義と method_missing での対応とは併存できますので,
> お好みのように定義いただいても支障は出ないと思います.
>
> ただ,create(type, *opt) の形式にも利点はあって,
> -------------------------------
> items = [
>   [TkcLine, 0, 0, 100, 100, {:fill=>'red'}],
>   [TkcLine, 0, 0, 100, 150, {:fill=>'blue'}],
>   [TkcLine, 0, 0, 100, 200, {:fill=>'green'}],
>    ...
> ]
>
> TkCanvas.new{|c|
>   items.each{|type, *opts|
>     c.create(type, *opts)
>   }
> }.pack
> -------------------------------
> のように描画定義をまとめて記述したりする場合に便利なんですよね.(^_^)
> --
> 永井 秀利  (nagai / ai.kyutech.ac.jp)
> 九州工業大学大学院情報工学研究院知能情報工学研究系知能情報メディア部門助教



-- 
=============================================
OSHIRO Naoki: oshiro / mibai.tec.u-ryukyu.ac.jp
http://mibai.tec.u-ryukyu.ac.jp/~oshiro/
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=