2012-04-16 7 views
1

これはtkに固有のものではなく、むしろルビーDSLとinstance_evalのより一般的な問題ですが、ここでは私の質問です。もしDSLをtkに使いたいのであれば、作業。たとえば、ボタンを押してインスタンスメソッドを呼び出す場合、これは動作しません。なぜなら、Tk親クラス(Tk :: Button)内の同じ名前のメソッドをTk DSLはインスタンスメソッドと変数へのアクセスを失いますか?

require 'tk' 
class MyApp 
    def initialize 
    @root = TkRoot.new 
    TkFrame.new {|f| 
     TkButton.new(f) { 
     text "Press Me" 
     command proc {do_something()} 
     pack 
     } 
     pack 
    } 
    end 
    def do_something 
    puts "Hello!" 
    end 
    def run 
    Tk.mainloop 
    end 
end 

MyApp.new.run 

私はDSLを使用していない、それを書き換えた場合、私はこの問題を回避することができますが、私は様々な理由のためにDSLを好む:コードの下

class MyApp 
    def initialize 
    @root = TkRoot.new 
    f = TkFrame.new 
    TkButton.new(f, text: "Press Me", command: proc {do_something()}).pack 
    f.pack 
    end 
    def do_something 
    puts "Hello!" 
    end 
    def run 
    Tk.mainloop 
    end 
end 

MyApp.new.run 

同じでのインスタンス変数のために真でありますMyAppクラス。これには何らかの方法がありますか?

答えて

2

proc { do_something }は、おそらくTkButtonインスタンスのコンテキストで評価されています。おそらくブロック内でtextcommandpackと呼ぶことができます。

これは実質的にselfMyAppインスタンスではないことを意味します。それはTkButtonインスタンスに変更されました。ブロックが閉鎖されているので、my_appローカル変数はブロックに利用できるようになります

def initialize 
    my_app = self # self is the MyApp instance here 
    @root = TkRoot.new 
    TkFrame.new do |f| 
    TkButton.new f do 
     text "Press Me" 
     command proc { my_app.do_something } 
     pack 
    end 
    pack 
    end 
end 

はこれを試してみてください。

+1

それは、ありがとう、それをしました。 –

関連する問題