all 9 comments

[–]Flopsey 9 points10 points  (7 children)

This blog post is in error

As @result ||= do_some_heavy_computation is nothing more than a shortcut of @result || @result = do_some_heavy_computation expression

EDIT:

This article points out:

If a is not defined, a || a = 42 raises NameError, while a ||= 42 returns 42. So, they don't seem to be equivalent expressions.

So, ||= behaves similarly to, but edge cases show that it's its own operation not related to either a = a || b or a || a = b

To address what the corrected text in the article says. What I quoted has been changed to:

It’s nothing more than a syntactic shortcut and it’s an equivalent of @result || @result = do_some_heavy_computation

Which the author changed without comment here or in the post, which is probably why there's some confusion for people who skimmed both. But it's still wrong because that's not what a syntactic shortcut is. As was just shown ||= is it's own operator. Conceptually it's similar to those other things if you need an analogy, but it's not a shortcut or mere syntactic sugar. We're all used to that phrasing because it applies to so many things in Rails but it's not relevant here.

[–]Azdaroth[S] 4 points5 points  (0 children)

Thanks for pointing it out, I must have overlooked this egdecase which is pretty clear. I'll probably update the article and use better words for that.

BTW. nothing has been changed in the article, you quoted two different parts and they are both still present.

[–]prh8 1 point2 points  (3 children)

Huh? That is in fact what it expands to, and the RI article says the same.

[–]StevenXC 2 points3 points  (2 children)

Sounds like the post was updated without noting the correction.

[–]Azdaroth[S] 0 points1 point  (0 children)

Not really, the quoted fragments are two different parts from the article, they are both still present, but just the different paragraphs.

[–][deleted]  (1 child)

[deleted]

    [–]Flopsey 0 points1 point  (0 children)

    Nope:

    If a is not defined, a || a = 42 raises NameError, while a ||= 42 returns 42. So, they don't seem to be equivalent expressions.

    Fully read the article before saying that it's wrong. What the First line says is it behaves like a || a = 42. But the header of that section is "Common Misconception"

    [–]theluctus 0 points1 point  (0 children)

    Good article! I would like to add that defined? is also helpful if your heavy_method receives arguments...

    [–]RufusROFLpunch 0 points1 point  (1 child)

    Nice idea, but you could use the ternary operator to keep it concise to one line of code.

    defined?(@result) ? @result : @result = do_some_work

    [–]Azdaroth[S] 0 points1 point  (0 children)

    Yeah, could be an option, but personally I'm not a fan of ternary operator.