What is the use of || = begin ... end block in Ruby?

What is the difference between these two pieces of code:

def config @config ||= begin if config_exists? @config = return some value else {} end end end 

and

  def config @config ||= method end def method if config_exists? return some value else {} end end 

I got confused with the " begin ... end " block. Does the output matter? If not, what does the begin ... end block do here?

+5
source share
4 answers

First of all, you need to know that a certain method inherently includes the functionality of a begin ... end block.

In the context of exception handling, def method_name ... end functionally equivalent to begin ... end . Both may include rescue instructions, for example.

The two blocks of code that you share are actually identical, and there is no benefit in one over the other ... if your method not needed in several places. In this case, you DRY up your code by placing the logic in one method and calling it from several other places.

+12
source

In your case, you can even omit the begin ... end block:

 @config ||= if config_exists? return_some_value else {} end 

or using triple if :

 @config ||= config_exists? ? return_some_value : {} 

Does the output matter?

This can make a difference, because unlike def ... end the begin ... end block does not create a new scope for the variable.

Here is a contrived example:

 def foo a = 456 # doesn't affect the other a end a = 123 b = foo pa: a, b: b #=> {:a=>123, :b=>456} 

Versus:

 a = 123 b = begin a = 456 # overwrites a end pa: a, b: b #=> {:a=>456, :b=>456} 
+5
source

Using ||= begin...end , you can memoize to get the result that runs in begin...end . This is useful for caching the result of resource-intensive computing.

+3
source

The only thing that will happen in a different way is the raising of an exception. For example, suppose there is a problem in calling the config_exists? method config_exists? . If an exception occurs 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 a return key. Actually this example should look as follows. This suggests that I understand the intention.

 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, unless the exception raised by @config will still be set to = some_value in the first example.

In addition, it should be noted that nothing will happen if @config already matters. The operators ||= are the same as:

 @config = some_value if @config.nil? 

Set only this value if it is currently zero.

Hope this is helpful and that I understand your question correctly.

-1
source

Source: https://habr.com/ru/post/1239969/


All Articles