Is it always the norm to skip 'return'?

Hello,

I have a question about skipping the 'return' keyword in a Ruby method.
For example:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  Digest::SHA1.hexdigest(string_to_hash)
end

Being used to work in other languages, this is weird to me. Without
looking at the documentation, I have no way of knowing that 'hexdigest'
returns a string. Wouldn't the following be easier to understand?:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  return Digest::SHA1.hexdigest(string_to_hash)
end

Why so many Ruby snippets skip the 'return' keyword?

Thanks,

-- Tito

···

--
Posted via http://www.ruby-forum.com/.

Because Ruby lets you be lazy like that. You can put it in if you want but
you don't have to so laziness prevails.

However how does your adding return address your issue with not knowing what
the last method call returns?

···

On 10/19/07, Tito Ciuro <tciuro@mac.com> wrote:

Hello,

I have a question about skipping the 'return' keyword in a Ruby method.
For example:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  Digest::SHA1.hexdigest(string_to_hash)
end

Being used to work in other languages, this is weird to me. Without
looking at the documentation, I have no way of knowing that 'hexdigest'
returns a string. Wouldn't the following be easier to understand?:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  return Digest::SHA1.hexdigest(string_to_hash)
end

Why so many Ruby snippets skip the 'return' keyword?

Thanks,

-- Tito
--
Posted via http://www.ruby-forum.com/\.

--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Ruby always returns the last value used in the method; it's pretty
redundant to use return in most cases. In your example, I see no
reason to use return. I see that
Digest::SHA1.hexdigest(string_to_hash) was the last value used in the
method, so therefore I know that's what is coming back to the code
that called it.

It's a Ruby idiom, but it's not as confusing as some. :slight_smile:

--Jeremy

···

On 10/19/07, Tito Ciuro <tciuro@mac.com> wrote:

Hello,

I have a question about skipping the 'return' keyword in a Ruby method.
For example:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  Digest::SHA1.hexdigest(string_to_hash)
end

Being used to work in other languages, this is weird to me. Without
looking at the documentation, I have no way of knowing that 'hexdigest'
returns a string. Wouldn't the following be easier to understand?:

def self.encrypted_password(password, salt)
  string_to_hash = password + salt
  return Digest::SHA1.hexdigest(string_to_hash)
end

Why so many Ruby snippets skip the 'return' keyword?

Thanks,

-- Tito
--
Posted via http://www.ruby-forum.com/\.

--
http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

For the simpler methods it does seem to be a waste to put a return in there however it should be remembered that the "if" also returns a value. So

def other(number)
    if number == 1 then
        puts "In the true condition"
        "the number was 1"
    else
        puts "In the false condition"
        "it was something else"
    end
end

puts other(21)

outputs

> In the false condition
> it was something else

The implicit return here is for the whole of the if. Which can be quite a pain to track down :frowning:

Hello,

I have a question about skipping the 'return' keyword in a Ruby method.

[snip]

Why so many Ruby snippets skip the 'return' keyword?

Thanks,

-- Tito
--

Because it's not needed and it's considered bad style to introduce
unnecessary noise in Ruby. Every method call returns a value. In the absence
of a return statement, it is the value of the last expression in the
definition. So, whether you want it or not, it happens. Better to get used
to that, take advantage of it and save yourself a few keystrokes than to
think that you typing return at the end of a method definition makes any
difference at all.

The only time to use return is when you return from the middle of a method,
but even that is considered bad programming practice (functions should have
only one exit).

Regards,
Sean

···

On 10/19/07, Tito Ciuro <tciuro@mac.com> wrote:

Hi Glen,

Hello,

I have a question about skipping the 'return' keyword in a Ruby method.
For example:

def self.encrypted_password(password, salt)
string_to_hash = password + salt
Digest::SHA1.hexdigest(string_to_hash)
end

Being used to work in other languages, this is weird to me. Without
looking at the documentation, I have no way of knowing that 'hexdigest'
returns a string. Wouldn't the following be easier to understand?:

def self.encrypted_password(password, salt)
string_to_hash = password + salt
return Digest::SHA1.hexdigest(string_to_hash)
end

Why so many Ruby snippets skip the 'return' keyword?

Thanks,

-- Tito
--
Posted via http://www.ruby-forum.com/\.

Because Ruby lets you be lazy like that. You can put it in if you want but
you don't have to so laziness prevails.

However how does your adding return address your issue with not knowing what
the last method call returns?

Well, if I'm looking at some code with a return statement as shown above, I tells me that Digest::SHA1.hexdigest returns a string, which in turn the method returns as well. I don't really need to check the documentation.

I just think that in this case it pays off to be a little less lazy :slight_smile:

Thanks for your reply.

-- Tito

···

On Oct 19, 2007, at 8:22 AM, Glen Holcomb wrote:

On 10/19/07, Tito Ciuro <tciuro@mac.com> wrote:

Hi Jeremy,

Ruby always returns the last value used in the method; it's pretty
redundant to use return in most cases. In your example, I see no
reason to use return. I see that
Digest::SHA1.hexdigest(string_to_hash) was the last value used in the
method, so therefore I know that's what is coming back to the code
that called it.

It's a Ruby idiom, but it's not as confusing as some. :slight_smile:

--Jeremy

I think my confusion has to do with not knowing for sure whether a particular method returns something or not. Perhaps my example was not the best one. I've seen some ambiguous methods that makes you really wonder whether it returns something or not. I think that if a statement was preceded with a return, it would be a little easier to recognize. Not a biggie :slight_smile:

Thank you,

-- Tito

···

On Oct 19, 2007, at 8:28 AM, Jeremy McAnally wrote:

