Return_on

Sometimes i do this:

  return x if x

Anyway to code it as:

  return_on x

t.

Trans schrieb:

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

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?

···

On 1/10/07, Trans <transfire@gmail.com> wrote:

Sometimes i do this:

  return x if x

Anyway to code it as:

  return_on x

--
Simon Strandgaard
http://opcoders.com/

I do this quite often, as well! We need a macro system :wink:

JS

···

On 10-Jan-2007, at 20:09, Trans wrote:

Sometimes i do this:

  return x if x

Anyway to code it as:

  return_on x

t.

Trans wrote:

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

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.

Trans wrote:

···

Sometimes i do this:

  return x if x

Anyway to code it as:

  return_on x

t.

This is pure unadulterated evil, however it did come up in #ruby-lang a
while ago, so I whipped up some good old fashioned homemade evil:

def try_return(&block)
   unless (blah = block.call).nil?
      GC.disable
      eval("return ObjectSpace._id2ref(#{blah.object_id})", block)
   end
ensure
  GC.enable
end

def f
  try_return { nil }
  try_return { 7 }
  0
end

p f

···

On Wed, Jan 10, 2007 at 11:39:00PM +0900, Trans wrote:

Sometimes i do this:

  return x if x

Anyway to code it as:

  return_on x

t.

Simon Strandgaard wrote:

> 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?

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.

···

On 1/10/07, Trans <transfire@gmail.com> wrote:

Daniel Finnie wrote:

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! :slight_smile:

T.

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

Well, this is much easier:

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

C'mon, Trans. :slight_smile:

Devin
(Or am I missing something obvious?)

Trans schrieb:

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

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

···

--
        vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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

Gavin

···

On Jan 14, 1:34 am, "Trans" <transf...@gmail.com> wrote:

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

"Trans" <transfire@gmail.com> writes:

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

def x
  @cache.fetch(:x) {
    @cache[:x] = result_of_stuff
  }
end

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

Rob Sanheim wrote:

Much like returning in ActiveSupport:
Buckblog: Mining ActiveSupport: Object#returning

Yes, kind-a. However there's been a lot of focus on the more common
method cache usecase, but return_on could also be used multple times
too:

  def x(a,b)
    return_on foo(a)
    return_on foo(b)

···

,
  end

T.

Devin Mullins wrote:

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

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.

Pit Capitain wrote:

Trans schrieb:
> 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.

Joel VanderWerf wrote:

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 :slight_smile:

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

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

t.

Gavin Sinclair wrote:

  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")

__END__

Output:

CACHING
"oof"

···

On Jan 14, 1:34 am, "Trans" <transf...@gmail.com> wrote:

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Joel VanderWerf wrote:

Gavin Sinclair wrote:
>> 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"

···

> On Jan 14, 1:34 am, "Trans" <transf...@gmail.com> wrote: