Skip to content

Commit

Permalink
Support helper method registration
Browse files Browse the repository at this point in the history
  • Loading branch information
st0012 committed Aug 9, 2023
1 parent 153b1e9 commit fe4ee5d
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 205 deletions.
19 changes: 19 additions & 0 deletions lib/irb/cmd/show_cmds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ def execute(*args)
output.puts
end

helpers_info = IRB::HelperMethod.all_helper_methods_info

unless helpers_info.empty?
output.puts(Color.colorize("[Helper Methods]", [:BOLD]) + "\n\n")
end

helpers_grouped_by_categories = helpers_info.group_by { |cmd| cmd[:category] }
longest_helper_name_length = helpers_info.map { |c| c[:display_name].length }.max

helpers_grouped_by_categories.each do |category, helpers|
output.puts Color.colorize(category, [:BOLD])

helpers.each do |helper|
output.puts " #{helper[:display_name].to_s.ljust(longest_helper_name_length)} #{helper[:description]}"
end

output.puts
end

Pager.page_content(output.string)
end
end
Expand Down
25 changes: 20 additions & 5 deletions lib/irb/extend-command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
#

require "irb/helper_method"

module IRB # :nodoc:
# Installs the default irb extensions command bundle.
module ExtendCommandBundle
Expand Down Expand Up @@ -174,11 +176,6 @@ def irb_context
[:ls, NO_OVERRIDE],
],

[
:irb_measure, :Measure, "cmd/measure",
[:measure, NO_OVERRIDE],
],

[
:irb_show_source, :ShowSource, "cmd/show_source",
[:show_source, NO_OVERRIDE],
Expand Down Expand Up @@ -308,6 +305,24 @@ def self.extend_object(obj)
end
end

def self.install_helper_methods
HelperMethod.helper_methods.each do |name, helper_method_class|
define_method name do |*args, **opts, &block|
helper_ivar = "@_helper_method_#{name}".to_sym
helper = instance_variable_get(helper_ivar)

unless helper
helper = helper_method_class.new
instance_variable_set(helper_ivar, helper)
end

helper.execute(*args, **opts, &block)
end
end
end

install_helper_methods

install_extend_commands
end

Expand Down
25 changes: 25 additions & 0 deletions lib/irb/helper_method.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require_relative "helper_method/base"

module IRB
module HelperMethod
@helper_methods = {}

class << self
attr_reader :helper_methods

def register(name, helper_class)
@helper_methods[name] = helper_class
end

def all_helper_methods_info
@helper_methods.map do |name, helper_class|
{ display_name: name, description: helper_class.description, category: helper_class.category }
end
end
end

# Default helper_methods
require_relative "helper_method/measure"
register(:measure, HelperMethod::Measure)
end
end
17 changes: 17 additions & 0 deletions lib/irb/helper_method/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module IRB
module HelperMethod
class Base
class << self
def category(category = nil)
@category = category if category
@category
end

def description(description = nil)
@description = description if description
@description
end
end
end
end
end
14 changes: 2 additions & 12 deletions lib/irb/cmd/measure.rb → lib/irb/helper_method/measure.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
require_relative "nop"

module IRB
# :stopdoc:

module ExtendCommand
class Measure < Nop
module HelperMethod
class Measure < Base
category "Misc"
description "`measure` enables the mode to measure processing time. `measure :off` disables it."

def initialize(*args)
super(*args)
end

def execute(type = nil, arg = nil, &block)
# Please check IRB.init_config in lib/irb/init.rb that sets
# IRB.conf[:MEASURE_PROC] to register default "measure" methods,
Expand Down Expand Up @@ -43,6 +35,4 @@ def execute(type = nil, arg = nil, &block)
end
end
end

# :startdoc:
end
188 changes: 0 additions & 188 deletions test/irb/test_cmd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,194 +221,6 @@ def test_irb_info_lang
end
end

class MeasureTest < CommandTestCase
def test_measure
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: false
}

c = Class.new(Object)
out, err = execute_lines(
"3\n",
"measure\n",
"3\n",
"measure :off\n",
"3\n",
conf: conf,
main: c
)

assert_empty err
assert_match(/\A=> 3\nTIME is added\.\n=> nil\nprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
assert_empty(c.class_variables)
end

def test_measure_keeps_previous_value
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: false
}

c = Class.new(Object)
out, err = execute_lines(
"measure\n",
"3\n",
"_\n",
conf: conf,
main: c
)

assert_empty err
assert_match(/\ATIME is added\.\n=> nil\nprocessing time: .+\n=> 3\nprocessing time: .+\n=> 3/, out)
assert_empty(c.class_variables)
end

def test_measure_enabled_by_rc
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: true
}

out, err = execute_lines(
"3\n",
"measure :off\n",
"3\n",
conf: conf,
)

assert_empty err
assert_match(/\Aprocessing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
end

def test_measure_enabled_by_rc_with_custom
measuring_proc = proc { |line, line_no, &block|
time = Time.now
result = block.()
puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
result
}
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: true,
MEASURE_PROC: { CUSTOM: measuring_proc }
}

out, err = execute_lines(
"3\n",
"measure :off\n",
"3\n",
conf: conf,
)
assert_empty err
assert_match(/\Acustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
end

def test_measure_with_custom
measuring_proc = proc { |line, line_no, &block|
time = Time.now
result = block.()
puts 'custom processing time: %fs' % (Time.now - time) if IRB.conf[:MEASURE]
result
}
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: false,
MEASURE_PROC: { CUSTOM: measuring_proc }
}
out, err = execute_lines(
"3\n",
"measure\n",
"3\n",
"measure :off\n",
"3\n",
conf: conf
)

assert_empty err
assert_match(/\A=> 3\nCUSTOM is added\.\n=> nil\ncustom processing time: .+\n=> 3\n=> nil\n=> 3\n/, out)
end

def test_measure_with_proc
conf = {
PROMPT: {
DEFAULT: {
PROMPT_I: '> ',
PROMPT_S: '> ',
PROMPT_C: '> ',
PROMPT_N: '> '
}
},
PROMPT_MODE: :DEFAULT,
MEASURE: false,
}
c = Class.new(Object)
out, err = execute_lines(
"3\n",
"measure { |context, code, line_no, &block|\n",
" result = block.()\n",
" puts 'aaa' if IRB.conf[:MEASURE]\n",
" result\n",
"}\n",
"3\n",
"measure { |context, code, line_no, &block|\n",
" result = block.()\n",
" puts 'bbb' if IRB.conf[:MEASURE]\n",
" result\n",
"}\n",
"3\n",
"measure :off\n",
"3\n",
conf: conf,
main: c
)

assert_empty err
assert_match(/\A=> 3\nBLOCK is added\.\n=> nil\naaa\n=> 3\nBLOCK is added.\naaa\n=> nil\nbbb\n=> 3\n=> nil\n=> 3\n/, out)
assert_empty(c.class_variables)
end
end

class IrbSourceTest < CommandTestCase
def test_irb_source
File.write("#{@tmpdir}/a.rb", "a = 'hi'\n")
Expand Down
Loading

0 comments on commit fe4ee5d

Please sign in to comment.