[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

problems with throw/catch (newbie

Thomas Luedeke

7/27/2008 4:52:00 PM

I'm trying to do something that I think would be pretty trivial. I've
read in an external file as an array. I want to parse the array of
lines, and set a line number as a variable if the line matches a certain
pattern. The file is rather long, so I want to break out of the loop
once I've made the match.

I've tried this a number of different ways, and they either don't work,
or I get some JumpError (which is incomprehensible to my newbie mind).
I'm still deeply in the "suck period" of learning Ruby (and
transitioning from O-O Fortran 95 and UNIX scripting), so I'm struggling
quite a bit.

I'm running Ruby 1.8.6 through Eclipse.

Where I'm at is the following (and this is just the latest in a series
of varieties trying to make the stupid thing work):

============================

inputFile = File.open( "filename","r" )
inputArray = inputFile.readlines
counts = 1
xcob3cArray.each catch(:breakout) do |line|
line_number = counts
throw(:breakout) "$counts" if ( line.lstrip =~ /^(11))/ )
counts = counts + 1
end
line_number = $counts

============================

Any help would be greatly appreciated!!
--
Posted via http://www.ruby-....

9 Answers

Robert Klemme

7/27/2008 4:59:00 PM

0

On 27.07.2008 18:52, Thomas Luedeke wrote:
> I'm trying to do something that I think would be pretty trivial. I've
> read in an external file as an array. I want to parse the array of
> lines, and set a line number as a variable if the line matches a certain
> pattern. The file is rather long, so I want to break out of the loop
> once I've made the match.
>
> I've tried this a number of different ways, and they either don't work,
> or I get some JumpError (which is incomprehensible to my newbie mind).
> I'm still deeply in the "suck period" of learning Ruby (and
> transitioning from O-O Fortran 95 and UNIX scripting), so I'm struggling
> quite a bit.
>
> I'm running Ruby 1.8.6 through Eclipse.
>
> Where I'm at is the following (and this is just the latest in a series
> of varieties trying to make the stupid thing work):
>
> ============================
>
> inputFile = File.open( "filename","r" )
> inputArray = inputFile.readlines
> counts = 1
> xcob3cArray.each catch(:breakout) do |line|
> line_number = counts
> throw(:breakout) "$counts" if ( line.lstrip =~ /^(11))/ )
> counts = counts + 1
> end
> line_number = $counts
>
> ============================
>
> Any help would be greatly appreciated!!

If your file is really that large you'd probably rather want to read it
line by line and not in a single Array.

# untested
def search file, rx
File.open file do |io|
io.each do |line|
return io.lineno if rx =~ line
end
end
end

Kind regards

robert

Joshua Ballanco

7/28/2008 12:10:00 AM

0

Thomas Luedeke wrote:
> inputFile = File.open( "filename","r" )
> inputArray = inputFile.readlines
> counts = 1
> xcob3cArray.each catch(:breakout) do |line|
> line_number = counts
> throw(:breakout) "$counts" if ( line.lstrip =~ /^(11))/ )
> counts = counts + 1
> end
> line_number = $counts
>
> ============================
>
> Any help would be greatly appreciated!!

Definitely, evaluating the file a line at a time will be more efficient,
but it's also worth noting that there is an error in your thinking about
the 'each' block.

First, Ruby blocks don't work like Java iterators. That is, you can't
use 'catch' and 'throw' the way that you have. Second, it is good
programing practice to reserve 'throw's and 'catch'es for
honest-to-goodness errors (this isn't just Ruby specific either).

In your case, you'd want to use 'break' ('next' is also good for loops).
So, combining Robert's advice with mine (and another tip or two for
conciseness and efficiency ;-) ), you'd have:

line_number = 0
File.open(inputFile) do |file|
file.each_line do |line|
line_number += 1
break if line =~ /^\s*(11)/
end
end

Cheers, and happy coding!

-Josh
--
Posted via http://www.ruby-....

Joel VanderWerf

7/28/2008 12:19:00 AM

0

