Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor command execution logic to encapsulate args transformation #548

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/irb/cmd/chws.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class ChangeWorkspace < Nop
description "Change the current workspace to an object."

def execute(*obj)
irb_context.change_workspace(*obj)
objs = obj.map { |o| irb_context.workspace.binding.eval(o)}
irb_context.change_workspace(*objs)
irb_context.main
end
end
Expand Down
20 changes: 20 additions & 0 deletions lib/irb/cmd/ls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ def self.transform_args(args)
end
end

def execute_with_raw_args(raw_args)
raw_args = raw_args.strip

if raw_args.empty?
execute
else
if match = raw_args.match(/\A(?<args>.+\s|)(-g|-G)\s+(?<grep>[^\s]+)\s*\z/)
args = match[:args]

if !args.empty?
execute(evaluate(args), grep: /#{match[:grep]}/)
else
execute(grep: /#{match[:grep]}/)
end
else
execute(evaluate(raw_args))
end
end
end

def execute(*arg, grep: nil)
o = Output.new(grep: grep)

Expand Down
3 changes: 3 additions & 0 deletions lib/irb/cmd/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ def initialize(*args)
end

def execute(type = nil, arg = nil, &block)
if type
type = type.sub(/\A:/, '').to_sym
end
# Please check IRB.init_config in lib/irb/init.rb that sets
# IRB.conf[:MEASURE_PROC] to register default "measure" methods,
# "measure :time" (abbreviated as "measure") and "measure :stackprof".
Expand Down
35 changes: 35 additions & 0 deletions lib/irb/cmd/nop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,41 @@ def initialize(irb_context)
def execute(*opts)
#nop
end

def transform_args(raw_args)
if string_literal?(raw_args)
evaluate(raw_args)
else
raw_args
end
end

def execute_with_raw_args(raw_args)
if raw_args.nil? || raw_args.empty?
execute
else
raw_args = raw_args.strip

args =
if respond_to?(:transform_args)
transform_args(raw_args)
else
evaluate(raw_args)
end
execute(args)
end
end

private

def string_literal?(args)
sexp = Ripper.sexp(args)
sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal
end

def evaluate(str)
eval(str, @irb_context.workspace.binding)
end
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/irb/cmd/pushws.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class PushWorkspace < Workspaces
description "Push an object to the workspace stack."

def execute(*obj)
irb_context.push_workspace(*obj)
objs = obj.map { |o| irb_context.workspace.binding.eval(o)}
irb_context.push_workspace(*objs)
super
end
end
Expand Down
9 changes: 0 additions & 9 deletions lib/irb/cmd/show_source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ class ShowSource < Nop
description "Show the source code of a given method or constant."

class << self
def transform_args(args)
# Return a string literal as is for backward compatibility
if args.empty? || string_literal?(args)
args
else # Otherwise, consider the input as a String for convenience
args.strip.dump
end
end

def find_source(str, irb_context)
case str
when /\A[A-Z]\w*(::[A-Z]\w*)*\z/ # Const::Name
Expand Down
10 changes: 6 additions & 4 deletions lib/irb/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -490,11 +490,13 @@ def evaluate(line, line_no, exception: nil) # :nodoc:

# Hook command-specific transformation
command_class = ExtendCommandBundle.load_command(command)
if command_class&.respond_to?(:transform_args)
line = "#{command} #{command_class.transform_args(args)}"
end

set_last_value(@workspace.evaluate(line, irb_path, line_no))
if command_class
command_class.new(self).execute_with_raw_args(args)
set_last_value(nil)
else
set_last_value(@workspace.evaluate(line, irb_path, line_no))
end
end

def inspect_last_value # :nodoc:
Expand Down
Loading