return_on

P

Pit Capitain

Trans said:
Sometimes i do this:

return x if x

Anyway to code it as:

return_on x

It's not very nice, but you could wrap the whole method body in a block
and use throw/catch behind the scenes.

Regards,
Pit
 
S

Simon Strandgaard

Sometimes i do this:

return x if x

Anyway to code it as:

return_on x

I cannot recall I ever have used return, in this way,
but my coding style may be 5% different than yours.
Maybe I can improve my minimal insight.

Any good (larger) examples of this thing?
 
D

Devin Mullins

Trans said:
Sometimes i do this:
return x if x
Anyway to code it as:
return_on x

I'm wondering if continuations (or continuations + set_trace_func to
catch the method end) could be used to achieve that, but am not a whiz
at callcc, and am up past my bedtime (hence am not going to experiment
w/ it).

Is there a Weirich in the house?

Devin
(Even if it can be implemented using such hackery, I might consider that
a smell that it's so different, and doesn't map to Ruby's ways, and be
hesitant to use such a beast in GP code.)
 
T

Trans

Simon said:
I cannot recall I ever have used return, in this way,
but my coding style may be 5% different than yours.
Maybe I can improve my minimal insight.

Any good (larger) examples of this thing?

I don't really have any examples that are repleat with it, but as to
insight it's especially convenient when caching a return value:

def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

this gets rid of an extraneous variable too b/c otherwise, the more
efficient impl. is:

def x
r = @cache[:x]
return r if r
# do stuff
@cache[:x] = result_of_stuff
end

funny thing i just came across a similar case for break. how would you
DRY this up and get rid of 'result'?

result = nil
files.each do
result = require file
break if result
end
if result
...

t.
 
D

Devin Mullins

Trans said:
funny thing i just came across a similar case for break. how would you
DRY this up and get rid of 'result'?

result = nil
files.each do
result = require file
break if result
end
if result
...

Well, this is much easier:

if files.any? {|file| require file }
...

C'mon, Trans. :)

Devin
(Or am I missing something obvious?)
 
P

Pit Capitain

Trans said:
I don't really have any examples that are repleat with it, but as to
insight it's especially convenient when caching a return value:

def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

this gets rid of an extraneous variable too b/c otherwise, the more
efficient impl. is:

def x
r = @cache[:x]
return r if r
# do stuff
@cache[:x] = result_of_stuff
end

You could also implement this as

def x
@cache[:x] ||= (
# do stuff
result_of_stuff
)
end
funny thing i just came across a similar case for break. how would you
DRY this up and get rid of 'result'?

result = nil
files.each do
result = require file
break if result
end
if result
...

If "result" is only a flag whose value you don't need later, you could do

if files.find { |file| require file }
...
end

Regards,
Pit
 
T

Trans

Devin said:
Well, this is much easier:

if files.any? {|file| require file }
...

Cool, I forget that #any? will break after the first true encounter. I
used #find as pit suggested (which can return any value actually). But,
that wasn't really my point. Such a solution breaks the analogy to the
original return case --whihc can't be DRYed-up that way.

T.
 
T

Trans

Pit said:
Trans said:
I don't really have any examples that are repleat with it, but as to
insight it's especially convenient when caching a return value:

def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

this gets rid of an extraneous variable too b/c otherwise, the more
efficient impl. is:

def x
r = @cache[:x]
return r if r
# do stuff
@cache[:x] = result_of_stuff
end

You could also implement this as

def x
@cache[:x] ||= (
# do stuff
result_of_stuff
)
end

That pretty good. I rarely use ( ) as local encapsulator and probably
should consider it more often. I'm generally partial to less indention
when I can get it though.

Thanks,
T.
 
J

Joel VanderWerf

Trans wrote:
...
funny thing i just came across a similar case for break. how would you
DRY this up and get rid of 'result'?

result = nil
files.each do
result = require file
break if result
end
if result
...

This only helps a little...

result = files.each do |file|
r = require file and break r
end
 
D

Daniel Finnie

I have made the most hackish thing to accomplish this. It is basically
a regexp-supporting preprocessor. I don't recommend using it.

#! /usr/bin/ruby -w

def preprocessor_define(*args, &blk)
# Determine line of caller
callerLine = caller.join.match(/[0-9]+/)[0].to_i

# Get the source of the running file
source = IO.read(__FILE__)

# Remove the callerLine line
source = source.split("\n")
source.delete_at(callerLine - 1)
source = source.join("\n")

# Do the replacement
source.gsub!(*args, &blk)

# Avoid function redefinition warnings
newName = ""
50.times {newName << (rand(26) + 65).chr }
source.gsub!("preprocessor_define", newName)

# Run the replacement
#puts source
eval source
exit
end

