Class: RuboCop::Cop::Style::SpecialGlobalVars

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
ConfigurableEnforcedStyle, RangeHelp, RequireLibrary
Defined in:
lib/rubocop/cop/style/special_global_vars.rb

Overview

Looks for uses of Perl-style global variables. Correcting to global variables in the ‘English’ library will add a require statement to the top of the file if enabled by RequireEnglish config.

Examples:

EnforcedStyle: use_english_names (default)

# good
require 'English' # or this could be in another file.

puts $LOAD_PATH
puts $LOADED_FEATURES
puts $PROGRAM_NAME
puts $ERROR_INFO
puts $ERROR_POSITION
puts $FIELD_SEPARATOR # or $FS
puts $OUTPUT_FIELD_SEPARATOR # or $OFS
puts $INPUT_RECORD_SEPARATOR # or $RS
puts $OUTPUT_RECORD_SEPARATOR # or $ORS
puts $INPUT_LINE_NUMBER # or $NR
puts $LAST_READ_LINE
puts $DEFAULT_OUTPUT
puts $DEFAULT_INPUT
puts $PROCESS_ID # or $PID
puts $CHILD_STATUS
puts $LAST_MATCH_INFO
puts $IGNORECASE
puts $ARGV # or ARGV

EnforcedStyle: use_perl_names

# good
puts $:
puts $"
puts $0
puts $!
puts $@
puts $;
puts $,
puts $/
puts $\
puts $.
puts $_
puts $>
puts $<
puts $$
puts $?
puts $~
puts $=
puts $*

EnforcedStyle: use_builtin_english_names


# good
# Like `use_perl_names` but allows builtin global vars.
puts $LOAD_PATH
puts $LOADED_FEATURES
puts $PROGRAM_NAME
puts ARGV
puts $:
puts $"
puts $0
puts $!
puts $@
puts $;
puts $,
puts $/
puts $\
puts $.
puts $_
puts $>
puts $<
puts $$
puts $?
puts $~
puts $=
puts $*

Constant Summary collapse

MSG_BOTH =
'Prefer `%<prefer>s` from the stdlib \'English\' ' \
'module (don\'t forget to require it) or `%<regular>s` over ' \
'`%<global>s`.'
MSG_ENGLISH =
'Prefer `%<prefer>s` from the stdlib \'English\' ' \
'module (don\'t forget to require it) over `%<global>s`.'
MSG_REGULAR =
'Prefer `%<prefer>s` over `%<global>s`.'
ENGLISH_VARS =

rubocop:disable Style/MutableConstant

{ # rubocop:disable Style/MutableConstant
  :$: => [:$LOAD_PATH],
  :$" => [:$LOADED_FEATURES],
  :$0 => [:$PROGRAM_NAME],
  :$! => [:$ERROR_INFO],
  :$@ => [:$ERROR_POSITION],
  :$; => %i[$FIELD_SEPARATOR $FS],
  :$, => %i[$OUTPUT_FIELD_SEPARATOR $OFS],
  :$/ => %i[$INPUT_RECORD_SEPARATOR $RS],
  :$\ => %i[$OUTPUT_RECORD_SEPARATOR $ORS],
  :$. => %i[$INPUT_LINE_NUMBER $NR],
  :$_ => [:$LAST_READ_LINE],
  :$> => [:$DEFAULT_OUTPUT],
  :$< => [:$DEFAULT_INPUT],
  :$$ => %i[$PROCESS_ID $PID],
  :$? => [:$CHILD_STATUS],
  :$~ => [:$LAST_MATCH_INFO],
  :$= => [:$IGNORECASE],
  :$* => %i[$ARGV ARGV]
}
NON_ENGLISH_VARS =

Anything not in this set is provided by the English library.

Set.new(%i[$LOAD_PATH $LOADED_FEATURES $PROGRAM_NAME ARGV]).freeze
PERL_VARS =
ENGLISH_VARS.flat_map { |k, vs| vs.map { |v| [v, [k]] } }.to_h
BUILTIN_VARS =
PERL_VARS.merge(
  NON_ENGLISH_VARS
    .select { |v| v.to_s.start_with?('$') }
    .flat_map { |v| [[v, [v]], PERL_VARS[v].flat_map { |a| [a, [v]] }] }
    .to_h
)
STYLE_VARS_MAP =
{
  use_english_names: ENGLISH_VARS,
  use_perl_names: PERL_VARS,
  use_builtin_english_names: BUILTIN_VARS
}.freeze
LIBRARY_NAME =
'English'

Constants included from RequireLibrary

RequireLibrary::RESTRICT_ON_SEND

Constants inherited from Base

Base::RESTRICT_ON_SEND

Instance Attribute Summary

Attributes inherited from Base

#config, #processed_source

Instance Method Summary collapse

Methods included from AutoCorrector

support_autocorrect?

Methods included from RequireLibrary

#ensure_required, #on_send, #remove_subsequent_requires

Methods included from ConfigurableEnforcedStyle

#alternative_style, #alternative_styles, #ambiguous_style_detected, #correct_style_detected, #detected_style, #detected_style=, #no_acceptable_style!, #no_acceptable_style?, #opposite_style_detected, #style, #style_configured?, #style_detected, #style_parameter_name, #supported_styles, #unexpected_style_detected

Methods inherited from Base

#active_support_extensions_enabled?, #add_global_offense, #add_offense, #always_autocorrect?, autocorrect_incompatible_with, badge, #begin_investigation, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #cop_config, #cop_name, cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #offenses, #on_investigation_end, #on_other_file, #parse, #parser_engine, #ready, #relevant_file?, requires_gem, #string_literals_frozen_by_default?, support_autocorrect?, support_multiple_source?, #target_rails_version, #target_ruby_version

Methods included from ExcludeLimit

#exclude_limit

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

silence_warnings

Constructor Details

This class inherits a constructor from RuboCop::Cop::Base

Instance Method Details

#autocorrect(corrector, node, global_var) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rubocop/cop/style/special_global_vars.rb', line 175

def autocorrect(corrector, node, global_var)
  node = node.parent while node.parent&.begin_type? && node.parent.children.one?

  if should_require_english?(global_var)
    ensure_required(corrector, node, LIBRARY_NAME)

    @required_english = true
  end

  corrector.replace(node, replacement(node, global_var))
end

#message(global_var) ⇒ Object



167
168
169
170
171
172
173
# File 'lib/rubocop/cop/style/special_global_vars.rb', line 167

def message(global_var)
  if style == :use_english_names
    format_english_message(global_var)
  else
    format(MSG_REGULAR, prefer: preferred_names(global_var).first, global: global_var)
  end
end

#on_gvar(node) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/rubocop/cop/style/special_global_vars.rb', line 151

def on_gvar(node)
  global_var = node.name

  return unless (preferred = preferred_names(global_var))

  if preferred.include?(global_var)
    correct_style_detected
  else
    style_detected(matching_styles(global_var))

    add_offense(node, message: message(global_var)) do |corrector|
      autocorrect(corrector, node, global_var)
    end
  end
end

#on_new_investigationObject



146
147
148
149
# File 'lib/rubocop/cop/style/special_global_vars.rb', line 146

def on_new_investigation
  super
  @required_english = false
end