Problems with throw/catch (newbie)

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!!

On 27.07.2008 18:52, Thomas L. wrote:

quite a bit.
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

Thomas L. 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 :wink: ), 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

Joshua B. 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.

Joel VanderWerf wrote:

Joshua B. 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.

Joshua B. 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. :wink:

Dave

2008/7/28 Dave B. [email protected]:

Joshua B. 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. :wink:

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

Robert K. wrote:

2008/7/28 Dave B. [email protected]:

Joshua B. 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. :wink:

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.

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.

2008/7/28 Thomas L. removed_email[email protected]:

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs