Class: RuboCop::Cop::Lint::NoReturnInMemoization

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/lint/no_return_in_memoization.rb

Overview

Checks for the use of a return with a value in begin..end blocks in the context of instance variable assignment such as memoization. Using return with a value in these blocks can lead to unexpected behavior as the return will exit the method that contains and not set the values of the instance variable.

Examples:


# bad
def foo
  @foo ||= begin
    return 1 if bar
    2
  end
end

# bad
def foo
  @foo = begin
    return 1 if bar
    2
  end
end

# bad
def foo
  @foo += begin
    return 1 if bar
    2
  end
end

# bad - using return in rescue blocks still exits the method
def foo
  @foo ||= begin
    bar
  rescue
    return 2 if baz
  end
end

# good
def foo
  @foo ||= begin
    if bar
      1
    else
      2
    end
  end
end

# good - not an assignment to an instance variable
def foo
  foo = begin
    return 1 if bar
    2
  end
end

# good - proper exception handling without return
def foo
  @foo ||= begin
    bar
  rescue
    baz ? 2 : 3
  end
end

Constant Summary collapse

MSG =
"Do not `return` in `begin..end` blocks in instance variable assignment contexts."

Instance Method Summary collapse

Instance Method Details

#on_op_asgn(node) ⇒ Object



87
88
89
90
91
# File 'lib/rubocop/cop/lint/no_return_in_memoization.rb', line 87

def on_op_asgn(node)
  return unless node.assignment_node.ivasgn_type?

  on_or_asgn(node)
end

#on_or_asgn(node) ⇒ Object Also known as: on_ivasgn, on_and_asgn



79
80
81
82
83
84
85
# File 'lib/rubocop/cop/lint/no_return_in_memoization.rb', line 79

def on_or_asgn(node)
  node.each_node(:kwbegin) do |kwbegin_node|
    kwbegin_node.each_node(:return) do |return_node|
      add_offense(return_node)
    end
  end
end