Return statement

i've been getting confused about what exactly the return statement
does...

i really think this book i'm reading "learn to program" is really not
that great of a book to be reading when getting into programming. While
the author covers somethings very much in depth, he barely touches some
things for more than a line, and sometimes not at all, and then you end
up finding it in his code.

Along with that confusion on the return function.. i was code tracing
the code below and i understand it, except for one part, i just don't
see where the code tells the program to print out the numString. I see
it telling the program to in the 'one hundred' section, but not at all
in the teens or single digits?

i read these forums everyday, and i really don't understand that much of
the advanced stuff you guys talk about, but everyday i do begin to
understand more and more little parts, i just hope i'm not being a pain
in the arse. I guess it's just a little hard learning from a book and
having no teacher to learn from.. if you guys are getting annoyed, just
let me know. thank you again in advance.

def englishNumber number
  # We only want numbers from 0-100.
  if number < 0
    return 'Please enter a number zero or greater.'
  end
  if number > 100
    return 'Please enter a number 100 or lesser.'
  end

  numString = '' # This is the string we will return.

  # "left" is how much of the number we still have left to write out.
  # "write" is the part we are writing out right now.
  # write and left... get it? :slight_smile:
  left = number
  write = left/100 # How many hundreds left to write out?
  left = left - write*100 # Subtract off those hundreds.

  if write > 0
    return 'one hundred'
  end

  write = left/10 # How many tens left to write out?
  left = left - write*10 # Subtract off those tens.

  if write > 0
    if write == 1 # Uh-oh...
      # Since we can't write "tenty-two" instead of "twelve",
      # we have to make a special exception for these.
      if left == 0
        numString = numString + 'ten'
      elsif left == 1
        numString = numString + 'eleven'
      elsif left == 2
        numString = numString + 'twelve'
      elsif left == 3
        numString = numString + 'thirteen'
      elsif left == 4
        numString = numString + 'fourteen'
      elsif left == 5
        numString = numString + 'fifteen'
      elsif left == 6
        numString = numString + 'sixteen'
      elsif left == 7
        numString = numString + 'seventeen'
      elsif left == 8
        numString = numString + 'eighteen'
      elsif left == 9
        numString = numString + 'nineteen'
      end
      # Since we took care of the digit in the ones place already,
      # we have nothing left to write.
      left = 0
    elsif write == 2
      numString = numString + 'twenty'
    elsif write == 3
      numString = numString + 'thirty'
    elsif write == 4
      numString = numString + 'forty'
    elsif write == 5
      numString = numString + 'fifty'
    elsif write == 6
      numString = numString + 'sixty'
    elsif write == 7
      numString = numString + 'seventy'
    elsif write == 8
      numString = numString + 'eighty'
    elsif write == 9
      numString = numString + 'ninety'
    end

    if left > 0
      numString = numString + '-'
    end
  end

  write = left # How many ones left to write out?
  left = 0 # Subtract off those ones.

  if write > 0
    if write == 1
      numString = numString + 'one'
    elsif write == 2
      numString = numString + 'two'
    elsif write == 3
      numString = numString + 'three'
    elsif write == 4
      numString = numString + 'four'
    elsif write == 5
      numString = numString + 'five'
    elsif write == 6
      numString = numString + 'six'
    elsif write == 7
      numString = numString + 'seven'
    elsif write == 8
      numString = numString + 'eight'
    elsif write == 9
      numString = numString + 'nine'
    end
  end

  if numString == ''
    # The only way "numString" could be empty is if
    # "number" is 0.
    return 'zero'
  end

  # If we got this far, then we had a number somewhere
  # in between 0 and 100, so we need to return "numString".
  numString
end

puts englishNumber( 0)
puts englishNumber( 9)
puts englishNumber( 10)
puts englishNumber( 11)
puts englishNumber( 17)
puts englishNumber( 32)
puts englishNumber( 88)
puts englishNumber( 99)
puts englishNumber(100)

···

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

i've been getting confused about what exactly the return statement
does...

Return means "we are done".