Joshua Ballanco wrote:
> First, Ruby blocks don't work like Java iterators. That is, you can't
> use 'catch' and 'throw' the way that you have. Second, it is good
> programing practice to reserve 'throw's and 'catch'es for
> honest-to-goodness errors (this isn't just Ruby specific either).

There's nothing wrong with using catch/throw as a control flow
construct, if you need it. For example: breaking out of nested loops.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Joshua Ballanco

7/28/2008 12:34:00 AM

0

Joel VanderWerf wrote:
> Joshua Ballanco wrote:
>> First, Ruby blocks don't work like Java iterators. That is, you can't
>> use 'catch' and 'throw' the way that you have. Second, it is good
>> programing practice to reserve 'throw's and 'catch'es for
>> honest-to-goodness errors (this isn't just Ruby specific either).
>
> There's nothing wrong with using catch/throw as a control flow
> construct, if you need it. For example: breaking out of nested loops.

Ah, the classic debate...this could go on forever....

There are a number of reasons not to use throw/catch for flow control.
One reason is the overhead involved. Another reason is that there's the
risk of someone else catching your throw. Yet another is that if, for
whatever reason, your throw is not caught, it will percolate all the way
up and kill your process.

If you're in a nested loop, it would be better to have a flag and set it
when you want to break out entirely. Better yet, use a 'goto'.

Yes, that's right, 'goto' can be useful. Those teachers that taught you
you'd go to programmer hell if you used it weren't telling the whole
truth.
--
Posted via http://www.ruby-....

Dave Bass

7/28/2008 10:31:00 AM

0

Joshua Ballanco wrote:
> Yes, that's right, 'goto' can be useful.

Every processor instruction set I've seen has an unconditional jump
opcode or equivalent. E.g. x86 assembler uses JMP. If it's there we
should us it. ;-)

Dave
--
Posted via http://www.ruby-....

Robert Klemme

7/28/2008 11:58:00 AM

0

2008/7/28 Dave Bass <davebass@musician.org>:
> Joshua Ballanco wrote:
>> Yes, that's right, 'goto' can be useful.
>
> Every processor instruction set I've seen has an unconditional jump
> opcode or equivalent. E.g. x86 assembler uses JMP. If it's there we
> should us it. ;-)

Sorry, but this is ridiculous. Assembler and Ruby are two completely
different pairs of shoes.

In this case "return" or "break" are far more appropriate IMHO. throw
/ catch would also work (module caveats that have been mentioned) but
I always feel reluctant about using those when they are not needed
since they resemble exceptions too closely.

Cheers

robert

--
use.inject do |as, often| as.you_can - without end

Thomas Luedeke

7/28/2008 2:47:00 PM

0

Robert Klemme wrote:
> 2008/7/28 Dave Bass <davebass@musician.org>:
>> Joshua Ballanco wrote:
>>> Yes, that's right, 'goto' can be useful.
>>
>> Every processor instruction set I've seen has an unconditional jump
>> opcode or equivalent. E.g. x86 assembler uses JMP. If it's there we
>> should us it. ;-)
>
> Sorry, but this is ridiculous. Assembler and Ruby are two completely
> different pairs of shoes.
>
> In this case "return" or "break" are far more appropriate IMHO. throw
> / catch would also work (module caveats that have been mentioned) but
> I always feel reluctant about using those when they are not needed
> since they resemble exceptions too closely.
>
> Cheers
>
> robert


What is annoying to me is that even Fortran 95 has the capability (using
"EXIT [construct] name") to get out of deeply nested loops. Why does
Ruby force you to use catch/throw (which intuitively seems like
exception handling to me). My example above used catch/throw for a
single loop, but the reason I asked is that I anticipate having to break
out of more deeply nested loops.
--
Posted via http://www.ruby-....

Marc Heiler

7/28/2008 3:31:00 PM

0

The biggest argument against catch/throw is that, when one looks at
existing ruby code, authors using it are in a minority compared to
return/break/each/loop/begin/rescue users. Or it other words, it is seen
less often.
--
Posted via http://www.ruby-....

Robert Klemme

7/29/2008 7:16:00 AM

0

2008/7/28 Thomas Luedeke <thomas.luedeke@areva.com>:
> What is annoying to me is that even Fortran 95 has the capability (using
> "EXIT [construct] name") to get out of deeply nested loops. Why does
> Ruby force you to use catch/throw (which intuitively seems like
> exception handling to me). My example above used catch/throw for a
> single loop, but the reason I asked is that I anticipate having to break
> out of more deeply nested loops.

Interestingly I cannot remember having to break from a nested loop.
It must be a very rare situation in my programming. I can think of a
number of reasons why that is:

a) my programming style, namely to keep methods short and refactor
b) the types of problems I build solutions for

Not sure what it is in fact but I tend to believe that often this
breaking from nested loop can easily be done via a "return" or having
appropriate loop conditions. For example, this is an idiom I often
use in other languages and it also works well for arbitrarily nested
loops:

def look_for x
@items.each do |it|
return it if x == it
end
nil
end

Maybe this helps.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end