Begin else pattern question

M

Mikel Lindsaar

[Note: parts of this message were removed to make it a legal post.]

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 :)

Any other simpler way to do this pattern?

Mikel
 
A

Alan Johnson

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 :)

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
 
E

Eric I.

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.
 
M

Mikel Lindsaar

[Note: parts of this message were removed to make it a legal post.]

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?" :)
 
E

Eric I.

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?" :)

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.
 
P

Peña, Botp

RnJvbTogTWlrZWwgTGluZHNhYXIgW21haWx0bzpyYWFzZG5pbEBnbWFpbC5jb21dIA0KIyBkZWYg
aW5pdGlhbGl6ZSh2YWx1ZSkNCiMgICBiZWdpbg0KIyAgICAgaWYgdmFsdWUgPT0gJ2JsYWgnDQoj
ICAgICAgIGFfYWN0aW9uDQojICAgICBlbHNlDQojICAgICAgIGJfYWN0aW9uDQojICAgICBlbmQN
CiMgICByZXNjdWUNCiMgICAgIGJfYWN0aW9uDQojICAgZW5kDQojIGVuZA0KIyANCiMgVGhhdCBp
cy4gIElmIGEgaXMgbmVlZGVkIGFuZCBkb2luZyBhIHRocm93cyBhbiBleGNlcHRpb24sIGRvIA0K
IyBiIGluc3RlYWQuICBPdGhlcndpc2UsIGlmIGEgaXMgbm90IG5lZWRlZCBkbyBiLg0KDQphbmQg
d2hhdCBpZiBiX2FjdGlvbiB0aHJvd3MsIHJlc2N1ZSBpdCBhbHNvIHcgYl9hY3Rpb24gPz8NCg0K
DQptYXliZSwgc29tZXRoaW5nIGxpa2UsDQoNCg0KZGVmIGluaXRpYWxpemUodmFsdWUpDQogIGlm
IHZhbHVlID09ICdibGFoJw0KICAgICBiZWdpbg0KICAgICAgIGFfYWN0aW9uDQogICAgIHJlc2N1
ZQ0KICAgICAgIGJfYWN0aW9uDQogICAgIGVuZA0KICBlbHNlDQogICAgYl9hY3Rpb24NCiAgZW5k
DQplbmQNCg0Kb3IsIGlmIHlvdSBsaWtlIGEgZmxhZyBhbmQgZW5zdXJlDQoNCmRlZiBpbml0aWFs
aXplKHZhbHVlKQ0KICBhX2FjdGlvbiBpZiBmbGFnID0gKHZhbHVlID09ICdibGFoJykNCnJlc2N1
ZQ0KICBmbGFnID0gZmFsc2UNCmVuc3VyZQ0KICBiX2FjdGlvbiB1bmxlc3MgZmxhZw0KZW5kDQoN
Cg==
 
B

Brian Candler

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.
 
R

Robert Klemme

2008/11/26 Mikel Lindsaar said:
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 :)

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,186
Messages
2,570,998
Members
47,587
Latest member
JohnetteTa

Latest Threads

Top