Use of "return"


#1

This is a total newbie question, but I’d like to know how “return” is
specifically used in ruby. From my understanding, it can be avoided in
a
lot of cases since ruby returns the last value by default.

However, some of the code in the Rails stuff I’m looking at has “return”
and
I was wondering if this “return” is necessary or just the individual
programmer’s style (maybe carried over from other languages).

Sorry, I’m vague but I would like to know how “return” is effectively
used
in ruby if at all.

Here’s a code snippet from the SaltedHash Engine

def new_security_token(hours = nil)
  write_attribute('security_token', AuthenticatedUser.hashed(

self.salted_password + Time.now.to_i.to_s + rand.to_s))
write_attribute(‘token_expiry’, Time.at(Time.now.to_i +
token_lifetime(hours)))
update_without_callbacks
return self.security_token
end

or this:

  def authenticate(login, pass)
    u = find(:first, :conditions => ["login = ? AND verified = 1 AND

deleted = 0", login])
return nil if u.nil?
find(:first, :conditions => [“login = ? AND salted_password = ?
AND
verified = 1”, login, AuthenticatedUser.salted_password(u.salt,
AuthenticatedUser.hashed(pass))])
end

Sorry if my question’s off the wall. Still finding my bearings.


#2

Hi –

On Mon, 9 Jan 2006, SB wrote:

Here’s a code snippet from the SaltedHash Engine

def new_security_token(hours = nil)
write_attribute(‘security_token’, AuthenticatedUser.hashed(
self.salted_password + Time.now.to_i.to_s + rand.to_s))
write_attribute(‘token_expiry’, Time.at(Time.now.to_i +
token_lifetime(hours)))
update_without_callbacks
return self.security_token

Programmer’s individual style. You could replace that line with:

security_token

“self” as receiver would be implied, and since it’s the last
expression evaluated, it would be the return value of the method.

end

or this:

 def authenticate(login, pass)
   u = find(:first, :conditions => ["login = ? AND verified = 1 AND

deleted = 0", login])
return nil if u.nil?

A return in mid-method needs “return”. You could avoid it by
rewriting the end of the method like this:

if u.nil?
nil
else
other code
end

But the “return nil if u.nil?” thing both terminates the method and
provides a visual cue that u being nil is a terminal condition. So
it’s partly style, but once you decide to do a mid-method return, you
have to use “return”.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#3

hi,
‘return’ is used to return a value, and end the method processing.
at the end of a method, ‘return’ is indeed not needed, and simply that
value
will suffice, though i think a return looks nicer :wink:
a good example where a return is needed, is this:

def method(arg)
if arg.class==String
return “invalid argument”
end
#rest of processing
end

this looks a lot nicer than placing your entire method in if/else code.
greetings, Dirk.


#4

removed_email_address@domain.invalid wrote:

I was wondering if this “return” is necessary or just the individual
write_attribute(‘security_token’, AuthenticatedUser.hashed(
“self” as receiver would be implied, and since it’s the last
return nil if u.nil?
But the “return nil if u.nil?” thing both terminates the method and
provides a visual cue that u being nil is a terminal condition. So
it’s partly style, but once you decide to do a mid-method return, you
have to use “return”.

David

“return” is required if you want to return multiple values like this:

def foo
return “a”, “b”, “c”
end

Though you can also do this

def foo
[“a”, “b”, “c”]
end

Personally, I always use “return” if the name of the variable/method is
short.

Short names

return result
return value

Long name, no “return” keyword

Foo::Bar.bur(1, 2, 3)

Method call with arguments, no “return” keyword

foobar(1, 2, 3)
barfoo 1, 2, 3

Cheers,
Daniel


#5

removed_email_address@domain.invalid wrote:

if u.nil?
nil
else
other code
end

But the “return nil if u.nil?” thing both terminates the method and
provides a visual cue that u being nil is a terminal condition. So
it’s partly style, but once you decide to do a mid-method return, you
have to use “return”.

In this case a completely different solution is possible:

def authenticate(login, pass)
u = find(:first, :conditions => [“login = ? AND verified = 1 AND
deleted
= 0”, login]) and
find(:first, :conditions => [“login = ? AND salted_password = ? AND
verified = 1”,
login, AuthenticatedUser.salted_password(u.salt,
AuthenticatedUser.hashed(pass))])
end

:slight_smile:

robert

#6

On Jan 9, 2006, at 8:57 AM, removed_email_address@domain.invalid wrote:

 return self.security_token

Programmer’s individual style. You could replace that line with:

security_token

Seems like every time I check, code with a ‘return’ runs slower
than code without. Less typing and faster. I say drop the return.

Jim


#7

Dirk M. wrote:

#rest of processing

end

this looks a lot nicer than placing your entire method in if/else
code. greetings, Dirk.

In this case you wouldn’t use return values to flag this error. It’s is
a
typical case for exceptions.

def mett(arg)
raise ArgumentError, “#{arg.inspect} is not a String” unless String

arg

further processing

end

And taking this even further, in the light of Duck Typing ™ usually
no
type checks of this kind are made at all. :slight_smile:

Kind regards

robert

#8

On 1/10/06, Jim F. removed_email_address@domain.invalid wrote:

Seems like every time I check, code with a ‘return’ runs slower
than code without. Less typing and faster. I say drop the return.

Confirmed:

require ‘quickbench’

class Test
def initialize(test)
@test = test
end

def test
@test
end

def get_test
return @test
end
end

t = Test.new(“something”)
QuickBench.go(3000000, 25) {}

END
t.test
t.get_test

Results:


| QuickBench Session Started |

3000000 Iterations
                              user     system      total        real
  1. t.test 2.860000 0.000000 2.860000 (
    2.859000)
  2. t.get_test 3.078000 0.000000 3.078000 (
    3.094000)

Fastest was <1. t.test>

Ryan


#9

Ryan L. wrote:

require ‘quickbench’
def get_test

Fastest was <1. t.test>

Ryan

Most weird. Let’s hope someone notices and the compiler is modified to
plain drop tail-returns. That is, if “return” is a reserved word and
thus not viable to being overridden by someone who codes with a dead
chicken in his left hand :stuck_out_tongue_winking_eye: (Gotta love it when flexibility bites you
back. daydreams about clean blocks)


#10

Robert K. wrote:

if arg.class==String
In this case you wouldn’t use return values to flag this error. It’s is a

Kind regards

robert

Indeed, arg.to_str would be a more consistent duck typecheck. (Le Groan,
what gruesome terminoogy sees the light of day.)

David V.