Return statement


#1

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)


#2

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

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

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


#3

Making a wild guess at the signal in the noise.

On Mon, 19 Feb 2007 13:44:46 +0100, Derek T.
removed_email_address@domain.invalid wrote:

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 V.


#4

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

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?


#5

Hi –

On Mon, 19 Feb 2007, David V. wrote:

[snip self-depreciation - just keep that one out next time ;P]
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


#6

On Mon, 19 Feb 2007 14:43:07 +0100, removed_email_address@domain.invalid wrote:

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.

David V.


#7

On 2/19/07, Derek T. removed_email_address@domain.invalid wrote:

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

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!


#8

Hi –

On Mon, 19 Feb 2007, David V. wrote:

end
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
blah
return x if x == 1
blah
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


#9

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

   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


#10

Hi –

On Mon, 19 Feb 2007, Derek T. wrote:

   return 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


#11

On Feb 19, 2007, at 3:20 PM, removed_email_address@domain.invalid 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.

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


#12

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?


#13

Hi –

On Mon, 19 Feb 2007, Derek T. wrote:

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


#14

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

puts square(3)

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

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


#15

Derek T. removed_email_address@domain.invalid writes:

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


#16

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.