Ruby style question from a newby: exceptions

Discussion in 'Ruby' started by rj-cole, Nov 17, 2005.

  1. rj-cole

    rj-cole Guest

    Hi,

    Any hints on the best way to catch exceptions from the point of view of
    good style for the following?

    ---
    puts "Create connection..."
    imap = IMAP.new('sslmail.somewhere.com', 993, true)
    puts "Capabilities: cap = #{imap.capability().join(" ")}"
    puts "Authenticate..."
    logged_in = false

    begin
    imap.authenticate('CRAM-MD5', 'myname', 'secret')
    logged_in = true
    rescue Net::IMAP::NoResponseError => e
    puts " Failed, #{e}"
    end

    puts "Try Login..."
    if ! logged_in then
    begin
    imap.login('myname', 'secret')
    logged_in = true
    rescue
    puts " Failed, #{e}"
    end
    end
    ---

    What am I trying to do and what don't I like? Basically I want to try a
    sequence of things until one of them works --- first I want to use the
    authenticate method and if that fails to use the login method. Each of
    these methods indicates failure by raising an exception. I want to log
    each failure (because I'm experimenting with the library at this
    stage). In this example I want to log each failure and on failure I
    want to cacade to an alternative strategy.

    How could this code be better written so that it is easier to read and
    understand the flow of the code? Would it be possible to achieve
    something like the following?

    ---
    exceptions = until_success \
    { imap.authenticate ... },
    { imap.login ... }

    if exceptions.failed then
    puts "Unable to login: #{exceptions.join('\n')}"
    else
    puts "Login successfull. Record of unsuccessfull attempts: \n \
    #{exceptions.join("\n ")}"
    end
    ---

    with a function until_success taking a sequence of blocks as arguments?

    regards,

    Richard.
     
    rj-cole, Nov 17, 2005
    #1
    1. Advertisements

  2. Is the following irb session informative?

    irb(main):013:0> c = 0
    irb(main):014:0> begin
    irb(main):015:1* p c
    irb(main):016:1> raise
    irb(main):017:1> rescue
    irb(main):018:1> c += 1
    irb(main):019:1> retry if c < 5
    irb(main):020:1> end
    1
    2
    3
    4
    => nil
     
    YANAGAWA Kazuhisa, Nov 17, 2005
    #2
    1. Advertisements

  3. rj-cole

    daz Guest


    Hi Richard,

    Here's a variation on that theme:

    #--------------------------------------------------------

    METHOD_Q = [ [:aaa, TypeError],
    [:bbb, NoMethodError],
    [:ccc, ArgumentError],
    [:ddd, NameError],
    ].freeze

    def log(item); puts "LOG: #{item}"; end

    def aaa; 11 + 'Two Two'; end
    def bbb; 12.sort; end
    def ccc; [].each(13) {}; end
    def ddd
    puts "4th attempt"
    # NOCONST # <--- uncomment
    end


    catch:)done) do
    stack = METHOD_Q.dup
    begin
    meth, exc = stack.shift
    unless meth
    log "Tried everything :("
    throw:)done)
    end
    send(meth)
    log "Success at last!"
    rescue exc => e
    log "#{meth} error"
    log "^ #{e.message}"
    retry
    end
    end

    =begin

    LOG: aaa error
    LOG: ^ String can't be coerced into Fixnum
    LOG: bbb error
    LOG: ^ undefined method `sort' for 12:Fixnum
    LOG: ccc error
    LOG: ^ wrong number of arguments (1 for 0)
    4th attempt
    LOG: Success at last!

    =end
    #--------------------------------------------------------


    daz
     
    daz, Nov 17, 2005
    #3
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.