What do you think of this idiom?


(HAL 9000) #1

I was writing a little script which prompted
the user for a directory. I wanted to repeat
until a valid directory was entered.

At first I was going to write an actual loop.
Then I thought of this little technique. What
do you think? How would you do it?

Cheers,
Hal Fulton

begin
print "Dir = "
mydir = gets.chomp
dir = Root + mydir
raise “No such directory” if not File.stat(dir).directory?
rescue => err
puts err
retry
end


(David Alan Black) #2

Hi –

I was writing a little script which prompted
the user for a directory. I wanted to repeat
until a valid directory was entered.

At first I was going to write an actual loop.
Then I thought of this little technique. What
do you think? How would you do it?

Cheers,
Hal Fulton

begin
print "Dir = "
mydir = gets.chomp
dir = Root + mydir
raise “No such directory” if not File.stat(dir).directory?
rescue => err
puts err
retry
end

I think it isn’t doing what you think :slight_smile:

$ ruby getdir.rb # with “Root = ‘./’” added
Dir = non-existent
No such file or directory - “./non-existent”

Note that it’s not using your error message, because the "if not"
branch never happens: the stat on a bad directory name raises an
exception of its own. You could use test(?d,dir) to get a true/false
test.

Anyway, I like the way “retry” fits in here, and this seems like a
good way to avoid the annoying pattern of repeating a test, which I
always seem to fall into:

until some_test(str)
print "Input: "
str = gets.chomp
puts “Invalid” unless some_test(str)
end

Ultimately, though, it would be nice to wrap all this stuff up in a
method. I was playing around with that a little, using yours as a
starting point. Nothing profound here, just curious how the wrapping
might go.

def getstr(prompt,error=“Invalid input”)
str = “” # not strictly needed, but clearer
begin
print prompt
str = gets.chomp
raise error unless yield(str)
rescue => err
puts err
retry
end
str
end

s = getstr("Dir = ", “No such directory”) {|dir| test(?d,dir)}

David

···

On Sat, 22 Jun 2002, Hal E. Fulton wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav


(Pablo Lorenzzoni) #3

Hello!

I like it, but it’s not going to work. File.stat needs the the directory to
exist. First you have to test that:

begin
print "Dir = "
mydir = gets.chomp
dir = Root + mydir
raise “No such directory” if not File.exist?(dir) # added
raise “It’s not a directory” if not File.stat(dir).directory? # changed
rescue => err
puts err
retry
end

[]s

Pablo

···

Em Sab 22 Jun 2002 01:20, Hal E. Fulton escreveu:

I was writing a little script which prompted
the user for a directory. I wanted to repeat
until a valid directory was entered.

At first I was going to write an actual loop.
Then I thought of this little technique. What
do you think? How would you do it?

Cheers,
Hal Fulton

begin
print "Dir = "
mydir = gets.chomp
dir = Root + mydir
raise “No such directory” if not File.stat(dir).directory?
rescue => err
puts err
retry
end


Pablo Lorenzzoni (Spectra) spectra@debian.org
GnuPG Key ID 268A084D at search.keyserver.net
Webpage: http://people.debian.org/~spectra/


(ts) #4

    begin
      print prompt
      str = gets.chomp
      raise error unless yield(str)
    rescue => err
      puts err
      retry
    end

there is a stupid way to write it, without rescue

   begin
      print prompt
      str = gets.chomp
   end until yield(str) or puts error

Guy Decoux


(HAL 9000) #5

I think it isn’t doing what you think :slight_smile:

$ ruby getdir.rb # with “Root = ‘./’” added
Dir = non-existent
No such file or directory - “./non-existent”

Note that it’s not using your error message, because the "if not"
branch never happens: the stat on a bad directory name raises an
exception of its own. You could use test(?d,dir) to get a true/false
test.

Right! Hadn’t noticed that. That’s why I post
these things.

[snip]

s = getstr("Dir = ", “No such directory”) {|dir| test(?d,dir)}

Ah, that’s not bad. Good idea.

Hal Fulton

···

----- Original Message -----
From: “David Alan Black” dblack@candle.superlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, June 22, 2002 3:29 AM
Subject: Re: What do you think of this idiom?


(HAL 9000) #6

Hello!

I like it, but it’s not going to work. File.stat needs the the directory
to
exist. First you have to test that:

[snip]

Quite right. Thanks for the fix.

Hal Fulton

···

----- Original Message -----
From: “Pablo Lorenzzoni” spectra@debian.org
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, June 22, 2002 5:41 AM
Subject: Re: What do you think of this idiom?


(HAL 9000) #7

More and more interesting. I’d never have
thought of that.

Thanks,
Hal Fulton

···

----- Original Message -----
From: “ts” decoux@moulon.inra.fr
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Cc: ruby-talk@ruby-lang.org
Sent: Saturday, June 22, 2002 10:52 AM
Subject: Re: What do you think of this idiom?

there is a stupid way to write it, without rescue

begin
print prompt
str = gets.chomp
end until yield(str) or puts error