[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

use of "return"

SB

1/9/2006 2:49:00 PM

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.
9 Answers

dblack

1/9/2006 2:57:00 PM

0

Dirk Meijer

1/9/2006 3:00:00 PM

0

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 ;-)
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.

Daniel Schierbeck

1/9/2006 3:16:00 PM

0

dblack@wobblini.net wrote:
> Hi --
>
> On Mon, 9 Jan 2006, SB wrote:
>
>> 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
>
> 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
>

"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

Robert Klemme

1/9/2006 3:46:00 PM

0

dblack@wobblini.net wrote:
>> 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".

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

:-)

robert


Robert Klemme

1/9/2006 3:49:00 PM

0

Dirk Meijer wrote:
> 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 ;-)
> 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.

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 (TM) usually no
type checks of this kind are made at all. :-)

Kind regards

robert

Jim Freeze

1/10/2006 5:30:00 AM

0


On Jan 9, 2006, at 8:57 AM, dblack@wobblini.net 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



Ryan Leavengood

1/10/2006 5:21:00 PM

0

On 1/10/06, Jim Freeze <jim@freeze.org> 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


David Vallner

1/11/2006 5:37:00 AM

0

Ryan Leavengood wrote:

>On 1/10/06, Jim Freeze <jim@freeze.org> 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
>
>
>
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 ;P (Gotta love it when flexibility bites you
back. *daydreams about clean blocks*)


David Vallner

1/11/2006 5:38:00 PM

0

Robert Klemme wrote:

>Dirk Meijer wrote:
>
>
>>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 ;-)
>>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.
>>
>>
>
>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 (TM) usually no
>type checks of this kind are made at all. :-)
>
>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 Vallner