Sometimes when you write a method (I don't know the jargon used in that book, it may be function, or subroutine, or procedure, ...) you know somewhere in the middle that _if the code reached that point_ we do not need to do anything else. For instance, see this method that says where the given number is positive:

   def is_positive?(n)
     if n > 0
       return true
     end
     return false
   end

That method can be written in different ways, but to depict the meaning of return: if n is greater than 0, you already know the answer, so in that point you indicate there's no need to execute more code, you're ready to give the answer: true. If the execution reaches that point, the following executable line "return false" will be ignored altogether, execution is halted.

Return in addition accepts a value to be returned (true/false in the example), which is considered to be the _result_ of that method call in such case.

Along with that confusion on the return function.. i was code tracing
the code below and i understand it, except for one part, i just don't
see where the code tells the program to print out the numString. I see
it telling the program to in the 'one hundred' section, but not at all
in the teens or single digits?

def englishNumber number

<snip>

end

The purpose of that method is to compute and return a _string_, not to actually _print_ that string.

puts englishNumber( 0)

Now here you have two calls: first a call to englishNumber( 0), and then a call to puts. They are executed in that order, and the string returned by the first call is chained into the second call, so puts is the one that prints the string.

Does that help? Please do no hesitate to send more questions.

-- fxn

···

On Feb 19, 2007, at 1:44 PM, Derek Teixeira wrote:

Making a wild guess at the signal in the noise.

Along with that confusion on the return function.. i was code tracing
the code below and i understand it, except for one part, i just don't
see where the code tells the program to print out the numString. I see
it telling the program to in the 'one hundred' section, but not at all
in the teens or single digits?

[snip self-depreciation - just keep that one out next time ;P]

def englishNumber number
  ## [snip unrelated code]

  # If we got this far, then we had a number somewhere
  # in between 0 and 100, so we need to return "numString".
  numString ## equivalent to "return numString"
end

In Ruby, a function always returns the value of the last expression in its definition by default if it reaches the end.

(I really, really, really hate on relying on this behaviour because it makes it easy to miss the fact that this is happening instead of just a "void" method call, or to miss that the method is in fact returning anything at all, and it really doesn't belong in a beginners' book. Tut. Oversight maybe?)

David Vallner

···

On Mon, 19 Feb 2007 13:44:46 +0100, Derek Teixeira <derek.teixeira@gmail.com> wrote:

Hi Derek,

That is exactly why I started the RubyMentor project last week, which
you can find a thread about in this list titled "adopt-a-newbie".

Please read it, it's exactly for you!

···

On 2/19/07, Derek Teixeira <derek.teixeira@gmail.com> wrote:

I guess it's just a little hard learning from a book and having no teacher to learn from..

Hi --

Making a wild guess at the signal in the noise.

Along with that confusion on the return function.. i was code tracing
the code below and i understand it, except for one part, i just don't
see where the code tells the program to print out the numString. I see
it telling the program to in the 'one hundred' section, but not at all
in the teens or single digits?

[snip self-depreciation - just keep that one out next time ;P]

def englishNumber number
## [snip unrelated code]

# If we got this far, then we had a number somewhere
# in between 0 and 100, so we need to return "numString".
numString ## equivalent to "return numString"
end

In Ruby, a function always returns the value of the last expression in its definition by default if it reaches the end.

(I really, really, really hate on relying on this behaviour because it makes it easy to miss the fact that this is happening instead of just a "void" method call, or to miss that the method is in fact returning anything at all, and it really doesn't belong in a beginners' book. Tut. Oversight maybe?)

No; Chris knows what he's doing. It's pretty fundamental -- I always
make a point of explaining it when I introduce the topic of methods to
beginners. Otherwise simple things like:

   def of_age?
     age > 17
   end

make no sense. It's basically just a function that performs a
calculation.

David

···

On Mon, 19 Feb 2007, David Vallner wrote:

On Mon, 19 Feb 2007 13:44:46 +0100, Derek Teixeira <derek.teixeira@gmail.com> > wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Return means "we are done".

Sometimes when you write a method (I don't know the jargon used in
that book, it may be function, or subroutine, or procedure, ...) you
know somewhere in the middle that _if the code reached that point_ we
do not need to do anything else. For instance, see this method that
says where the given number is positive:

   def is_positive?(n)
     if n > 0
       return true
     end
     return false
   end

That method can be written in different ways, but to depict the
meaning of return: if n is greater than 0, you already know the
answer, so in that point you indicate there's no need to execute more
code, you're ready to give the answer: true. If the execution reaches
that point, the following executable line "return false" will be
ignored altogether, execution is halted.

Return in addition accepts a value to be returned (true/false in the
example), which is considered to be the _result_ of that method call
in such case.

  So you are saying that it basically saves the confusion of elsif's and
it just makes more sense.. in your example you could have easily written

def is_positive?(n)
if n > 0
       answer= true
    elsif
    n<0
       answer= false
end

Right? but that just looks sloppy and could really get confusing if i
had more lines of code.. am i getting it right?

def englishNumber number

<snip>

end

The purpose of that method is to compute and return a _string_, not
to actually _print_ that string.

puts englishNumber( 0)

Now here you have two calls: first a call to englishNumber( 0), and
then a call to puts. They are executed in that order, and the string
returned by the first call is chained into the second call, so puts
is the one that prints the string.

   so basically when you define a method you are saying that when i call
this method, i want this done with the thing next to it. So here it is
saying i want you to run all these checks on the number next to
"englishNumber"? then it runs each of those tests .. the if statements
and once one is true to that statement, then it stops there and prints
out the last line before end?

···

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

For mathemathical functions with a simple enough control flow, I'm ambivalent on the topic. However once a method has a premature return (or four) somewhere, the inconsistency hurts my sensitivities. Using the keyword in such a method as a matter of style gives me one less thing to keep in my head when scanning the code for exit points - either there is only one and it's completely obvious like in your example, or it's every line with "return" in it.

David Vallner

···

On Mon, 19 Feb 2007 14:43:07 +0100, <dblack@wobblini.net> wrote:

Hi --

No; Chris knows what he's doing. It's pretty fundamental -- I always
make a point of explaining it when I introduce the topic of methods to
beginners. Otherwise simple things like:

   def of_age?
     age > 17
   end

make no sense. It's basically just a function that performs a
calculation.

Hi --

Return means "we are done".

Sometimes when you write a method (I don't know the jargon used in
that book, it may be function, or subroutine, or procedure, ...) you
know somewhere in the middle that _if the code reached that point_ we
do not need to do anything else. For instance, see this method that
says where the given number is positive:

   def is_positive?(n)
     if n > 0
       return true
     end
     return false
   end

That method can be written in different ways, but to depict the
meaning of return: if n is greater than 0, you already know the
answer, so in that point you indicate there's no need to execute more
code, you're ready to give the answer: true. If the execution reaches
that point, the following executable line "return false" will be
ignored altogether, execution is halted.

Return in addition accepts a value to be returned (true/false in the
example), which is considered to be the _result_ of that method call
in such case.

So you are saying that it basically saves the confusion of elsif's and
it just makes more sense.. in your example you could have easily written

def is_positive?(n)
if n > 0
      answer= true
   elsif
   n<0
      answer= false
end

Right? but that just looks sloppy and could really get confusing if i
had more lines of code.. am i getting it right?

Well, in that particular case, I would just do:

   def is_positive?(n)
     n > 0
   end

You definitely don't need the temporary variable (answer), and in fact
you don't need to code the true/false return values because > will
already give you one or the other.

David

···

On Mon, 19 Feb 2007, Derek Teixeira wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

  So you are saying that it basically saves the confusion of elsif's and
it just makes more sense.. in your example you could have easily written

def is_positive?(n)
if n > 0
       answer= true
    elsif
    n<0
       answer= false
end

Right? but that just looks sloppy and could really get confusing if i
had more lines of code.. am i getting it right?

Right.

Now that you have the idea, there are some details that depend on the programming language here. I expect that book to abstract them from the reader so I won't mention them. Just let me add that return is generally used to end the execution of a method and (normally) give some result back. That can happen anywhere, it is not required to be in the middle so to speak. Thus, this is valid:

   def square(n)
     s = n*n
     return s
   end

   so basically when you define a method you are saying that when i call
this method, i want this done with the thing next to it. So here it is
saying i want you to run all these checks on the number next to
"englishNumber"? then it runs each of those tests .. the if statements
and once one is true to that statement, then it stops there and prints
out the last line before end?

When you call a method you say: "please, execute the code inside the method definition with the values I pass and return some result".

In the example above, the method is "square" and it does a different thing if you call "square(3)" or "square(5)" because you pass a different number in the call, a "5" in the former, a "3" in the latter. In each call, the value of the variable "n" is the one in the call, and so the code is executed for that particular value of "n". As if the method definition was a template where you substitute "n" with some actual number in each call.

OK, the _result_ of the computation is returned to who issued the call and its usage depends on the actual surrounding code. For example, here

   a = square(3)

you take the result of "square(3)", which is 9, and assign it to "a". After that line "a" holds the number "9".

You can chain calls, that was the point in your original code:

   b = square(square(3))

The result of "square(3)" becomes the value passed to the outer call to "square", and so it receives "9". In consequence, "b" will hold "81".

Chained calls do not require chained methods to be equal, you chained "englishNumber" and "puts" in your code.

-- fxn

···

On Feb 19, 2007, at 2:48 PM, Derek Teixeira wrote:

Hi --

Hi --

No; Chris knows what he's doing. It's pretty fundamental -- I always
make a point of explaining it when I introduce the topic of methods to
beginners. Otherwise simple things like:

  def of_age?
    age > 17
  end

make no sense. It's basically just a function that performs a
calculation.

For mathemathical functions with a simple enough control flow, I'm ambivalent on the topic. However once a method has a premature return (or four) somewhere, the inconsistency hurts my sensitivities. Using the keyword in such a method as a matter of style gives me one less thing to keep in my head when scanning the code for exit points - either there is only one and it's completely obvious like in your example, or it's every line with "return" in it.

But if an exit point is midway through a method, it will have to have
a return:

   def m(x)
     return false unless x > 0
     blah
     return x if x == 1
     blah
   end

I can't drop the "return"s on those, because the values will just be
thrown away and the method will continue.

The only time you'd see this not literally at the very end of the
method, I think, is if you've got something like an if/else or case
statement:

   def m(x)
     if x > 0
       false
     else
       ...
     end
   end

I agree that if too much happens afterwards -- if you stick a whole
bunhc of lines in that else -- it can be hard to catch the fact that
"false" is a potential exit point. I'd rather see a hard-coded
conditional return -- sort of in the spirit of "break" -- and then get
on with the method.

David

···

On Mon, 19 Feb 2007, David Vallner wrote:

On Mon, 19 Feb 2007 14:43:07 +0100, <dblack@wobblini.net> wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Yes David, as I said in the message that method can be wrriten in different ways, and its purpose was just to serve as support to depict what return does.

-- fxn

···

On Feb 19, 2007, at 3:20 PM, dblack@wobblini.net wrote:

Well, in that particular case, I would just do:

  def is_positive?(n)
    n > 0
  end

You definitely don't need the temporary variable (answer), and in fact
you don't need to code the true/false return values because > will
already give you one or the other.

   def square(n)
     s = n*n
     return s
   end

  so right here we could have gotten rid of the "return" and then below
just write

puts square(3)

and the code will give us 9?
because it returns to us that s value, and we are putting that value?

···

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

Hi --

   def square(n)
     s = n*n
     return s
   end

so right here we could have gotten rid of the "return" and then below
just write

puts square(3)

and the code will give us 9?
because it returns to us that s value, and we are putting that value?

Yes. You could even do:

   def square(n)
     n * n
   end

and square(3) will evaluate to 9 (the value of the last expression in
the method before it ends). (Aside to Xavier: I know, it's just an
illustration :slight_smile:

David

···

On Mon, 19 Feb 2007, Derek Teixeira wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Exactly.

Now that you have grasped the meaning of return, let me say that not all languages make it optional at the end, some programming languages do require an explicit return.

Additionally, in that example the variable "s" is superfluous, you can just write

   return n*n

but I wanted to have a simple method with two lines of code instead of one, so that it was visually evident there was a last line of code in a series of lines.

-- fxn

···

On Feb 19, 2007, at 3:44 PM, Derek Teixeira wrote:

   def square(n)
     s = n*n
     return s
   end

  so right here we could have gotten rid of the "return" and then below
just write

puts square(3)

and the code will give us 9?
because it returns to us that s value, and we are putting that value?

Derek Teixeira <derek.teixeira@gmail.com> writes:

   def square(n)
     s = n*n
     return s
   end

  so right here we could have gotten rid of the "return" and then below
just write

puts square(3)

and the code will give us 9?
because it returns to us that s value, and we are putting that value?

You can do the "puts square(3)" and "9" will print out whether the
"return" statement is there or not, because in every function, if there
is no "return", the final value calculated before the "end" is
implicitly passed to the caller as if the "return" were present.

In your "square" function, the final value calculated is the value of
"s = n*n", and therefore, that would be the value that is implicitly
passed to the caller if the "return" were missing.

For example ...

  def square1(n) # no return statement
    s = n*n
    a = 12345 # this gets implicitly returned
  end

  def square2(n) # with a return statement
    s = n*n
    a = 12345
    return s # explicitly returns s
  end

  puts square1(3)
  => 12345

  puts square2(3)
  => 9

···

--
Lloyd Zusman
ljz@asfast.com
God bless you.

I UNDERSTAND! (i think =D )

thanks a lot you guys. I really think it's just this book, and it's lack
of depth on certain things ... it sort of leaves a lot to be figured out
by the reader (but when they give you an example as long, and crazy as
that one - for a beginner) it can become over whelming to figure out
what you should be grasping.

from here on out, if i have any questions, like this one, i will be sure
to use the new WIKI thing.

···

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