Justin Collins
7/20/2006 10:23:00 PM
Eric Armstrong wrote:
> There is no inefficency here. Recursion isn't
> being used to count down. That's in a loop.
>
> Recursion is only being used to restart the
> timer after it expires. No stack space is
> required. Any sufficiently optimizing compiler
> will take the stack out of the equation.
> (Whether ruby does so is another matter.)
It doesn't, sadly. Soon, hopefully.
>
> The question is really about the nature of
> instance variables in a script, I guess.
>
> It seems they can only be initialized in a
> method. (Something I keep forgetting. I'm
> /so/ used to intializing instance variables
> in Java.)
>
> Defining initialize() didn't work, because
> the Object object the variables belong to
> in a script is already created when that
> definition is processed. So it never runs.
>
> The obvious solution (which occurs to me only
> now) is to create an init() method, and
> invoke it before the first call to run().
>
I would think, given Ruby's nature, that the solution would be to create
a timer object. ;)
class MyTimer
def initialize(hours, minutes, seconds)
@hours = hours
@minutes = minutes
@seconds = seconds
end
#Rather than recursion, which in Ruby
#will eventually run out of stack space
def start
loop do
run
end
end
#Using nearly your exact same method
def run
#Won't see count down until the end without this
$stdout.sync = true
#Your line breaks meant that time_remaining was always zero
time_remaining = (3600 * @hours) + (60 * @minutes) +
@seconds
puts "sleeping for " + time_remaining.to_s
time_remaining.downto(0) do |i|
sleep(1)
print i.to_s + ".."
end
puts
beep; beep; beep
sleep 1
beep; beep; beep
sleep 1
beep; beep; beep
end
end
timer = MyTimer.new(0,0,15)
timer.start
Maybe that helps...
-Justin
> As the mathematician said...
>
> "It is now obvious that...wait a minute...
> let me check that...(works furiously)...
> Yes! It /is/ obvious..."
>
>
> Matthew Smillie wrote:
>> On Jul 20, 2006, at 20:03, Eric Armstrong wrote:
>>
>>> Is it me, or is it pretty much impossible
>>> to write a recursive script in ruby unless
>>> you use global variables?
>>>
>>> I have a simple countdown timer. I
>>> set up the number of seconds to sleep,
>>> sleep for a while, and then beep.
>>>
>>> A single run is easily done in a script
>>> (code below). The problems start when
>>> I define a run method and recurse.
>>>
>>> Unless I use global variables, there
>>> doesn't seem to be any way for the
>>> variables to get the data.
>>>
>>> Is that about it?
>>
>> Well, in this case, if you're using global variables, there's not
>> much of a point to making the method recursive (which stores all of
>> its local variables on the stack). The typical way to do recursive
>> method is to pass the relevant information as parameters, e.g.,
>>
>> def countdown(seconds)
>> sleep(1)
>> puts "tick"
>> sleep(1)
>> puts "tock"
>> countdown(seconds - 2)
>> end
>>
>> I'll also mention that a deep recursion like this is a horribly
>> inefficient way to do a countdown timer.
>>
>> matthew smillie
>>
>>>
>>>
>>> Initial Script
>>> --------------
>>> #!/usr/bin/env ruby
>>>
>>> # Beeps and character I/O
>>> require 'curses'
>>> include Curses
>>>
>>> @seconds = 10
>>> @minutes = 0
>>> @hours = 0
>>>
>>> #def run
>>> timeremaining = (3600 * @hours)
>>> + (60 * @minutes)
>>> + @seconds
>>> puts "sleeping for " + time_remaining.to_s
>>> timeremaining.downto(0) do |i|
>>> sleep(1)
>>> print i.to_s + ".."
>>> end
>>> puts
>>> beep; beep; beep
>>> sleep 1
>>> beep; beep; beep
>>> sleep 1
>>> beep; beep; beep
>>>
>>> # run
>>> #end
>>>
>>> #run
>>>
>>>
>>>
>>>
>>
>>