Begin else pattern question


#1

What is the cleanest way of doing:
def initialize(value)
begin
if value == ‘blah’
a_action
else
b_action
end
rescue
b_action
end
end

That is. If a is needed and doing a throws an exception, do b instead.
Otherwise, if a is not needed do b.

Or is that the cleanest way?

By cleanest, I mean l don’t like calling b_action twice in the method if
I
don’t have to, but it’s a trade off on readability… and I don’t like
the
way the code looks now :slight_smile:

Any other simpler way to do this pattern?

Mikel


#2

On Nov 25, 6:19 pm, Mikel L. removed_email_address@domain.invalid wrote:

Any other simpler way to do this pattern?

Hi Mikel,

One simplification would be to remove the “begin” and the
corresponding “end” since they’re not needed in this situation.

An extreme approach would be to put the basic logic structure into a
method. But then you’d have to pass in three Procs – one for the
boolean expression, and one each for a_action and b_action.

If you just want to avoid repeating the b_action, you could raise an
exception in your else to force yourself into the rescue clause and do
the b_action there.

Hope there’s something in there that you find helpful!

Eric

====

Interested in hands-on, on-site Ruby or Ruby on Rails
training? See http://LearnRuby.com for information about a
well-reviewed courses.


#3

On Tue, Nov 25, 2008 at 3:19 PM, Mikel L. removed_email_address@domain.invalid
wrote:

end

Any other simpler way to do this pattern?

Mikel

A device that turns exceptions into a return value might assist.
Perhaps something like this:

def succeeded
begin
yield
true
rescue
false
end
end

def a_action(succeed)
raise “failed” if !succeed
print “a_action\n”
end

def b_action
print “b_action\n”
end

def action(value, succeed)
b_action if !(value == “blah” && succeeded { a_action(succeed) })
end

action “blah”, true
action “blah”, false
action “not blah”, true
action “not blah”, false


#4

On Wed, Nov 26, 2008 at 11:10 AM, Eric I. removed_email_address@domain.invalid
wrote:

On Nov 25, 6:19 pm, Mikel L. removed_email_address@domain.invalid wrote:

Any other simpler way to do this pattern?
One simplification would be to remove the “begin” and the
corresponding “end” since they’re not needed in this situation.

Actually… that cleans it up enough and makes it nice and readable.
def initialize(raw_field)
if a
a_action
else
b_action
end
rescue
b_action
end

Why aren’t the begin and end blocks needed? Is it because it is already
encapsulated within a method any way and if it hits rescue, the rescue
block
is terminated by the method end in any case?

What I am trying to ask is “where did you learn when the begin and end
are
needed and when not?” :slight_smile:


#5

On Nov 25, 8:02 pm, Mikel L. removed_email_address@domain.invalid wrote:

Why aren’t the begin and end blocks needed? Is it because it is already
encapsulated within a method any way and if it hits rescue, the rescue block
is terminated by the method end in any case?

What I am trying to ask is “where did you learn when the begin and end are
needed and when not?” :slight_smile:

Hi Mikel,

It’s in the reference section of the “pickaxe” book (in my edition
it’s p. 346).

Basically there are three cases when you can use a rescue:

  1. Directly within a begin/end block.
  2. At the top-level of a method.
  3. Attached to a single statement.

Hope that helps,

Eric

====

Interested in hands-on, on-site Ruby or Ruby on Rails
training? See http://LearnRuby.com for information about a
well-reviewed courses.


#6

From: Mikel L. [mailto:removed_email_address@domain.invalid]

def initialize(value)

begin

if value == ‘blah’

a_action

else

b_action

end

rescue

b_action

end

end

That is. If a is needed and doing a throws an exception, do

b instead. Otherwise, if a is not needed do b.

and what if b_action throws, rescue it also w b_action ??

maybe, something like,

def initialize(value)
if value == ‘blah’
begin
a_action
rescue
b_action
end
else
b_action
end
end

or, if you like a flag and ensure

def initialize(value)
a_action if flag = (value == ‘blah’)
rescue
flag = false
ensure
b_action unless flag
end


#7

2008/11/26 Mikel L. removed_email_address@domain.invalid:

end

Any other simpler way to do this pattern?

def initialize(value)
if value == ‘blah’
a_action rescue b_action
else
b_action
end
end

Or if you really want to get rid of the second call:

def initialize(value)
raise “do b!” if value != ‘blah’
a_action
rescue Exception
b_action
end

Cheers

robert


#8

Here’s another option for removing the duplication of b_action:

def initialize(value)
begin
if value == ‘blah’
a_action
return
end
rescue
end
b_action
end

This is not identical to your original code, which would call b_action
twice if an exception occurred during the first invocation of b_action.

If a_action is short you could fold the first four lines to

return a_action if value == 'blah'

Note that a bare ‘rescue’ is the same as ‘rescue StandardError’. Certain
exceptions, typically due to lack of system resources, are not caught.
Often that is what you want, but to catch absolutely everything do

rescue Exception

Finally, there is the expression version of rescue, which I believe
catches StandardError:

def initialize(value)
(return a_action if value == ‘blah’) rescue nil
b_action
end

Regards,

Brian.