0

I usually use "one time assignment" (don't really know how to call this anw) in ruby like this:

class FooBar
    def foo
       @foo ||= begin
           # Costly operation putting here
       end 
    end
end

This will allow the variable @foo to be computed only once, then being used directly in subsequent calls to method foo. My question are:

  1. Is using begin/end block in this case good or not, as the documentation states that it is used for encapsulating exceptions, doesn't mention any other uses.
  2. Can I use other block types (Proc, Lambda, do/end) with this syntax? If yes then how?
3
  • en.wikipedia.org/wiki/Memoization Commented Jul 23, 2014 at 5:41
  • That's normally done in initialize, but could be done anywhere. Yes, @foo could point to the result of any type of operation: @foo = arr.map..., @foo = if..else...end, @foo = lambda..., etc. Commented Jul 23, 2014 at 5:43
  • 1
    Please don't change your code once comments or answers have been given, as it can render the latter meaningless. It's better to leave it as is and add a note (as an edit, not a comment) explaining what you intended, preferably with the word "edit", e.g., "Edit:...". Commented Jul 23, 2014 at 5:50

2 Answers 2

2
  1. I haven't seen any usage of begin/end in the memorization, but I think that's fine.

  2. Of course, you can use lambda like this @foo ||= lambda { "foo" }.call, just remember that the one time assignment(||=) only evaluate the proc when @foo is evaluated to false. It's equivalent to the following:

    if @foo
      @foo
    else
      @foo = lambda { "foo" }.call
    end
    
Sign up to request clarification or add additional context in comments.

2 Comments

But doesn't that mean I have to use @foo.call to get the value of @foo?
I see. So I can do thing like this also: Proc.new {}.call
1

I typically do it something like this:

class MyClass

  def foo
    @foo ||= build_foo
  end

  private

  def build_foo
    puts "I'm expensive"
    5
  end

end

I don't see why you'd need to make it any more complicated. To my eyes having a method named something like build_XXX or process_XXX clearly explains it's doing something more involved, and having the memoization take place in the publicly-accessible method makes it clear you are avoiding doing that more than once if needed.

1 Comment

We don't know if herophuong is calling foo more than once. It could be called just once (as with initialize) then other methods are called that use @foo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.