Skip to content

Commit

Permalink
Move parse_command method to Context
Browse files Browse the repository at this point in the history
Since Context dictates whether a line is a command or an expression,
moving the parse_command method to Context makes the relationship
more explicit.
  • Loading branch information
st0012 committed Aug 25, 2024
1 parent 949f032 commit 6c0ff36
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 29 deletions.
31 changes: 2 additions & 29 deletions lib/irb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1131,7 +1131,7 @@ def build_statement(code)
end

code.force_encoding(@context.io.encoding)
if (command, arg = parse_command(code))
if (command, arg = @context.parse_command(code))
command_class = Command.load_command(command)
Statement::Command.new(code, command_class, arg)
else
Expand All @@ -1140,35 +1140,8 @@ def build_statement(code)
end
end

ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])

def parse_command(code)
command_name, arg = code.strip.split(/\s+/, 2)
return unless code.lines.size == 1 && command_name

arg ||= ''
command = command_name.to_sym
# Command aliases are always command. example: $, @
if (alias_name = @context.command_aliases[command])
return [alias_name, arg]
end

# Assignment-like expression is not a command
return if arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/)

# Local variable have precedence over command
return if @context.local_variables.include?(command)

# Check visibility
public_method = !!Kernel.instance_method(:public_method).bind_call(@context.main, command) rescue false
private_method = !public_method && !!Kernel.instance_method(:method).bind_call(@context.main, command) rescue false
if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
[command, arg]
end
end

def command?(code)
!!parse_command(code)
!!@context.parse_command(code)
end

def configure_io
Expand Down
26 changes: 26 additions & 0 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module IRB
# A class that wraps the current state of the irb session, including the
# configuration of IRB.conf.
class Context
ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=])
# Creates a new IRB context.
#
# The optional +input_method+ argument:
Expand Down Expand Up @@ -635,6 +636,31 @@ def evaluate_expression(code, line_no) # :nodoc:
result
end

def parse_command(code)
command_name, arg = code.strip.split(/\s+/, 2)
return unless code.lines.size == 1 && command_name

arg ||= ''
command = command_name.to_sym
# Command aliases are always command. example: $, @
if (alias_name = command_aliases[command])
return [alias_name, arg]
end

# Assignment-like expression is not a command
return if arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/)

# Local variable have precedence over command
return if local_variables.include?(command)

# Check visibility
public_method = !!Kernel.instance_method(:public_method).bind_call(main, command) rescue false
private_method = !public_method && !!Kernel.instance_method(:method).bind_call(main, command) rescue false
if Command.execute_as_command?(command, public_method: public_method, private_method: private_method)
[command, arg]
end
end

def inspect_last_value # :nodoc:
@inspect_method.inspect_value(@last_value)
end
Expand Down

0 comments on commit 6c0ff36

Please sign in to comment.