Forum: Ruby Optional return values

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Andreas S. (Guest)
on 2007-07-18 13:21
Hi,

I have a few methods that check permissions, e.g.

unless user.can_view?(object)
  puts "go away"
end

What I want do do now is add the possibility to give the caller more
information why the user doesn't have permission. I want to make it
backwards compatible, so returning [false, NotInGroupError(:group =>
'xyz')] is not an option. The only thing I could think of is giving the
function a String or Array that is modified in place:

def can_view?(object, message='')
  if foo.bar
   message.replace('some error message')
   false
  else
    true
  end
end

That's how one would have to do it in C or VHDL. It does seem kinda
un-rubyish though. Is there some obvious way to do this better that I'm
missing?

Thanks
Andreas
Stefano C. (Guest)
on 2007-07-18 13:32
(Received via mailing list)
Alle mercoledì 18 luglio 2007, Andreas S. ha scritto:
> backwards compatible, so returning [false, NotInGroupError(:group =>
> end
>
> That's how one would have to do it in C or VHDL. It does seem kinda
> un-rubyish though. Is there some obvious way to do this better that I'm
> missing?
>
> Thanks
> Andreas

I'do this:

def can_view?(object, more_info = false)
  if foo.bar
    more_info ? [false, 'message'] : false
  else
   more_info ? [true, nil] : true
  end
end

If the user doesn't specify the second argument, then the method works
as the
original version, otherwise it returns an array whose first argument is
true
or false and whose second argument is nil if the user has the
perimission or
the reason he doesn't if he doesn't (in the example above, I used a
string,
but it can be anything, of course). The only drawback I can see with
this
approach is that you can simply test the condition using

if can_view?(obj, true)
#...
but you need

if can_view?(obj,true)[0]
#...

I hope this helps

Stefano
Daniel DeLorme (Guest)
on 2007-07-18 15:16
(Received via mailing list)
Andreas S. wrote:
> backwards compatible, so returning [false, NotInGroupError(:group =>
> 'xyz')] is not an option.

Maybe turn it into a block?

user.cannot_view?(object) do |msg|
   puts msg
end

Daniel
Robert K. (Guest)
on 2007-07-18 15:36
(Received via mailing list)
2007/7/18, Andreas S. <removed_email_address@domain.invalid>:
> backwards compatible, so returning [false, NotInGroupError(:group =>
> 'xyz')] is not an option. The only thing I could think of is giving the
> function a String or Array that is modified in place:

I would not do that - that's plain awful for a language that has
multiple return values.

Some options I can think of that are better:

 - create another method returning the reason
 - use exceptions, i.e. do not check but simply do something and throw
if the permission is not granted (typically methods dealing with the
file system do it this way)
 - create another method returning a boolean and a reason, but do not
use a question mark as last character in the identifier
 - invert the logic, i.e. def permission_denied? which returns the
reason if forbidden and nil if granted (though I find this a bit
hackish)

I'd probably favor raising exceptions.

Kind regards

robert
This topic is locked and can not be replied to.