Misterparker
Misterparker

Reputation: 606

Ruby double pipe assignment with block/proc/lambda?

It is really nice to be able to write out

@foo ||= "bar_default"

or

@foo ||= myobject.bar(args)

but I have been looking to see if there is a way to write something like

@foo ||= do
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
end

roughly equivalent in actually functional code to something like

@foo = if [email protected]?
         @foo
       else
         myobject.attr = new_val
         myobject.other_attr = other_new_val
         myobject.bar(args)
       end

And I suppose I could write my own global method like "getblock" to wrap and return the result of any general block, but I'm wondering if there is already a built-in way to do this.

Upvotes: 21

Views: 5751

Answers (3)

tothemario
tothemario

Reputation: 6309

I usually write it like this:

@foo ||= (
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
)

Upvotes: 4

jacknagel
jacknagel

Reputation: 1311

You can use begin..end:

@foo ||= begin
  # any statements here
end

or perhaps consider factoring the contents of the block into a separate method.

Upvotes: 45

dteoh
dteoh

Reputation: 5922

@foo ||= unless @foo
  myobject.attr = new_val
  myobject.other_attr = other_new_val
  myobject.bar(args)
end

Upvotes: -2

Related Questions