preprocessor_define(/return_on (.*)/) {|s| "return #{s[1]} unless
#{s[1]}.nil?"}

def test
zulu = 5
return_on zulu
puts "Broken."
end
test

Output: None, as 'puts Broken' never gets executed.
 
T

Trans

Joel said:
This only helps a little...

result = files.each do |file|
r = require file and break r
end

...and the use of 'and'. these are the crafty of ruby :)

def x
r = @cache[:x] and return r
...
end

pretty good, still a little unDRY, but pretty good.

t.
 
T

Trans

Daniel said:
I have made the most hackish thing to accomplish this. It is basically
a regexp-supporting preprocessor. I don't recommend using it.

#! /usr/bin/ruby -w

def preprocessor_define(*args, &blk)
# Determine line of caller
callerLine = caller.join.match(/[0-9]+/)[0].to_i

# Get the source of the running file
source = IO.read(__FILE__)

# Remove the callerLine line
source = source.split("\n")
source.delete_at(callerLine - 1)
source = source.join("\n")

# Do the replacement
source.gsub!(*args, &blk)

# Avoid function redefinition warnings
newName = ""
50.times {newName << (rand(26) + 65).chr }
source.gsub!("preprocessor_define", newName)

# Run the replacement
#puts source
eval source
exit
end

preprocessor_define(/return_on (.*)/) {|s| "return #{s[1]} unless
#{s[1]}.nil?"}

def test
zulu = 5
return_on zulu
puts "Broken."
end
test

Output: None, as 'puts Broken' never gets executed.

Holy Smokes! The Man goes out of his way!!! return_on brother,
return_on! :)

T.
 
J

Joel VanderWerf

Gavin said:
def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

def x
@cache[:x] ||= begin
# do stuff
end
end

Or (saving an exception handler setup):

def reverse x
@cache[:x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("foo")

__END__

Output:

CACHING
"oof"
"oof"
 
W

William James

Joel said:
Gavin said:
def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

def x
@cache[:x] ||= begin
# do stuff
end
end

Or (saving an exception handler setup):

def reverse x
@cache[:x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("foo")

__END__

Output:

CACHING
"oof"
"oof"

It doesn't work correctly.

def reverse x
@cache[:x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("what?")
p reverse("And this is cached, you think???")

--- output -----
CACHING
"oof"
"oof"
"oof"
 
J

Joel VanderWerf

William said:
Joel said:
Gavin said:
def x
return_on @cache[:x]
# do stuff
@cache[:x] = result_of_stuff
end

def x
@cache[:x] ||= begin
# do stuff
end
end
Or (saving an exception handler setup):

def reverse x
@cache[:x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("foo")

__END__

Output:

CACHING
"oof"
"oof"

It doesn't work correctly.

def reverse x
@cache[:x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("what?")
p reverse("And this is cached, you think???")

--- output -----
CACHING
"oof"
"oof"
"oof"

Oof! Typo.

def reverse x
@cache[x] ||= (
puts "CACHING"
x.reverse
)
end

@cache = {}

p reverse("foo")
p reverse("bar")
p reverse("foo")
p reverse("bar")

__END__

Output:

CACHING
"oof"
CACHING
"rab"
"oof"
"rab"
 
D

Devin Mullins

Joel said:
Gavin said:
def x
@cache[:x] ||= begin
# do stuff
end
end

Or (saving an exception handler setup):

Does begin...end really have some sort of overhead? I've found that one
the nicest looking yet, and I'd hate to dismiss it based on a false
perception.

Devin
 
J

Joel VanderWerf

Devin said:
Joel said:
Gavin said:
def x
@cache[:x] ||= begin
# do stuff
end
end

Or (saving an exception handler setup):

Does begin...end really have some sort of overhead? I've found that one
the nicest looking yet, and I'd hate to dismiss it based on a false
perception.

The overhead is smaller than I remembered, pretty negligible apparently:

require 'benchmark'

def meth_with_begin_end
x = begin 3 end
end

def meth_without_begin_end
x = 3
end

N = 10000000

Benchmark.bmbm do |b|
b.report("meth_with_begin_end") do
N.times {meth_with_begin_end}
end
b.report("meth_without_begin_end") do
N.times {meth_without_begin_end}
end
end

__END__

Rehearsal ----------------------------------------------------------
meth_with_begin_end 5.648000 0.000000 5.648000 ( 5.729000)
meth_without_begin_end 5.458000 0.000000 5.458000 ( 5.458000)
------------------------------------------------ total: 11.106000sec

user system total real
meth_with_begin_end 5.708000 0.000000 5.708000 ( 5.718000)
meth_without_begin_end 5.608000 0.000000 5.608000 ( 5.608000)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top