How can I do this better?

Hi,

I find myself to use the following idiom frequently.

def foo i
return @cache[i] if @cache[i]
@cache[i] = some_method_that_takes_long_time(i)
end

I like the post-modifying if statement.
But I feel uncomfortable with calling @cache[i] twice.

I wish this worked.
return v if v = @cache[i] #=> undefined local variable or method `v’

This works but it’s long.
if v = @cache[i]
return v
end

Maybe this is a compromise.
if v = @cache[i] then return v end

I want “return statement” to stand out.
Post-modification looks better for that.
So I call @cache[i] twice.

How do you do it?

Sam

hi,

def foo i

@cache[i]||=some_method_that_takes_long_time(i)

end

if @cache[i] is not nil it will return same value else the other

regards
gaurav

On 5 Jan 2007, at 09:05, Sam K. wrote:

I find myself to use the following idiom frequently.

def foo i
return @cache[i] if @cache[i]
@cache[i] = some_method_that_takes_long_time(i)
end

You could also use the ‘overlooked feature of Ruby hashes’ and put
your lengthy method in the block you pass to Hash.new:

http://moonbase.rydia.net/mental/blog/programming/overlooked-feature-
of-ruby-hashes.html

Regards,
Andy S.

On 1/5/07, Sam K. [email protected] wrote:

I find myself to use the following idiom frequently.

def foo i
return @cache[i] if @cache[i]
@cache[i] = some_method_that_takes_long_time(i)
end

I like the post-modifying if statement.
But I feel uncomfortable with calling @cache[i] twice.
[snip]

how about?

irb(main):001:0> a = nil
=> nil
irb(main):002:0> a ||= 42
=> 42
irb(main):003:0> a ||= 666
=> 42
irb(main):004:0> a
=> 42

Hi gaurav,

gaurav bagga wrote:

hi,

def foo i

@cache[i]||=some_method_that_takes_long_time(i)

end

This is great.
I’ll use this pattern from now on.

Thanks.

Sam

On 05.01.2007 12:12, Andrew S. wrote:

You could also use the ‘overlooked feature of Ruby hashes’ and put your
lengthy method in the block you pass to Hash.new:

http://moonbase.rydia.net/mental/blog/programming/overlooked-feature-of-ruby-hashes.html

That’s definitively a better option - especially if i is non numeric.
:slight_smile:

def initialize
@foo = Hash.new {|h,k| h[k] = some_method_that_takes_long_time(k)}
end

def foo(i)
@foo[i]
end

Cheers

robert

def foo i
return @cache[i] ? @cache[i] : some_method_that_takes_long_time(i)
end

jean

On Fri, Jan 05, 2007 at 06:05:32PM +0900, Sam K. wrote:
} Hi,
}
} I find myself to use the following idiom frequently.
}
} def foo i
} return @cache[i] if @cache[i]
} @cache[i] = some_method_that_takes_long_time(i)
} end
[…]
} How do you do it?

You may find this of use:

http://redcorundum.blogspot.com/2006/09/simple-flyweight-implementation_26.html

} Sam
–Greg

Hi Gregory,

Gregory S. wrote:

You may find this of use:

Ruby, iOS, and Other Development: Simple Flyweight Implementation

Yes.
It’s very interesting and useful.

Thanks.

Sam

On 1/5/07, Sam K. [email protected] wrote:

Hi,

I wish this worked.

return v if v = @cache[i] #=> undefined local variable or method `v’

Hi Sam
that is too bad I did not know about that, good you showed us.
Maybe you like the following code(1):

 v = @cache[i] and return v

but I agree that

return v if v = @cache[i]

would be nicer

(1) some people wondered recently why “or” and “and” have such low a
precedence, I guess this example is a reason behind this.

HTH
Robert

I want “return statement” to stand out.

Sorry I cannot do that

Post-modification looks better for that.

So I call @cache[i] twice.

How do you do it?

Sam

Robert


“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay

Hi Robert,

Robert D. wrote:

(1) some people wondered recently why “or” and “and” have such low a
precedence, I guess this example is a reason behind this.

Probably because ruby provides “||” and “&&” also for higher
precedence.

Thanks.
Sam

actually this seems to work too :
def foo(1)
@cache[i]||=some_method_that_takes_long_time(i)
end

limited testing in a trivial case in for both

jean

On 1/5/07, Sam K. [email protected] wrote:

Hi Robert,

Robert D. wrote:

(1) some people wondered recently why “or” and “and” have such low a
precedence, I guess this example is a reason behind this.

Probably because ruby provides “||” and “&&” also for higher
precedence.

I think so too, but just one worry, did you read me here?
Tthis was only a side remark but what I meant is

v = … and return v # does what you want
v = … && return v # is not even correct syntax

Cheers
R.

Thanks.
Sam


“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay

On 1/5/07, Sam K. [email protected] wrote:

R.

Of course, I read you.^^
That’s a good suggestion.
@cache[i] ||= some_method(i) kills all others, though.

Now that is funny, how stubborn I was, of course that is what you
wanted,
but I really had the feeling that you were angry
about

return v if v = x()

which one might be angry about and I think that was a good point.
I should have realized that the method around the “return … if” had
not
context purpose, the method was what you were worried about.

Of course ||= is what you are looking for.

Cheers
Robert

Thanks.

Sam


“The real romance is out ahead and yet to come. The computer revolution
hasn’t started yet. Don’t be misled by the enormous flow of money into
bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas.”

  • Alan Kay

Robert D. wrote:

I think so too, but just one worry, did you read me here?
Tthis was only a side remark but what I meant is

v = … and return v # does what you want
v = … && return v # is not even correct syntax

Cheers
R.

Of course, I read you.^^
That’s a good suggestion.
@cache[i] ||= some_method(i) kills all others, though.

Thanks.

Sam

On 05.01.2007 10:30, Jean H. wrote:

actually this seems to work too :
def foo(1)

You want “def foo(i)” here.

@cache[i]||=some_method_that_takes_long_time(i)
end

That’s what I’d do. And then there is also memoize, which implements
this pattern:

http://raa.ruby-lang.org/project/memoize/

Kind regards

robert