Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Idiomatic ruby

Reply
Thread Tools

Idiomatic ruby

 
 
eastcoastcoder@gmail.com
Guest
Posts: n/a
 
      02-13-2006
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?

 
Reply With Quote
 
 
 
 
ssmoot@gmail.com
Guest
Posts: n/a
 
      02-13-2006
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.

 
Reply With Quote
 
 
 
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      02-13-2006
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


 
Reply With Quote
 
William James
Guest
Posts: n/a
 
      02-13-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?


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

f, why = valid? 9

 
Reply With Quote
 
Adam P. Jenkins
Guest
Posts: n/a
 
      02-13-2006
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Idiomatic Ruby: Enumerations listrecv@gmail.com Ruby 1 02-21-2006 09:46 AM
Idiomatic ruby eastcoastcoder@gmail.com Ruby 5 02-13-2006 04:18 PM
Idiomatic ruby version of this code? Brock Weaver Ruby 16 08-23-2005 07:45 PM
[ANN] Ruby/Odeum 0.2 (More Idiomatic, Better Source Layout) Zed A. Shaw Ruby 2 04-23-2005 05:40 PM
Typical/idiomatic examples of dynamic code generation with Ruby? Iwan van der Kleyn Ruby 5 11-23-2004 03:26 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57