I think that's not true, and you're mistaking the output of "puts" on the
function (which IS nil) for the output of the if statement (which is the
output of the branch that's taken).

I know I've seen and used the if/else implicit-return idiom, and a quick
IRB check (1.8.6 Cygwin) shows:

irb(main):001:0> def other(number)
irb(main):002:1> if number == 1
irb(main):003:2> "it was one"
irb(main):004:2> else
irb(main):005:2* "it was not one"
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> other(21)
=> "it was not one"
irb(main):009:0> puts other(21)
it was not one
=> nil
irb(main):010:0> other(21).inspect
=> "\"it was not one\""

···

On Sat, 20 Oct 2007 00:38:42 +0900, Peter Hickman wrote:

For the simpler methods it does seem to be a waste to put a return in
there however it should be remembered that the "if" also returns a value. So

def other(number)
    if number == 1 then
        puts "In the true condition"
        "the number was 1"
    else
        puts "In the false condition"
        "it was something else"
    end
end

puts other(21)

outputs

> In the false condition
> it was something else

The implicit return here is for the whole of the if. Which can be quite
a pain to track down :frowning:

--
Jay Levitt |
Boston, MA | My character doesn't like it when they
Faster: jay at jay dot fm | cry or shout or hit.
http://www.jay.fm | - Kristoffer

Because it's not needed and it's considered bad style to introduce
unnecessary noise in Ruby. Every method call returns a value. In the absence
of a return statement, it is the value of the last expression in the
definition. So, whether you want it or not, it happens. Better to get used
to that, take advantage of it and save yourself a few keystrokes than to
think that you typing return at the end of a method definition makes any
difference at all.

The only time to use return is when you return from the middle of a method,

You're doing great up until

but even that is considered bad programming practice (functions should have
only one exit).

which is just ridiculous.

Pat

···

On 10/19/07, Sean O'Halpin <sean.ohalpin@gmail.com> wrote:

Tito Ciuro wrote:

I think my confusion has to do with not knowing for sure whether a
particular method returns something or not.

In ruby *all* methods return something.

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Tito Ciuro wrote:

>> def self.encrypted_password(password, salt)
>> string_to_hash = password + salt
>> return Digest::SHA1.hexdigest(string_to_hash)
>> end
>>
Well, if I'm looking at some code with a return statement as shown
above, I tells me that Digest::SHA1.hexdigest returns a string

Where does it tell you that? I don't get it. hexdigest could return anything,
you can't know it returns a string just by the fact that there's a return in
front of it. You can only tell that by looking at it's documentation.
What does the return keyword have to do with what kind of object a method
returns?

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

I concur. There's nowhere that says that functions should have just one
exit - it doesn't necessarily make for bad style, or code noise.
Sometimes the most elegant way *is* just to drop out, rather than
changing the control structure of your entire method.

Arlen

···

On Sat, 2007-10-20 at 09:23 +0900, Pat Maddox wrote:

You're doing great up until

> but even that is considered bad programming practice (functions should have
> only one exit).

which is just ridiculous.

Sebastian,

Tito Ciuro wrote:

def self.encrypted_password(password, salt)
string_to_hash = password + salt
return Digest::SHA1.hexdigest(string_to_hash)
end

Well, if I'm looking at some code with a return statement as shown
above, I tells me that Digest::SHA1.hexdigest returns a string

Where does it tell you that? I don't get it. hexdigest could return anything,
you can't know it returns a string just by the fact that there's a return in
front of it. You can only tell that by looking at it's documentation.
What does the return keyword have to do with what kind of object a method
returns?

That's not what I meant. You're right, the return keyword has nothing to do with the return type.

What I meant is that without the return, to me it looks like a one-way method. If I see a 'return', I know there is something being returned.

To me, and possibly other people as well, the inclusion of 'return' would make things clearer. That's all :slight_smile:

Thanks,

-- Tito

···

On Oct 19, 2007, at 8:54 AM, Sebastian Hungerecker wrote:

Arlen Christian Mart Cuss wrote:

You're doing great up until

but even that is considered bad programming practice (functions should have
only one exit).

which is just ridiculous.

I concur. There's nowhere that says that functions should have just one
exit - it doesn't necessarily make for bad style, or code noise.

error, section 4.13.2, Return Types and Values:

"AV Rule 113 (MISRA Rule 82, Revised)
Functions will have a single exit point.
Rationale: Numerous exit points tend to produce functions that are both difficult to understand and analyze.
Exception: A single exit is not required if such a structure would obscure or otherwise significantly complicate (such as the introduction of additional variables) a function’s control logic. Note that the usual resource clean-up must be managed at all exit points."

This is from a (heavily referenced) C++ style guide, specifically for code written for the Joint Strike Fighter. I'm no C++ expert, but I'm led to believe that having more than one exit point in a function in C++ can lead to resource release problems. As such, it would have a clear, practical effect there. Also, C++ functions tend to be longer (in pure LOCs) than Ruby methods, so structural complexity is more of a barrier to comprehension. If you google for "single-entry, single-exit" you'll find more references to this style and where it comes from - typically high-reliability embedded system design, as far as I can tell.

It's less of a problem in Ruby, I think, mainly because of the expressiveness and the presence of GC.

···

On Sat, 2007-10-20 at 09:23 +0900, Pat Maddox wrote:

--
Alex

Tito Ciuro wrote:

What I meant is that without the return, to me it looks like a one-way
method. If I see a 'return', I know there is something being returned.

As I said in my other message: every method returns something in ruby
(though not necessarily something useful). There are no void methods
in ruby (I assume, that's what you mean by one-way).

···

--
Jabber: sepp2k@jabber.org
ICQ: 205544826

Single-exit actually used to be standard practice, back in the days of
"structured programming". I'm surprised to see it's still around, but I
suppose AT&T has a point - in procedural languages, if you have multiple
returns in a function, you *could* forget to release the appropriate
resources each time. And C++, which has no GC, isn't immune to that.

Personally, I've never had a problem forgetting to release the right
resources, because any time I cut and paste a return statement, I copy the
whole block above it too that releases all the resources. Easy.

I much prefer what I call "straight line" programming - keep on exiting at
errors. It's the difference between this:

···

On Sat, 20 Oct 2007 18:56:20 +0900, Alex Young wrote:

On Sat, 2007-10-20 at 09:23 +0900, Pat Maddox wrote:

I concur. There's nowhere that says that functions should have just one
exit - it doesn't necessarily make for bad style, or code noise.

error, section 4.13.2, Return
Types and Values:

----
if file_exists
  if open
    if lines_to_read
      if read_doesnt_fail
        if not_a_comment
          process_line
        end
      else
        log_an_error
        close_the_File
      end
    else
      log_were_done
      close_the_file
    end
  else
    log_an_error
  end
else
  log_an_error
end
----

and this:

----
unless file_exists
  log_an_error
  return
end

unless open
  log_an_error
  return
end

unless lines_to_read
  log_were_done
  close_the_file
  return
end

unless read_doesnt_fail
  log_an_error
  close_the_file
  return
end

if not_a_comment
  process_line
end
----

Which would YOU rather maintain? For one thing, I didn't even realize I
forgot to create a loop to read the file until I got through refactoring it
into the second form. To me, the readability makes it less likely, not
more, that I will forget to release resources.

And if you're really worried about it, you can always wrap a function that
DOES have early returns inside a function that doesn't, and give the
responsibility for resource management to the outer function. I've done
that a lot.

I've seen programs (this week!) in the first form where the routine is
hundreds of lines. If you don't have a code-folding editor, it's nearly
impossible to figure out what the logic really is, and where the if/elses
match up. Doubly so on an 80x25 non-resizable screen where all the indents
make the lines impossibly short.
        
--
Jay Levitt |
Boston, MA | My character doesn't like it when they
Faster: jay at jay dot fm | cry or shout or hit.
http://www.jay.fm | - Kristoffer

Hi,

"AV Rule 113 (MISRA Rule 82, Revised)
Functions will have a single exit point.
Rationale: Numerous exit points tend to produce functions that are both
difficult to understand and analyze.
Exception: A single exit is not required if such a structure would
obscure or otherwise significantly complicate (such as the introduction
of additional variables) a function’s control logic. Note that the usual
resource clean-up must be managed at all exit points."

I think we're both in agreement and not. Particularly, the exception -
if it would obscure/complicate the control logic.

Typical C++ programming tendencies, however, should make the matter of
resource releasing a non-issue; objects are typically passed in by
reference (cleanup takes place lower in the stack) or are instantiated
in the function itself (and are automatically destructed on function
exit/exception conditions). Some people tend to use pointers and
new/delete for everything, and that's when you get issues with exit
points like this.

It's less of a problem in Ruby, I think, mainly because of the
expressiveness and the presence of GC.

Still, I think you're right about it being a lesser problem in Ruby, and
in the end it may just come down to style, yet again. Readable code is
achievable both ways, I believe, but it may be more effort in some cases
with several exit points.

Arlen

···

On Sat, 2007-10-20 at 18:56 +0900, Alex Young wrote:

Sebastian Hungerecker wrote:

Tito Ciuro wrote:

What I meant is that without the return, to me it looks like a one-way
method. If I see a 'return', I know there is something being returned.

As I said in my other message: every method returns something in ruby
(though not necessarily something useful). There are no void methods
in ruby (I assume, that's what you mean by one-way).

But I think it's still a good idea to use return in order to document
that the method is MEANT to return something, and that it's not just an
unintended side effect.

···

--
Posted via http://www.ruby-forum.com/\.

If you want to use return, use it. The value returned by a Ruby method
is t

···

On Sat, 20 Oct 2007, Andreas S. wrote:

But I think it's still a good idea to use return in order to document
that the method is MEANT to return something, and that it's not just an
unintended side effect.

--
Greg Donald
Cyberfusion Consulting
http://cyberfusionconsulting.com/

What I mean to say is the returned value is always going to be the value
of the last evaluated expression. Not having to use return is good.
It's smaller code and once you get used to it, it seems very normal.

···

On Sat, 20 Oct 2007, Greg Donald wrote:

On Sat, 20 Oct 2007, Andreas S. wrote:
> But I think it's still a good idea to use return in order to document
> that the method is MEANT to return something, and that it's not just an
> unintended side effect.

If you want to use return, use it. The value returned by a Ruby method
is t

--
Greg Donald
Cyberfusion Consulting
http://cyberfusionconsulting.com/