'What is use of ||= begin....end block in Ruby?
What is the difference between these snippets?
def config
@config ||= begin
if config_exists?
@config = return some value
else
{}
end
end
end
def config
@config ||= method
end
def method
if config_exists?
return some value
else
{}
end
end
I'm confused with the "begin ... end" block. Does it make any difference in the output? If not, then what is the use of the begin ... end block here?
Solution 1:[1]
In your case, you can even omit the begin ... end block:
@config ||=
if config_exists?
return_some_value
else
{}
end
or, using the ternary if:
@config ||= config_exists? ? return_some_value : {}
Does it make any difference in output?
It could make a difference, because unlike def ... end, an begin ... end block doesn't create a new variable scope.
Here's a contrived example:
def foo
a = 456 # doesn't affect the other a
end
a = 123
b = foo
p a: a, b: b #=> {:a=>123, :b=>456}
Versus:
a = 123
b = begin
a = 456 # overwrites a
end
p a: a, b: b #=> {:a=>456, :b=>456}
Solution 2:[2]
Using ||= begin...end allows you to memoize the result of whatever is run in the begin...end. This is useful for caching the result of resource-intensive computation.
Solution 3:[3]
The only thing that will happen differently is if an exception is raised. For instance, let's say there is a problem in the config_exists? method call. If it raises an exception in the first example your @config var will be set to {}. In the second example if the same thing happens your program will crash.
As a side note, there is no need for the return keyword here. In fact the example should read as follows. This is assuming that I understand the intent.
def config
@config ||=
begin
if config_exists?
some_value
else
{}
end
rescue
{}
end
end
and
def config
@config ||= method
end
def method
if config_exists?
some_value
else
{}
end
end
Both examples are exactly the same, except if an exception is raised @config will still be set to = some_value in the first example.
Also, it should be noted that nothing will happen if @config already has a value. The ||= operators is the same as:
@config = some_value if @config.nil?
Only set the variable to this value if it is currently nil.
Hope this is helpful and that I am understanding your question correctly.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Stefan |
| Solution 2 | shanecav |
| Solution 3 |
