Idiomatic ruby

Discussion in 'Ruby' started by eastcoastcoder@gmail.com, Feb 13, 2006.

  1. Guest

    Very often I have a question method, which, in some cases, the caller
    would want to know why as well.

    Examples:

    def valid?
    end

    def abort?
    end

    Ruby does not allow subclassing true and false, so, if these methods
    return one of those, they can't return any additional info. But
    sometimes the caller needs additional info, as in:

    if !valid? logger.warn "Not valid: #{why not?}"

    What is the best way to handle this? I could have those methods set
    @instance_variables, but this seems a little hackish, and could
    introduce race conditions.

    Is there anyway to return false, "reason", or something of that sort?
    What is the preferred, idiomatic way of doing this?
    , Feb 13, 2006
    #1
    1. Advertising

  2. Guest

    I can think of two directions you could go real quickly.

    You could go the Rails validations way of your question method having a
    side-effect that populates some other member. eg:

    flash[:warning] = user.errors.get_full_messages unless user.valid?

    Of you could go with the Perlish way the Regex library works:

    "Cows are Cool" =~ /(\w+)/
    puts $1

    I prefer the side-effect method.
    , Feb 13, 2006
    #2
    1. Advertising

  3. Guest

    On Mon, 13 Feb 2006 wrote:

    > Very often I have a question method, which, in some cases, the caller
    > would want to know why as well.
    >
    > Examples:
    >
    > def valid?
    > end
    >
    > def abort?
    > end
    >
    > Ruby does not allow subclassing true and false, so, if these methods
    > return one of those, they can't return any additional info. But
    > sometimes the caller needs additional info, as in:
    >
    > if !valid? logger.warn "Not valid: #{why not?}"
    >
    > What is the best way to handle this? I could have those methods set
    > @instance_variables, but this seems a little hackish, and could
    > introduce race conditions.
    >
    > Is there anyway to return false, "reason", or something of that sort?
    > What is the preferred, idiomatic way of doing this?


    use a block to return info:

    harp:~ > cat a.rb
    class C
    def initialize(x) @x = x end
    def valid?()
    if @x == 42
    true
    else
    yield "x is not 42" rescue nil
    false
    end
    end
    end

    c = C::new 43
    unless c.valid?{|reason| warn "not valid : #{ reason }" }
    # do something
    end

    c = C::new 42
    c.valid?{|reason| warn "not valid : #{ reason }" }


    harp:~ > ruby a.rb
    not valid : x is not 42



    or invert your logic so info can be added:

    harp:~ > cat a.rb
    class C
    def initialize(x) @x = x end
    def invalid?() @x == 42 ? false : "x is not 42" end
    end

    c = C::new 43
    if((reason = c.invalid?))
    puts reason
    end

    c = C::new 42
    if((reason = c.invalid?))
    puts reason
    end


    harp:~ > ruby a.rb
    x is not 42


    hth.

    -a

    --
    happiness is not something ready-made. it comes from your own actions.
    - h.h. the 14th dali lama
    , Feb 13, 2006
    #3
  4. wrote:
    > Very often I have a question method, which, in some cases, the caller
    > would want to know why as well.
    >
    > Examples:
    >
    > def valid?
    > end
    >
    > def abort?
    > end
    >
    > Ruby does not allow subclassing true and false, so, if these methods
    > return one of those, they can't return any additional info. But
    > sometimes the caller needs additional info, as in:
    >
    > if !valid? logger.warn "Not valid: #{why not?}"
    >
    > What is the best way to handle this? I could have those methods set
    > @instance_variables, but this seems a little hackish, and could
    > introduce race conditions.
    >
    > Is there anyway to return false, "reason", or something of that sort?
    > What is the preferred, idiomatic way of doing this?


    def valid?( n )
    return n%2==0, "It's odd."
    end

    f, why = valid? 9
    William James, Feb 13, 2006
    #4
  5. wrote:

    > harp:~ > cat a.rb
    > class C
    > def initialize(x) @x = x end
    > def valid?()
    > if @x == 42
    > true
    > else
    > yield "x is not 42" rescue nil
    > false
    > end
    > end
    > end
    >
    > c = C::new 43
    > unless c.valid?{|reason| warn "not valid : #{ reason }" }
    > # do something
    > end
    >
    > c = C::new 42
    > c.valid?{|reason| warn "not valid : #{ reason }" }
    >
    >
    > harp:~ > ruby a.rb
    > not valid : x is not 42


    I like this solution the best. Unlike the solutions involving
    exceptions or multiple return values, it still allows valid? to be used
    as an ordinary boolean function when you don't care about the reason why
    something's not valid, yet doesn't have the race conditions involved in
    the side-effect solutions.

    That said, I think part of the reason there's no agreed upon idiom for
    this is because it would have been more idiomatic in Ruby to not even
    have the valid? method. Instead an exception would have been thrown as
    soon as the object became invalid, and the exception would have
    contained the reason. Having your class have a valid? method seems like
    how you'd design things in a language which doesn't have exceptions.

    Adam
    Adam P. Jenkins, Feb 13, 2006
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Iwan van der Kleyn
    Replies:
    5
    Views:
    150
    James Edward Gray II
    Nov 23, 2004
  2. Zed A. Shaw
    Replies:
    2
    Views:
    104
    Zed A. Shaw
    Apr 23, 2005
  3. Brock Weaver

    Idiomatic ruby version of this code?

    Brock Weaver, Aug 18, 2005, in forum: Ruby
    Replies:
    16
    Views:
    158
    pat eyler
    Aug 23, 2005
  4. Idiomatic ruby

    , Feb 12, 2006, in forum: Ruby
    Replies:
    5
    Views:
    104
    Robert Klemme
    Feb 13, 2006
  5. Replies:
    1
    Views:
    105
    Robert Klemme
    Feb 21, 2006
Loading...

Share This Page