class RuboCop::Cop::Style::EmptyLiteral
s = ”
h = {}
a = []
# good
s = String.new
h = Hash[]
h = Hash.new
a = Array[]
a = Array.new
# bad
@example
mutable and the latter would be frozen.
isn’t corrected to an empty string since the former is
NOTE: When frozen string literals are enabled, ‘String.new`
would be a literal, like an empty array, hash, or string.
Checks for the use of a method, the result of which
def correction(node)
def correction(node) if offense_array_node?(node) '[]' elsif str_node(node) preferred_string_literal elsif offense_hash_node?(node) if first_argument_unparenthesized?(node) # `some_method {}` is not same as `some_method Hash.new` # because the braces are interpreted as a block. We will have # to rewrite the arguments to wrap them in parenthesis. args = node.parent.arguments "(#{args[1..].map(&:source).unshift('{}').join(', ')})" else '{}' end end end
def first_argument_unparenthesized?(node)
def first_argument_unparenthesized?(node) parent = node.parent return false unless parent && %i[send super zsuper].include?(parent.type) node.equal?(parent.first_argument) && !parentheses?(node.parent) end
def frozen_strings?
def frozen_strings? return true if frozen_string_literals_enabled? frozen_string_cop_enabled = config.cop_enabled?('Style/FrozenStringLiteralComment') frozen_string_cop_enabled && !frozen_string_literals_disabled? && string_literals_frozen_by_default?.nil? end
def offense_array_node?(node)
def offense_array_node?(node) (array_node(node) && !array_with_block(node.parent)) || array_with_index(node) end
def offense_hash_node?(node)
def offense_hash_node?(node) # If Hash.new takes a block, it can't be changed to {}. (hash_node(node) && !hash_with_block(node.parent)) || hash_with_index(node) end
def offense_message(node)
def offense_message(node) if offense_array_node?(node) format(ARR_MSG, current: node.source) elsif offense_hash_node?(node) format(HASH_MSG, current: node.source) elsif str_node(node) && !frozen_strings? format(STR_MSG, prefer: preferred_string_literal) end end
def on_send(node)
def on_send(node) return unless (message = offense_message(node)) add_offense(node, message: message) do |corrector| corrector.replace(replacement_range(node), correction(node)) end end
def replacement_range(node)
def replacement_range(node) if hash_node(node) && first_argument_unparenthesized?(node) # `some_method {}` is not same as `some_method Hash.new` # because the braces are interpreted as a block. We will have # to rewrite the arguments to wrap them in parenthesis. args = node.parent.arguments range_between(args[0].source_range.begin_pos - 1, args[-1].source_range.end_pos) else node.source_range end end