Forum: Ruby Re: Alternatives to methods for large number of nested "ifs"

Posted by Philip Rhoades (Guest)
on 2012-11-17 14:50
(Received via mailing list)
People,

Thanks to the people who responded - I looked at everything but nothing
really suited what I was trying to do but see below for some progress
that I made and another question:


On 2012-11-17 01:35, Philip Rhoades wrote:
>   if ..
> it to something like:
>       call something
> the same position in the nested "ifs"?
I found that I could use sequential "ifs" instead of nested "ifs" by
using "exit" statements in each "if" block - the script is processing
incoming mails and can exit when a mail has been satisfactorily
classified.  I still have something like this:


lots of code
if block - small
lots of code
if block - small
if block - large
if block - small
if block - large
.
.
etc


What I want is to be able to see the whole logic of the program in
about 25 lines (ie one screenfull of code - ie all the "if" statements)
- I could probably use standard methods for the repetitive small "if"
blocks but for the large "lots of code" and "if block - large" I
definitely can't.  Is it possible that a method can be forced to NOT use
local variables? - then I could replace the large blocks with these
sorts of methods.

Thanks,

Phil.

--
Philip Rhoades

GPO Box 3411
Sydney NSW  2001
Australia
E-mail:  phil@pricom.com.au
Posted by Robert Klemme (robert_k78)
on 2012-11-17 17:11
(Received via mailing list)
On Sat, Nov 17, 2012 at 2:50 PM, Philip Rhoades <phil@pricom.com.au> 
wrote:
> People,
>
> Thanks to the people who responded - I looked at everything but nothing
> really suited what I was trying to do but see below for some progress that I
> made and another question:

> I found that I could use sequential "ifs" instead of nested "ifs" by using
> "exit" statements in each "if" block - the script is processing incoming
> mails and can exit when a mail has been satisfactorily classified.

Ah, now we are cooking!  That looks like a proper use case for case.

> if block - large
> .
> .
> etc

For a start you could replace that with either

case email
when /foo/
  asdsdds
when /bar/
  adioaiosdipaosdpoasdopad  ads
when /something_else/
  method_which_contains_lots_of_code(email)
else
  raise "No category" # or whatever
end

Or, for more complex checks

case
when /foo/ =~ email && email.length > 1000
  d adasdsd ada
when email.urgent?
  adslkasda
else
  asdsd
end

> What I want is to be able to see the whole logic of the program in about 25
> lines (ie one screenfull of code - ie all the "if" statements) - I could
> probably use standard methods for the repetitive small "if" blocks but for
> the large "lots of code" and "if block - large" I definitely can't.  Is it
> possible that a method can be forced to NOT use local variables? - then I
> could replace the large blocks with these sorts of methods.

I am not sure I understand what you mean here.

Anyway, if you are categorizing you could use a similar approach to 
botp's:

CATEGORIES = [
  lambda {|email| email.size > 1000 and :large},
  lambda {|email| email.size <= 1000 and :small},
]

def categorize(email)
  CATEGORIES.each {|c| x = c[email] and return x}
  nil
end


Kind regards

robert
Posted by Philip Rhoades (Guest)
on 2012-11-21 17:32
(Received via mailing list)
On 2012-11-18 00:50, Philip Rhoades wrote:
>> I have an existing script that looks like:
>>       some lines of code
>> .
>>         if ..
> I found that I could use sequential "ifs" instead of nested "ifs" by
> if block - small
> small "if" blocks but for the large "lots of code" and "if block -
> large" I definitely can't.  Is it possible that a method can be
> forced
> to NOT use local variables? - then I could replace the large blocks
> with these sorts of methods.


procs were the solution (they allow shared variables) - I now have this
at the end of the program:

                                 ####        Mailing-List:,
Delivered-To: and Reply-To: lines
p_mailing_list.call
                                 #### OK     line_To non-blocked domains
p_line_To_non_blocked_domains.call
                                 #### OK     in_mailing_list
p_in_mailing_list.call
                                 #### Drop   in_black_list_to
p_in_black_list_to.call
                                 #### Drop   in_black_list_from AND
!Srejector content
p_in_black_list_from.call
                                 #### Drop   Bounce Bounced - deleting
old quarantined file if it exists
p_bounce_bounced.call
                                 #### Reject LinkedIn invitation
p_LinkedIn.call
                                 #### OK     Srejector content -
incoming/outgoing
p_Srejector.call
                                 #### OK     in_domains_list - for
incoming/outgoing mails, system mails etc
p_in_domains_list.call
                                 #### OK     put me on your whitelist
subject
p_put_me_on_your_whitelist_subject.call
                                 #### OK     To: line
p_line_To.call
                                 #### Drop   !in_white_list_to
p_not_in_white_list_to.call
                                 #### Drop   !in_white_list_to_substr
p_not_in_white_list_to_substr.call
                                 #### OK     in_white_list_from
p_in_white_list_from.call
                                 #### Drop   in_subject_list
p_in_subject_list.call
                                 #### Reject !in_white_list_from
p_not_in_white_list_from.call
                                 #### OK     shouldn\'t get here?
p_shouldnt_get_here.call


Regards,

Phil.

--
Philip Rhoades

GPO Box 3411
Sydney NSW  2001
Australia
E-mail:  phil@pricom.com.au
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.