class RuboCop::Cop::Lint::NestedMethodDefinition

Checks for nested method definitions.

@example

# bad

# `bar` definition actually produces methods in the same scope
# as the outer `foo` method. Furthermore, the `bar` method
# will be redefined every time `foo` is invoked.
def foo
  def bar
  end
end

@example

# good

def foo
  bar = -> { puts 'hello' }
  bar.call
end

@example

# good

# `class_eval`, `instance_eval`, `module_eval`, `class_exec`, `instance_exec`, and
# `module_exec` blocks are allowed by default.

def foo
  self.class.class_eval do
    def bar
    end
  end
end

def foo
  self.class.module_exec do
    def bar
    end
  end
end

@example

# good

def foo
  class << self
    def bar
    end
  end
end

@example AllowedMethods: [] (default)

# bad
def do_something
  has_many :articles do
    def find_or_create_by_name(name)
    end
  end
end

@example AllowedMethods: ['has_many']

# bad
def do_something
  has_many :articles do
    def find_or_create_by_name(name)
    end
  end
end

@example AllowedPatterns: [] (default)

# bad
def foo(obj)
  obj.do_baz do
    def bar
    end
  end
end

@example AllowedPatterns: ['baz']

# good
def foo(obj)
  obj.do_baz do
    def bar
    end
  end
end

Constants

MSG

Public Instance Methods

on_def(node) click to toggle source
# File lib/rubocop/cop/lint/nested_method_definition.rb, line 103
def on_def(node)
  subject, = *node
  return if node.defs_type? && subject.lvar_type?

  def_ancestor = node.each_ancestor(:def, :defs).first
  return unless def_ancestor

  within_scoping_def =
    node.each_ancestor(:block, :sclass).any? do |ancestor|
      scoping_method_call?(ancestor)
    end

  add_offense(node) if def_ancestor && !within_scoping_def
end
Also aliased as: on_defs
on_defs(node)
Alias for: on_def

Private Instance Methods

allowed_method_name?(node) click to toggle source
# File lib/rubocop/cop/lint/nested_method_definition.rb, line 126
def allowed_method_name?(node)
  name = node.method_name

  allowed_method?(name) || matches_allowed_pattern?(name)
end
scoping_method_call?(child) click to toggle source
# File lib/rubocop/cop/lint/nested_method_definition.rb, line 121
def scoping_method_call?(child)
  child.sclass_type? || eval_call?(child) || exec_call?(child) ||
    class_or_module_or_struct_new_call?(child) || allowed_method_name?(child)
end