Call method from a TK object

Discussion in 'Ruby' started by amnesiacx, Jan 9, 2004.

  1. amnesiacx

    amnesiacx Guest

    Please can someone tell my why the code that follows works when the
    "tick" and "zero" methods are nested inside "gui" , but when I move
    the "tick" and "zero" methods out of gui - into a top level class
    methods, the calls to tick from within the $stop object gets a "local
    method not found" error? (You need TK libs to run)

    # This script generates a counter with start and stop buttons.

    class StopWatch

    @@seconds=0
    @@hundredths=0
    @@stopped=TRUE
    $heading = "Ticker"

    #------------------------------------------------------------------------------
    public

    def initialize(head)
    $heading = head
    gui $heading
    root = Tk.root
    root.bind "Control-c", proc{root.destroy}
    root.bind "Control-q", proc{root.destroy}
    Tk.root.focus
    Tk.mainloop
    end

    #------------------------------------------------------------------------------
    private

    def gui(head)

    require "tk"

    $title = TkLabel.new {
    text head
    relief 'raised'
    width 20
    font 'courier'
    pack('side'=>'top', 'fill'=>'both')
    }

    $label = TkLabel.new {
    text '0.00'
    relief 'raised'
    width 10
    font 'verdana'
    pack('side'=>'bottom', 'fill'=>'both')
    }

    $start = TkButton.new {
    text 'Start'
    command proc {
    $stop.text "Stop"
    if @@stopped
    @@stopped = FALSE
    tick
    end
    }

    pack('side'=>'left','fill'=>'both','expand'=>'yes')
    }

    $stop = TkButton.new {
    text 'Stop'
    command proc{
    text "Zero"
    if @@stopped then
    zero
    text 'Stop'
    end
    @@stopped = TRUE
    }

    pack('side'=>'right','fill'=>'both','expand'=>'yes')
    }

    # the following two methods do not work when NOT nested inside
    the gui method as they are now
    # starts the timer
    def tick
    if @@stopped then return end
    Tk.after 50, proc{tick}
    @@hundredths+=5
    if @@hundredths >= 100
    @@hundredths=0
    @@seconds+=1
    end
    $label.text format("%d.%02d", @@seconds,
    @@hundredths)
    end

    # resets timer to zero
    def zero
    @@seconds=0
    @@hundredths=0
    $label.text format("%d.%02d", @@seconds,
    @@hundredths)
    end

    end

    end

    #------------------------------------------------------------------------------
    # run app
    StopWatch.new("BIT Ruby Stop Watch!")
     
    amnesiacx, Jan 9, 2004
    #1
    1. Advertising

  2. amnesiacx

    ts Guest

    >>>>> "a" == amnesiacx <> writes:

    a> $start = TkButton.new {

    TkButton::new use #instance_eval, this mean that in the the block self is
    $start

    a> text 'Start'
    a> command proc {
    a> $stop.text "Stop"
    a> if @@stopped
    a> @@stopped = FALSE
    a> tick

    ruby try to call self.tick i.e. TkButton#tick and not StopWatch#tick, this
    is why it give an error

    a> $stop = TkButton.new {
    a> text 'Stop'
    a> command proc{
    a> text "Zero"
    a> if @@stopped then
    a> zero

    same here, it try to call TkButton#zero and not StopWatch#zero

    a> text 'Stop'
    a> end
    a> @@stopped = TRUE
    a> }



    Guy Decoux
     
    ts, Jan 9, 2004
    #2
    1. Advertising

  3. amnesiacx

    amnesiacx Guest

    On Fri, 9 Jan 2004 20:30:29 +0900, ts <> wrote:

    >>>>>> "a" == amnesiacx <> writes:

    >
    >a> $start = TkButton.new {
    >
    > TkButton::new use #instance_eval, this mean that in the the block self is
    > $start
    >
    >a> text 'Start'
    >a> command proc {
    >a> $stop.text "Stop"
    >a> if @@stopped
    >a> @@stopped = FALSE
    >a> tick
    >
    > ruby try to call self.tick i.e. TkButton#tick and not StopWatch#tick, this
    > is why it give an error
    >
    >a> $stop = TkButton.new {
    >a> text 'Stop'
    >a> command proc{
    >a> text "Zero"
    >a> if @@stopped then
    >a> zero
    >
    > same here, it try to call TkButton#zero and not StopWatch#zero
    >
    >a> text 'Stop'
    >a> end
    >a> @@stopped = TRUE
    >a> }
    >
    >
    >
    >Guy Decoux
    >


    Nope, calling StopWatch.tick or StopWatch.zero doesnt work, "no such
    method" (sic) error
     
    amnesiacx, Jan 9, 2004
    #3
  4. amnesiacx

    ts Guest

    >>>>> "a" == amnesiacx <> writes:

    a> Nope, calling StopWatch.tick or StopWatch.zero doesnt work, "no such
    a> method" (sic) error

    You make the confusion between StopWatch::tich (class method) and
    StopWatch#tick (instance method). Try this (see 'self_orig = self')

    svg% cat b.rb
    #!/usr/bin/ruby
    class StopWatch

    @@seconds=0
    @@hundredths=0
    @@stopped=TRUE
    $heading = "Ticker"

    def initialize(head)
    $heading = head
    gui $heading
    root = Tk.root
    root.bind "Control-c", proc{root.destroy}
    root.bind "Control-q", proc{root.destroy}
    Tk.root.focus
    Tk.mainloop
    end

    private
    def gui(head)

    require "tk"
    self_orig = self

    $title = TkLabel.new {
    text head
    relief 'raised'
    width 20
    font 'courier'
    pack('side'=>'top', 'fill'=>'both')
    }

    $label = TkLabel.new {
    text '0.00'
    relief 'raised'
    width 10
    font 'verdana'
    pack('side'=>'bottom', 'fill'=>'both')
    }

    $start = TkButton.new {
    text 'Start'
    command proc {
    $stop.text "Stop"
    if @@stopped
    @@stopped = FALSE
    self_orig.tick
    end
    }
    pack('side'=>'left','fill'=>'both','expand'=>'yes')
    }

    $stop = TkButton.new {
    text 'Stop'
    command proc{
    text "Zero"
    if @@stopped then
    self_orig.zero
    text 'Stop'
    end
    @@stopped = TRUE
    }

    pack('side'=>'right','fill'=>'both','expand'=>'yes')
    }
    end

    protected
    def tick
    if @@stopped then return end
    Tk.after 50, proc{tick}
    @@hundredths+=5
    if @@hundredths >= 100
    @@hundredths=0
    @@seconds+=1
    end
    $label.text format("%d.%02d", @@seconds, @@hundredths)
    end

    def zero
    @@seconds=0
    @@hundredths=0
    $label.text format("%d.%02d", @@seconds, @@hundredths)
    end

    end

    StopWatch.new("BIT Ruby Stop Watch!")

    svg%


    p.s. : public is useless with initialize (initialize is always private)


    Guy Decoux
     
    ts, Jan 9, 2004
    #4
  5. amnesiacx

    amnesiacx Guest

    On Fri, 9 Jan 2004 21:27:22 +0900, ts <> wrote:

    >>>>>> "a" == amnesiacx <> writes:

    >
    >a> Nope, calling StopWatch.tick or StopWatch.zero doesnt work, "no such
    >a> method" (sic) error
    >
    > You make the confusion between StopWatch::tich (class method) and
    > StopWatch#tick (instance method). Try this (see 'self_orig = self')
    >
    >svg% cat b.rb
    >#!/usr/bin/ruby
    >class StopWatch
    >
    > @@seconds=0
    > @@hundredths=0
    > @@stopped=TRUE
    > $heading = "Ticker"
    >
    > def initialize(head)
    > $heading = head
    > gui $heading
    > root = Tk.root
    > root.bind "Control-c", proc{root.destroy}
    > root.bind "Control-q", proc{root.destroy}
    > Tk.root.focus
    > Tk.mainloop
    > end
    >
    > private
    > def gui(head)
    >
    > require "tk"
    > self_orig = self
    >
    > $title = TkLabel.new {
    > text head
    > relief 'raised'
    > width 20
    > font 'courier'
    > pack('side'=>'top', 'fill'=>'both')
    > }
    >
    > $label = TkLabel.new {
    > text '0.00'
    > relief 'raised'
    > width 10
    > font 'verdana'
    > pack('side'=>'bottom', 'fill'=>'both')
    > }
    >
    > $start = TkButton.new {
    > text 'Start'
    > command proc {
    > $stop.text "Stop"
    > if @@stopped
    > @@stopped = FALSE
    > self_orig.tick
    > end
    > }
    > pack('side'=>'left','fill'=>'both','expand'=>'yes')
    > }
    >
    > $stop = TkButton.new {
    > text 'Stop'
    > command proc{
    > text "Zero"
    > if @@stopped then
    > self_orig.zero
    > text 'Stop'
    > end
    > @@stopped = TRUE
    > }
    >
    > pack('side'=>'right','fill'=>'both','expand'=>'yes')
    > }
    > end
    >
    > protected
    > def tick
    > if @@stopped then return end
    > Tk.after 50, proc{tick}
    > @@hundredths+=5
    > if @@hundredths >= 100
    > @@hundredths=0
    > @@seconds+=1
    > end
    > $label.text format("%d.%02d", @@seconds, @@hundredths)
    > end
    >
    > def zero
    > @@seconds=0
    > @@hundredths=0
    > $label.text format("%d.%02d", @@seconds, @@hundredths)
    > end
    >
    >end
    >
    >StopWatch.new("BIT Ruby Stop Watch!")
    >
    >svg%
    >
    >
    >p.s. : public is useless with initialize (initialize is always private)
    >
    >
    >Guy Decoux


    Thx for the help. Appreciated.
     
    amnesiacx, Jan 9, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?ISO-8859-1?Q?Thomas_Gagn=E9?=
    Replies:
    9
    Views:
    11,225
    Jezuch
    Jul 3, 2003
  2. Ian
    Replies:
    2
    Views:
    346
    Ulrich Petri
    Sep 6, 2003
  3. Mac
    Replies:
    1
    Views:
    594
  4. sck10
    Replies:
    0
    Views:
    343
    sck10
    Mar 12, 2007
  5. Elf M. Sternberg
    Replies:
    15
    Views:
    271
    Matthias Reitinger
    Jul 29, 2009
Loading...

Share This Page